Hi everybody, I'm using UART3 to get data and everything goes fine. I wrote a state machine to get the data and the current state is sent to the computer. But when I use a very simple function in the main function, the state sent to the computer is wrong. This is a very strange behavior, since the function simply does nothing! Obviously this is a very simplified situation and other functions doesn't work properly either. Does anybody knows the reason for that behavior? The functional minimal code is attached. INLINE u8 test(void) { return 1; } int main (void) { initSystemFrequency(); initComputer(); initGps(); EIC_IRQConfig(ENABLE); while(!flagSend2Computer); flagSend2Computer = 0; while(1) { test(); //if commented everything goes fine } } Thanks in advance, Bruno
Slow down! The description of your problem, and the code don't seem to tie up. There is no sending data to a 'computer' or state-machine here. And the code is not complete - critically you have not shown a declaration of flagSend2 or the code that sets it. If this flag is not declared volatile, and you have used optimisation, the loop is unlikely to ever exit. You have described one problem, then posted different code. You may be looking at a different problem in each case. You have not fully described the problem (or rather problems). For example how is the data wrong? Tell us what you send, and what is actually received? Have you considered byte ordering or structure packing differences for example? Much of your code in your example is likely to be optimised out if you switched on optimisation. You have a comment "//if commented everything goes fine" - what does that mean? You have commented this line - it won't affect the generated code. Do you mean "if commented-out (or removed)"? What does 'fine' mean, what do you expect to happen and what actually happens? I think you will have to explain more carefully. Give a concrete example, and say what you are observing and what you expected to observe. "fine", "wrong", and "strange behaviour" are not adequate descriptions of your observations. Clifford
Clifford Slocombe wrote: > Slow down! The description of your problem, and the code don't seem to > tie up. > > There is no sending data to a 'computer' or state-machine here. And the > code is not complete - critically you have not shown a declaration of > flagSend2 or the code that sets it. If this flag is not declared > volatile, and you have used optimisation, the loop is unlikely to ever > exit. Like I said just before the little piece of code, "the functional minimal code is attached" (it's the bug_function.tar.gz file). So, flagSend2computer is in the file "Computer.h". Furthermore, I'm not using optimisation. > You have described one problem, then posted different code. You may be > looking at a different problem in each case. You have not fully > described the problem (or rather problems). For example how is the data > wrong? Tell us what you send, and what is actually received? Have you > considered byte ordering or structure packing differences for example? I think you are right in some points. I poorly described my problem. The data that is received by UART3. This is the piece of code of UART3 (remember, the minimal functional code is attached - bug_function.tar.gz): void UART3_IRQHandler(void) { static vu8 stateGps = 0; static vu16 checksum = 0; static vu8 i = 0; vu8 id, packetSize; vu8 data; //UART_ItConfig(gps,UART_RxBufFull, DISABLE); data = (u8)gps->RxBUFR; stateGps+=48; UART_ByteSend(computer,&stateGps); stateGps-=48; switch (stateGps) { case 0: if (data == 1) { stateGps = 1; checksum=0; checksum += data; } break; case 1: id = data; stateGps = 2; checksum += data; break; case 2: if (data == (255-id)) { stateGps = 3; checksum += data; } else stateGps=0; break; case 3: packetSize = data; i = 0; stateGps = 4; checksum += data; break; case 4: i++; checksum += data; if (i == packetSize) stateGps = 5; break; case 5: if (data == (u8)checksum) stateGps = 6; else stateGps = 0; break; case 6: stateGps=0; break; } //UART_ItConfig(gps,UART_RxBufFull, ENABLE); } You can note the function call UART_ByteSend(computer,&stateGps). So, the state of data received is sent to my computer and I can trace all the states of data received. > Much of your code in your example is likely to be optimised out if you > switched on optimisation. You are completely right, but now I'm a little bit more worried about the problem that I'm trying to explain below =). > You have a comment "//if commented everything goes fine" - what does > that mean? You have commented this line - it won't affect the > generated code. Do you mean "if commented-out (or removed)"? What does > 'fine' mean, what do you expect to happen and what actually happens? Sorry, I made a bad use of the language. When I said //if commented everything goes fine, I tried to say: When I call test() (or any other function. It doesn't matter what it does), the state machine on UART3 doesn't reaches level 6. while(1) { test(); //if commented everything goes fine } When I remove test() the state machine on UART3 reaches level 6. while(1) { //test(); } As you can see, test doesn't anything, so it couldn't affect the data received on UART3. I can say more: suppose that test was: u8 a = 0, b = 0; //both global variables INLINE void test() { a = b; } If I call test() inside while(1), the state machine on UART3 *doesn't* reaches level 6, but if I put while(1) { a = b; } the state machine on UART3 reaches level 6! So, I use functions inside while(1) everything goes wrong. Note that I'm not using any optimisations... You can note too that global variables used both inside and out of interrupt are declared as volatiles. > I think you will have to explain more carefully. Give a concrete > example, and say what you are observing and what you expected to > observe. "fine", "wrong", and "strange behaviour" are not adequate > descriptions of your observations. > > Clifford Now I think that the problem is better explained =). Thanks, Bruno
Sorry I did not notice the attachment. Not that I would wade through all of that in any case. Sounds line a stack overflow or buffer oveverun to me. Perhaps the normal stack running interrupt stack or vice versa. This would be easier for you to determine using the debugger that for someone to analyse without your set-up. Clifford
> Sounds line a stack overflow or buffer oveverun to me. Perhaps the > normal stack running interrupt stack or vice versa. This would be easier > for you to determine using the debugger that for someone to analyse > without your set-up. > > Clifford Clifford, which (easy to use) debugger tool do you suggest? I don't have the habit of using debugging tools (yes, I know that's a shame...). Thanks, Bruno
Bruno Adorno wrote: >> Sounds line a stack overflow or buffer oveverun to me. Perhaps the >> normal stack running interrupt stack or vice versa. This would be easier >> for you to determine using the debugger that for someone to analyse >> without your set-up. >> >> Clifford > > Clifford, > which (easy to use) debugger tool do you suggest? I don't have the > habit of using debugging tools (yes, I know that's a shame...). > > Thanks, > Bruno Well since you are using GCC the defacto choice is GDB. The command line tool is a bit painful. The Insight GUI makes it easier. Insight is included with the WinARM tools in the Utilities folder. Your zip file included an openocd/wiggler configuration file so I assumed that you already had the necessary JTAG hardware.
> Well since you are using GCC the defacto choice is GDB. The command line > tool is a bit painful. The Insight GUI makes it easier. Insight is > included with the WinARM tools in the Utilities folder. Your zip file > included an openocd/wiggler configuration file so I assumed that you > already had the necessary JTAG hardware. Now I'm using Insight/GDB am I am able to connect to my STR711 board. But how can I see if the problem is stack overflow or buffer overrun? Indeed, I don't think that the problem is buffer overrun because I am not using any buffer in my program. Maybe the problem is stack overflow, but how can I see it? Thanks, Bruno
Bruno Adorno wrote: > Maybe the problem is stack overflow, but how can I see it? > Observe the stack pointer register in the register window. It starts high and grows downward. If your build generated a map file, then that will tell you the address of stack (which will be the stack 'top' since it grows downward). If the SP is lower that this address you have exhausted the stack. The exceeding of bounds of any array is referred to as a "buffer overrun". Clifford
Clifford Slocombe wrote: > Observe the stack pointer register in the register window. It starts > high and grows downward. If your build generated a map file, then that > will tell you the address of stack (which will be the stack 'top' since > it grows downward). If the SP is lower that this address you have > exhausted the stack. This was the piece of map file that refers to the stack: .stack 0x20000814 0x400 0x20000814 _stack_start_ = . *(.stack) 0x20000c14 . = ((_stack_start_ + _STACKSIZE) MAX_K .) fill 0x20000814 0x400 00 0x20000c14 _stack_end_ = (_stack_start_ + SIZEOF (.stack)) So, the address of stack is 0x20000c14 and it grows downward to 0x20000814, right? The SP register is 0x20000c04 and then is lower that 0x20000c14. So, I believe that I exhausted the stack. But something is strange. If I increase the size of stack, SP still points to an address lower than address of stack: .stack 0x20000414 0x800 0x20000414 _stack_start_ = . *(.stack) 0x20000c14 . = ((_stack_start_ + _STACKSIZE) MAX_K .) fill 0x20000414 0x800 00 0x20000c14 _stack_end_ = (_stack_start_ + SIZEOF (.stack)) And the SP value is 0x20000c04. It means thas SP is always pointing to an address 40 bytes lower than stack beginning. This is correct or I understood all wrong? Thanks, Bruno
Bruno Adorno wrote: > The SP register is 0x20000c04 and then is lower that 0x20000c14. So, I > believe that I exhausted the stack. No, the stack pointer starts at _stack_end_ and is moved as the stack grows and shrinks. It must not be less than _stack_start_. The SP address changes as your code runs. Observe the stack at the start (on entry to main) and throughout your code. A good way to check the actual peak stack usage is to fill the stack with 0xee and then do a memory dump of the stack segment. The highest address from _stack_start_ still containing 0xee is the high-tide mark of your stack. If there are no 0xee values, you can be fairly sure you blew the stack. Clifford
Clifford Slocombe wrote: > Bruno Adorno wrote: >> The SP register is 0x20000c04 and then is lower that 0x20000c14. So, I >> believe that I exhausted the stack. > No, the stack pointer starts at _stack_end_ and is moved as the stack > grows and shrinks. It must not be less than _stack_start_. The SP > address changes as your code runs. Observe the stack at the start (on > entry to main) and throughout your code. > > A good way to check the actual peak stack usage is to fill the stack > with 0xee and then do a memory dump of the stack segment. The highest > address from _stack_start_ still containing 0xee is the high-tide mark > of your stack. If there are no 0xee values, you can be fairly sure you > blew the stack. > > Clifford I did it and I am not blewing the stack. Any other suggestions? Thanks, Bruno
I discovered the bug. There was two variables in UART3 (and that were related to the state of state machine) that were supposed to be static, but they were not (and they were not initialized). So, when I didn't use a function inside main(), the local variable in UART3 luckily was always allocated in same place and the program worked fine. But when I used a function inside main(), all became messed up and the local variable was allocated in another memory region. Anyway, now I am able to use a debugger and I'm happy with that. Thanks. Bruno
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.