|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
Code crash repetitively at same address |
Posted: Thu May 02, 2019 12:19 pm |
|
|
Device: PIC24EP512GP806
Compiler: 5.026
Alright, this is a very long shot but I figured I'd try to see if anyone can help...
I sent an email to the SD driver company (Brush Electronics). Mr. Smallridge from Brush Electronics is usually good and fast at responding but I'm giving a try here as well just in case...
My PIC is sampling 64kbps PCM data from an audio CODEC and saving it to an SD card using his driver. I have used this driver to save slow data during the past 4 years and it has always worked. Today is the first time I try with the audio. The recorded audio sounds as expected and works fine, however, there's something happening that the driver does not like and I have had 4 crashes today while saving data to the SD card, three at the same address and one at another address.
The three at the same address occured after roughly 2 minutes of data being written. I was, however, able to record successfully 3 minutes of audio in one instance without a glitch. So I have no idea why the crash occurs.
A few years ago on this site, I was given a little piece of code to capture the address of where the address trap occured and this code is inside the address trap interrupt. I was told that the crash occured at the address immediately _before_ the reported address.
When I tell the compiler to put the code in assembly, the address the trap interrupt returned is 0F5D8 therefore I would assume that the crash would occur at 0F5D6. Here is the ASM code of the function in questions (excerpt from the driver code):
wcnt = 512 - ((WORD)(fp->fptr) & 0x1ff); // Copy fractional bytes to file I/O buffer
if (wcnt > btw)
wcnt = btw;
memcpy((void *)&fp->buffer[(WORD)(fp->fptr) & 0x1ff], (void *)wbuff, wcnt);
fp->flag |= FA__DIRTY;
The ASM code below is what CCS provides in the .LST file. This code immediatly follows the last line above (fp->flag |= FA__DIRTY;):
0F5AC: MOV 5B96,W0
0F5AE: MOV #1A,W4
0F5B0: ADD W4,W0,W5
0F5B2: MOV.B [W5],W0L
0F5B4: IOR #40,W0
0F5B6: MOV.B W0L,[W5]
0F5B8: MOV 5BAA,W0
0F5BA: MOV 5BA6,W4
0F5BC: ADD W0,W4,W0
0F5BE: MOV W0,5BAA
0F5C0: MOV 5B96,W0
0F5C2: MOV #0,W4
0F5C4: ADD W4,W0,W5
0F5C6: MOV 5BA6,W0
0F5C8: MOV [W5],W4
0F5CA: ADD W4,W0,[W5]
0F5CC: MOV [++W5],W4
0F5CE: ADDC W4,#0,W4
0F5D0: MOV W4,[W5]
0F5D2: MOV 5B9C,W5
0F5D4: MOV 5BA6,W0
0F5D6: MOV [W5],W4
0F5D8: ADD W4,W0,[W5]
0F5DA: MOV 5B9A,W0
0F5DC: MOV 5BA6,W4
0F5DE: SUB W0,W4,W0
0F5E0: MOV W0,5B9A
0F5E2: GOTO F33C
The second (different) problem is at address 0EA54 with the ASM code below function <f_write> at the line indicated below:
fp->curr_sect = sect;
0EA4A: MOV 5B92,W0
0EA4C: MOV #10,W4
0EA4E: ADD W4,W0,W5
0EA50: MOV #5B9E,W4
0EA52: MOV [W4++],[W5++]
0EA54: MOV [W4++],[W5++]
Again, I know this is a long shot and perhaps the code above does not mean anything to anyone therefore it's not a big deal but I have no idea how the assembly code works so maybe someone out there will understand and shed some light.
Thanks for your time!
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu May 02, 2019 1:43 pm |
|
|
Before we waste time, what is the address offset used by the code you have
to access the error address?. CCS changed the design of the interrupt
handler a while ago, and the latter compilers need a different address to
older compilers. Lets just make sure you are using the address for your
compiler version....
Now obviously everything here is dependant on fp genuinely pointing to the
right address. Triple check anything that sets/changes fp. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri May 03, 2019 4:51 am |
|
|
Hi TTelmah,
Actually, I got a lightning fast response form Andrew at Brush Electronics yesterday.
His suggestion is to try a 4GB-32GB card to force the driver in SDHC mode which will probably circumvent that issue. I did not realize I was using a 2GB SD, I just grabbed whatever I had kicking around without really paying attention to its size.
Andrew's response sums-up to:
My suspicion is that the issue will be related to pointer arithmetic and how it is handled differently between different versions of the compiler. I don’t know if it will solve the problem (using a 4GB or greater card) but it will force the code through the SDHC path. I still think it is a compiler related issue that is exposing an existing bug in the driver that was not previously visible or it is introducing a bug. The pointer handing between the PCH and PCD version of the file system differ only be the WORD alignment forced by the processor. This translates to a difference in pointer handling and therefore pointer arithmetic however this code has not been changed in years.
So if that's the case and solves the issue, although it may or may not help anyone here, I'll still post it here in case anyone else uses that driver for PIC24 and encounters some weird unexplainable random issues.
I have many versions of the compilers between 5.026 and 5.071 but all versions above 5.026 caused many problems at compile time, introduced bugs, handled memory horribly (even to the point I could not compile the code) so I opened a ticket with CCS and their suggestion was to stick with the 5.026 compiler in the background but use the 5.071 IDE. The reason I wanted to use the 5.071 IDE is because of its __BUILDCOUNT__ option which is not available in 5.026. So at the moment I have a bastardized CCS version which works well for me.
Not sure what's the new compiler version now but I don't want to buy it only to realize afterwards that it's worse.
Thanks for your time.
Ben |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Fri May 03, 2019 7:34 am |
|
|
A little late to the party, but for PIC24's I like to do the trap address check a little more generically so that there is less chance for compiler differences to occur:
Code: |
//holds the address after the one that caused the issue, so
//look at the previous address.
volatile unsigned int32 g_last_addr;
//Mark the ISR as fast so that the compiler does not save
//any registers to the stack and instead calls the shadow
//register push/pop commands (hardware register stack)
#int_addrerr FAST
void address_trap(){
// BE VERY CAREFUL OF CODE HERE. Must not use W4 - W14 registers in ASM
// Stack layout after interrupt. W15 holds stack address
// |----------------------------------------------------|
// W15 Value - 4 | Last PIC Address <15 .. 0> |
// |----------------------------------------------------|
// W15 Value - 2 | SR Register | IPL<3> | Last PIC Address <22 .. 16> |
// |----------------------------------------------------|
// W15 Value | Random Junk |
// |----------------------------------------------------|
#ASM
SUB W15,#2,W0 //Get address of first item on the stack
MOV [W0],W0 //Dereference it
AND #0x007f,W0 //Mask off upper 9 bits
MOV W0,g_last_addr+2 //Save to the high word
SUB W15,#4,W0 //Get address of second item on the stack
MOV [W0],W0 //Dereference it
MOV W0,g_last_addr //Save to the low word
#ENDASM
//Here figure out a way to view the address. Normally I can still
//print to the ICD-U64 software serial port or a hardware serial port
while(TRUE); //stop here
}
|
The nice thing is even if the compiler ends up changing how it saves registers to the stack from version to version, marking the interrupt as FAST stops that, so you know that the address you need to pop should always be in the same spot.
g_last_address refers to the address the ISR would have jumped to when it came back, so you want the address used before it.
Note that I do
at the end of the ISR. That's because I normally print the results and since I marked the interrupt as fast, I have no default way to prevent my debug code from using registers W4-W15, so not stopping the interrupt could have weird results unless I manually start saving registers. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
Code crash repetitively at same address [CLOSED] |
Posted: Fri May 10, 2019 5:57 am |
|
|
Well, I guess that I didn't get to really "fix" the issue other than it went away on its own after analyzing how I was handling the data and shuffling stuff around. I trust more the driver code than my own!
At the time this error occured last week, I realized afterwards that there were a few things I was doing wrong when handling the data and manipulating files.
We are a week later and since Tuesday, I've been analyzing my own code and I can confirm that I am no longer getting the crash therefore it really was something in my code.
So now I can record audio to SD card without a problem for as long as I want or reach the end of the card.
Sorry if I can't provide a clearer answer to my own problem in case anyone else runs into the same issue.
Thanks to both of you who responded.
Ben |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|