Please let me know if you need more information to help me debug this. The problem is easily reproducible by toggling the XINT1 interrupt via a physical switch (possibly lots of bouncing).
I am using CCS version 3.1 with DSP/BIOS 4.90 and C2812 microcontroller.
The code is getting stuck in the FXN_F_selfLoop:
3EE67A FXN_F_selfLoop:
3EE67A SB FXN_F_selfLoop,UNC
I have a breakpoint on 0x3EE67A so that when the loop is reached I will know immediately.
I thought that perhaps the problem is related to SDOCM00050676 which was resolved in DSP/BIOS 5.33.03:
http://e2e.ti.com/support/microcontrollers/tms320c2000_32-bit_real-time_mcus/f/171/p/21661/83705.aspx#83705
However, the SDOCM00050676 fix/problem only seems to be relevant for 2833x and not 281x DSPs. I checked anyway if the RPC was pointing to the following instruction:
LCR *XAR7
The RPC never points to an LCR instruction or an instruction that involves the XAR7 register when it gets into this loop. It ends up that the RPC is pointing to a different part in the code each time the loop is encountered. Sometimes it is pointing to kernel code and sometimes it is pointing to user application code.
User Aarti posted some good debugging tips for the FXN_F_selfLoop here:
http://e2e.ti.com/support/microcontrollers/tms320c2000_32-bit_real-time_mcus/f/171/p/21476/82991.aspx#82991
With regards to Aarti's suggestions:
1) -c is used and not -cr
2) It doesn't seem to be a task stack overflow because the stack peak is never larger than the stack size for each TSK listed in the CCS IDE (TSK part of KOV). Are there other stacks that I need to check for stack overflow? For example, what about the stack that the kernel uses? I think this is set in the MEM project settings. How can I check if that is overflowing? Other than stack overflow, how could I check for a faulty pointer/memory? The crash seems to be due to a stack overflow because it seems to be dependent on timing and not execution path (i.e. how much is on the stacks, not what is being executed). Also note that I don't think it is corrupted memory or stack corruption because the code will execute several times before the code gets stuck in the loop. It definitely seems to be an issue with timing, interrupts and stack overflow (i.e. I have to toggle the XINT1 interrupt several times before the loop is encountered).
3) The unplugged interrupts is interesting. All of the ISRs have been properly enabled/disabled in the IER or the PIEIER. The IER should be set to 613B. If I debug the program and watch the IER value in real time its value is always 613B. However, whenever the code gets stuck in the FXN_F_selfLoop loop then the IER register contains almost random values. What would cause the IER to change during operation? The IER register is set once during initialization and doesn't change anywhere in the code. Is it possible that a stack overflow or faulty hardware would cause the IER to change? I am thinking that if the IER changes somehow then perhaps the code is getting stuck in one of the unplugged interrupts (since they are somehow being enabled according to the IER register value, although I have no idea how or why the IER register's value changes from 613B to something else).
4) This shouldn't be applicable. PIEs are enabled but none of the interrupts are using the dispatcher (dispatcher option isn't checked in HWI settings). Also, the system isn't using the NMI.
I've also tried these tips:
http://tiexpressdsp.com/wiki/index.php?title=DSP_BIOS_Debugging_Tips
Again, I don't think there is a task stack overflow because each time the IDE breaks on the loop all of the tasks have more than enough stack space left over. For example, when the loop was encountered and RPC was pointing inside of FCS_Posi_tsk, the FCS_Posi_tsk had stack size 0x100 and stack peak 0x93. Is it possible that the IDE's information is not up-to-date and there was in fact a stack overflow within a task? How can I check the other stacks that aren't listed in the TSK part of the KOV?
Incase the system stack is overflowing I set SWI to have the same priorities (to prevent SWI from nesting) and I also set the PIE interrupts to use the dispatcher and set their masks to "all" (to prevent HWI from nesting). After doing this I had to move some things around in memory because with the dispatcher enabled some parts of memory ran out of room.
If I run the program so that SWI and HWI can't be nested then I get into the same FXN_F_selfLoop loop but it happens consistently during bootup and at the same time during bootup. Also, the RPC is the same when this occurs.
Here's some more details:
When SWI and HWI can be nested then the program enters the loop as follows (note IER and RPC are different with each case):
--------------------------------------------------------------------------------------------
Note: During normal operation IER is (and should be) 613B. Why is it something different when this loop is encountered?
test #1:
IER: F080, IFR: 6003, DBGIER:613B, PC: 3EE67A, RPC: 3F81DB
3F81D5 L8, DW$L$_SPM_Process_Tsk$2$B:
3F81D5 MOV @AL,#0xFFFF
3F81D7 SUB ACC, @@0 << 15
3F81D8 SUBU ACC, *0++, ARP2
3F81D9 .word 0x767E
3F81DA XORB AC, #0x38
3F81DB MOVB AL, #0
test #2:
IER: CBF4, IFR: 2001, DBGIER: 613B, INTM: 1, PC: 3EE67A, RPC: 3EEBC7
3EEBC4 _KNL_exit:
3EEBC4 MOVB XARG4, #1
3EEBC5 .word 0x767E
3EEBC6 MOV ACC, *+XARG0[2] << 11<
3EEBC7 .word 0x767E
test #3:
INTM: 1, DBGM: 1, IER: D38C, IFR: 2001, DBGIER: 613B, PC: 3EE67A, RPC: 3EF094
3EF066 _SEM_pend:
3EF066 ADDB SP, #10
...
3EF092 .word 0x767E
3EF093 XOR *--XAR3, AH
3EF094 MOVW DP, #0x0249
test #4:
INTM:1, DBGM: 1, IER: CC26, IFR: 2001, DBGIER: 613B, PC: 3EE67A, RPC: 3EE77C
3EE72AC SWI_F_run, SWI_RUNFXN:
...
3EE77A ACC, *AR0++ << 10
3EE77B .word 0x3E67
3EE77C MOVL ACC, *--SP
test #5:
INTM: 1, DBGM:1, IER: CF64, IFR: 2000, DBGIER: 613B, PC: 3EE67A, RPC: 3EF0C6
3EF066 _SEM_pendEnterKnl:
...
3EF0C4 .word 0x767E
3EF0C5 MOV ACC, *-SP[37 << 15
3EF0C6 MOV AL, *-SP[7]
test #6:
INTM: 1, DBGM: 1, IER: D092, IFR: 2001, DBGIER: 613B, PC: 3EE67A, RPC: 3F8013
3F800D DW$L$_FCS_POSI_Process_Tsk$2$B,L1:
..
3F8011 .word 0x767E
3F8012 XORB AL, #0x38
3F8013 MOVB AL, #1
Note: I tried 10 tests, the 6 above are the unique results. test #1 was seen three times, test #2 was seen twice, and test #5 was seen twice.
--------------------------------------------------------------------------------------------
When SWI and HWI cannot be nested then the program always enters the loop during bootup, at the same place, which I suppose is an improvement for debugging. The loop seems to always be caused by the HWI dispatcher now. I believe that IER is 0000 at this time because the interrupts have not yet been enabled (i.e. IER was not yet set to 613B).
--------------------------------------------------------------------------------------------
INTM: 1, DBGM: 1, PC: 3EE67A, RPC: 3EE6C1, IER: 0000, IFR: 2012, DBGIER: 613B
3EE67B _HWI_F_dispatch, HWI_F_dispatch:
...
3EE6BC MOVL *SP++, ACC
3EE6BD ADD ACC, @AR0 << 8
3EE6BE SUB ACC, *+XAR0[4] << 10
3EE6BF SUB ACC, *+XAR0[0] << 14
3EE6C0 .word 0x3E60
3EE6C1 POP @SP
I could see this having something to do with the stack because of the POP @SP instruction.
SP: 0408
0407 TRAP #30
0408 SUB ACC, @26 << 15
0409 ITRAP0
--------------------------------------------------------------------------------------------
How can I check if the system stack is overflowing? I believe it's populated with BEEF initially... where is the system stack's base and size defined?
Note: I am not the original author of this project so please bare with me as I'm new to this project, TI/DSPs, and CCS in general. Also note that I hand typed the ASM code above so there could be typos/errors due to human error.
Any suggestions/help would be greatly appreciated. It is preferred to find a fix rather than having to do a complete re-write.