This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I'm trying to write a new platform for TinyOS using a f5438 and a CC2520.
I manage to compile Blink (the example app of TOS), but it's not working. I enabled just Timer0 and led0.
The problem is that the PC and SR values pushed before executing the Timer ISR (I tried TimerA0 and A1, with the same results), are not right.
At first I thought that might be a problem when waking up, so I added a task with an infinit loop to keep the system up, and the same happends.
(Tools mspgcc-4.4.5, tinyos-2.1.1, mspdebug 0.13, MSP-FETU430IF, Ubuntu 10.10.)
Start of the program
(mspdebug) regs
( PC: 05c00) ( R4: 00b80) ( R8: 00001) (R12: 00334)
( SP: 05bfe) ( R5: 00000) ( R9: 00001) (R13: 00000)
( SR: 00000) ( R6: 00002) (R10: 000ff) (R14: 000f8)
( R3: 00000) ( R7: 00005) (R11: 00005) (R15: 00001)
05c00: 31 40 00 5c MOV #0x5c00, SP
05c04: b2 40 80 5a 5c 01 MOV #0x5a80, &0x015c
05c0a: 3f 40 00 00 CLR R15
05c0e: 0f 93 TST R15
I've also tried on a different 5438, but the problem is exactly the same.
Thanks in advance
Jorge
The new MSPs with 430X core (including the 54xx) have a 20 bit address bus and 20 bit registers. The instructions, however, are backwards compatible to the old 16 bit core. For calls that leave the 16 bit address range, or come from outside, there are new instructions CALLA and RETA which push and pop 20 (32) bit to and from stack for the return address.
With ISRs, however, Ti implemented a(normally) 100% compatible way: the upper 4 bit of the PC are pushed to the stack together with the status register, which has unused bits. This saves one cycle and two bytes stack.
upon return from the ISR, the PC is assembled from these 4 status register bits and the 16 bit return address.
In your case, it seems the status register isn't properly, so upon ISR return a wrong PC is assembled. This mechanism is built into the CPU core and not subject to the compiler-generated instructions. And normally it is transparent. But if you mess with the stack in your ISR, or mix 430 and 430x function calls and returns, you get into trouble.
Jens-Michael is correct, but I have an alternate suggestion: You code jumped off into the weeds, then the timer interrupt fired.
From your stack dump, the return address of 665CA is correct. This is the address that sits on the stack as the return address for your interrupt handler, assembled from the upper 4 bits of SR plus the lower 16 bits of PC. This is reported by your memory dump of the stack at 05BFA at the top of your TimerA interrupt handler. This tells me the problem is not in your interrupt handler; you are already dead, you just don't know it yet.
The real question is: How did 665CA finds its way onto the stack? 665CA is vacant memory, which will always fetch 3FFF (JMP PC, a nop). If you somehow jumped to 665CA, the cpu would sit and spin (firing NMI's, which in your code is stubbed to RETI's) until your timer interrupt fired.
Since 0665CA is invalid memory, the question is how did it find its way onto the stack?
-- Chip
You might try writing a stub handler for the NMI and see if your debugger will trigger a breakpoint on it. You might be able to gleen some more information that way.
-- Chip
Good question. Lett me narrow it down further: The TOS is 0A65. How can the upper byte of the saved status register be 65? Only 4 bits are userd for the PC storage, the rest is reserved, so where does the '5' come from (or more exactly the '4', as the '1' is the overflow bit)? I admit, I never checked the stack (I never used a debugger for the MSP), but this is strange. Even if the ISR was indeed called from the middle of the void, Bit 9..11 of the saved status register should be either all 0 or all 1. But maybe i'm on the wrong track and these three bits are always random.ChipD said:Since 0665CA is invalid memory, the question is how did it find its way onto the stack?
Unfortunately, neither the complete ISR nor the code a 0x065ca (Is there code on this place at all?) has been posted. The assembly dum, not the C source.
There's another possibility: the ISR isn't entered because of an interrupt. It is possible that the ISR is entered because the processor was running wild before (stack overflow? array out of bounds?). Then the values on the stack are neither status register nor return address, but something 'random'.
Besides a stack overflow, this can happen if an interrupt occurs and no ISR is assigned. Then the processor will jump to 0xfffe (since the unoccupied vector points to 0xffff) and run wild, eventually arriving at some code.
Also, it may be that the main funciton ends and the processor simply continues into the next function.
It is up to the compiler to handle these last two cases, but there is no general rule what happens if main ends. MSPGCC assigns all unused vectors to a function the just does a RETI (which may still cause a system halt on newer MSPs as the IRQ remains unhandled), some compilers just leave the vectors pointing to 0xffff. Also, on end of main, some add code that puts the MCU into LPM, others just do nothing and end main, just like any other function, with a RET (which jumps to nowhere since there is no return address on the stack).
Hi guys, thank you very much for your fast reply, I'm attaching the C source, I can also upload the nesC file if you consider it would help.
Timer ISR is called just once, and the code is working fine, (with timer dissabled it stays on the infinit loop I set to it), the thing is that when the Interrupt gets called....
the code of 0x065ca should be in the asm attached earlier, but the disassembly shows:
65c8: b0 12 34 5c call #0x5c34
65cc: 49 9b cmp.b r11, r9
65ce: 03 2c jc $+8 ;abs 0x65d6
as you can see, now it might work as for what SR is concerned, but the PC is 0x0000!!!
now, switching to another 5438, same code:
(mspdebug) regs
( PC: 05fa8) ( R4: 0ffff) ( R8: 00001) (R12: 00334)
( SP: 05bfa) ( R5: 00000) ( R9: 00001) (R13: 00000)
( SR: 00003) ( R6: 00002) (R10: 000ff) (R14: 000f8)
( R3: 00000) ( R7: 00005) (R11: 00005) (R15: 00001)
sig_TIMER0_A0_VECTOR+0x1c:
05fa8: 00 13 RETI
sig_TIMER0_A1_VECTOR:
05faa: 0f 12 PUSH R15
05fac: 0e 12 PUSH R14
05fae: 0d 12 PUSH R13
05fb0: 0c 12 PUSH R12
05fb2: 1f 42 6e 03 MOV &0x036e, R15
05fb6: 12 c3 CLRC
(mspdebug) md 0x5bfa
05bfa: 0a 65 ca 65 f8 00 31 40 00 5c b2 40 80 5a 5c 01 |.e.e..1@.\.@.Z\.|
same result as yesterday...
jorge
Chip,
thanks for your reply.
I checked your suggestion, but the code works fine until the interrupt is serviced. I agree with your question, because the only one messing with the stack before 0x5f8c (first line of the ISR) is the uP itself, no matter what i've done before with the SP, the last 4 bytes should be the SR & PC. SR gets corrupt and then as you said, I'm already dead inside the ISR code.
So the thing is that SR is getting corrupt somewhere, the rest of the operation is what it should. Bug CPU18 says something similar, but it's not the actual problem, I can see 3 nibbles repeated, but I wonder if this bug is related in some way.
Upon servicing an interrupt service routine, the program counter (PC) is pushed twice
onto the stack instead of the correct operation where the PC, then the SR registers are
pushed onto the stack. This corrupts the SR and possibly the PC on RETI from the ISR.
1100 lines of assembly listing was tough to look at, 6700 lines of C preprocessor output is even worse! By "C source" Jens meant the 20 lines of code you added to the known working base of TinyOS.
I am going to invoke Occam's Razor on this: This is most likely going to turn out to be a bug in the code you modified or added. It is highly unlikely that the TinyOS code is broken, and extraordinarily unlikely -- nigh on impossible -- that the MSP430 is broken.
I suggest abandoning the post-mortem approach, which can be an endless timesink. Get back to a known working code base (the original, unmodified Blink app), and re-introduce tiny changes until it breaks again. Look for buffer overruns, uninitialized pointers, etc.
-- Chip
**Attention** This is a public forum