Doe Keil IDE support initializing stack space with a constant? For example with a #define. If not, please does someone have ARM Cortex M3/M4 assembler code to do that and where should it be located? For example in startup*.s prior to the branch to main?
OK ... and "the necessary small block of code" is?
A little bit of assembler with a loop storing your constant value should suffice.
You don't really expect me to draw it out do you?
I'm feeling generous (and had a few bored moments). This might be an acceptable start:
; Reset Handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main LDR R0, =Stack_Mem ;Added LDR R1, =Stack_Size ; LDR R2, =0xCCCCCCCC ; Fill STR R2, [R0], #4 ; SUBS R1,#4 ; BNE Fill ; LDR R0, =__main BX R0 ENDP
Thanks. I'll try that. After your build up ... it should work!
OK so the Reset Handler now looks like this,
; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =SystemInit BLX R0 LDR R0, =Stack_Mem ;Added LDR R1, =Stack_Size ; LDR R2, =0xCCCCCCCC ; Fill STR R2, [R0], #4 ; SUBS R1,#4 ; BNE Fill ; LDR R0, =__main BX R0 ENDP
It works! Thanks for your help. I have one more question.
I checked the fill worked by getting the STACK address from the *.map file. Why doesn't typing "STACK" or "Stack_Mem" etc. directly into the "Memory 1" Memory Window work?
In other words, how can I use a symbolic name in the IDE debugger to view the stack content?
It works!
Glad to be of help [in the end].
Sorry, but I will have to let someone else (who might know the answer) respond to that one.
There's a caveat. Although it works as I step through the assembler ... as soon as the program jumps to main the STACK gets overwritten and cleared to zero despite its AREA being marked NOINIT. Please does anyone have any idea why this happens and how to stop it?
Hmmm.
The area gets cleared by the scatter loader (executed between startup and entry to main).
This is where I have previously started using a slightly more complex scatter file. Using an UNINIT section for the segment that I din't want to be touched by the scatter loader.
OK. Thanks for the hint. I see the project's scatter file *.sct in \Obj\ folder and that I can specify a different one by unchecking the target Options/Linker/Use Memory Layout from Target Dialog checkbox.
So how do I get the STACK into an UNINIT'd section please? ... or where can I find instructions to make a new scatter file?
Sorry, I don't have much time now ... but here's a scatter file I've modified from one of the Blinky examples. I gave it a quick try and the stack is not now being cleared.
In the IDE, select this one (or the one that you'll modify accordingly).
LR_ROM1 0x00000000 0x04000000 { ; load region size_region ER_ROM1 0x00000000 0x04000000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_RAM1 0x20000000 0x00400000 { ; RW data .ANY (+RW +ZI) } RW_STACK +0 UNINIT ALIGN 16 ; RW data - Stack <<< THIS SECTION IS WHAT I ADDED { *.o (Stack) } }
Thanks very much for your generous help. It appears to work now as you described with the stack left full of 0xcccccccc.
Does this help:
http://www.keil.com/support/man/docs/armlink/armlink_CHDFHJDJ.htm
Possibly. Thanks for the pointer Andrew. The problem of stack initialisation now seems to be solved. Keil / ARM advise me I can't use a symbolic name directly but,
"If you open a Watch window, you can type 'sp' to 'watch' the stack pointer (r13). Then you can right-click on 'sp' and navigate to 'Add 'sp' to...' -> Memory 1. The stack pointer, is also available in the 'Registers' window."
Hi John,
Why modify the scatter file? It's not easy to put the code in the stack initalisation? The ram is initialized before.
__user_initial_stackheap LDR R0, =Stack_Mem ; Test stack LDR R1, =Stack_Size ; LDR R2, =0xCCCCCCCC ; Fill STR R2, [R0], #4 ; SUBS R1,#4 ; BNE Fill ; LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR ALIGN
thank you for your thread, it helped me a lot.