I have a project that works until I add in some C modules that I inherited from someone else. The startup code (sam7.s) is the default startup code supplied by KEIL for the ATMEL AT91SAM7S256 (for MDK ARM V3.22a). The problem is that when the startup code gets to the point where it's supposed to branch to the C main function, it works okay until I add in these inherited C modules. Stepping through the startup code, the only difference I can find is that the top of the stack is in a different place for the two versions of the program. For the working version it's at 0x00201F20, and the non-working version it's at 0x002022C0. For the non-working version of code, when I get to the BX ASM statement shown below, rather than going to 'main', I end up in the default SWI handler.
; Enter the C code IMPORT __main LDR R0, =__main BX R0
The __main label in the MAP file is the same value for both versions of the code, and is at 0x0010014C.
Can anyone give me some hints as to what might be causing this problem, or how to debug it...?
Thanks!
P.S., I did find some references in the online knowledgebase to reserving space for the heap should this problem occur, and have reserved 0x8000 bytes for the heap, but that has had no effect on the symptom. Since this is a 'C'/ASM project (i.e., no C++ code), and no 'C' code could've been run yet (since the program hasn't made it to 'main' yet), I'm not sure how not reserving space for the heap could've caused this symptom either. Can anyone explain how not reserving space for the heap could cause this problem?
I would make sure you have include retarget.c in your project (look at examples if you have not). It is possible that the stdio system was initialized after including the other code and it was not initialized in your code.
You only reserve memory for a heap if you do dynamic memory allocations from said heap.
Thanks for the tip Robert.
I was not including a retarget.c file in my project, so I did a quick file search of my C:\KEIL\ARM directory and found quite a few to pick from. I looked at several for an ATMEL AT91SAM uC, and added the simplest one to my project to see what would happen. Here's what was in that file:
#include <rt_misc.h> #pragma import(__use_no_semihosting_swi) void _sys_exit(int return_code) { label: goto label; /* endless loop */ }
Now my project won't build (without errors) anymore. Apparently, the _sys_open and _ttywrch functions are being used somehow, although I can find no reference to them in any of my project files. I don't call printf, puts, scanf, or anything like that (aren't those the type of things that would fall under the "semihosting" category?); so I don't know why or where _sys_open or _ttywrch would be being called.
Besides... the right address for __main is in R0 when the BX R0 instruction is executed, so how could the uC not then branch to that address...? That code happens before any C code is executed. This problem (as best as I can tell) occurs whether I'm executing code from the debugger or not.
I'm stumped!
The code I inherited does do dynamic memory allocation (associated with file transfers across an EtherCAT network). I plan to eventually rewrite it so it doesn't. But for now... it does.
View all questions in Keil forum