Setup
Keil: uVision 5.17.0.0 ARM: LPC1768 A standard project with some UARTS and I2C "Use memory Layout form target" is checked (using the standard scatter file) "Use MicroLIB" is not checked
from startup_LPC17xx.s Heap_Size EQU 0x00002000
AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem SPACE Heap_Size __heap_limit
Problem Any call to malloc returns NULL, that is, the system can not allocate memory.
Why does not the mallco work, is my only options to 1) Use microLIB 2) Implement _init_alloc() and __rt_heap_extend() on my own
?
Regards Stefan
"That really seems like the way you would allocate a heap in previous versions, but not in any recent."
So maybe you got two separate functions that tries to initialize the heap.
I am using Keil: uVision 5.17.0.0 But ARM says that __user_initial_stackheap is a legacy thingy infocenter.arm.com/.../index.jsp and the, nowdays, the proper function should be __user_setup_stackheap() I gues the Keil runtime library get messaed up if it see the __user_initial_stackheap() and does not initilize heap (internally) nor does it call __user_initial_stackheap.
It seems that the only way is to hide __user_initial_stackheap from Keil so it does not see it and assume it have to initilize the heap itself. Note, if __user_initial_stackheap is comment out, it is neccessary as well to do the following at the begining of startup_LPC17xx.s
EXPORT __heap_base EXPORT __heap_limit
1) Stop making any calls to _init_alloc.
2) You should be getting a link error on TEST2, no compile error. See #4 below. This would only seem to be if you exported __heap_limit, __heap_base and __initial_sp. If you export these, it will compile and link fine using both microlib and standardlib, but will not actually work in standardlib mode. Did you somehow change the standard code in a way that these variables were exported when not using the microlib? You may notice in the map file that sys_stackheap_outer.o references a __user_inital_stackheap that resides in sys_stackheap_outer.o when these are exported. If you do not export these variables, it will reference the __user_initial_stackheap in YOUR startup.s file. This is why your __user_initial_stackheap is not being called. i.e. You are not using the "standard" code at all, you have modified it to not work and then complained about it not working.
3) Look at your map file
USING:__user_setup_stackheap, your map file should show __rtentry4.o referencing __user_setup_stackheap in your startup.s file. There is no reference to __user_initial_stackheap.
USING: __user_initial_stackheap your mapfile should show sys_stackheap_outer.o referenceing __user_initial_stackheap in your startup.s file. You will also see __user_setup_stackheap referenceing sys_stackheap_outer.o
4) I have never seen __heap_limit defined as a variable when not using the microlib. I think the "standard" startup code is very specific in NOT creating a __heap_limit or __heap_base variable when not using the microlib. Don't define this as a variable.
It works now as expected, it was all related to one of all of the added lines at the top of startup_LPC..
EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit
If any of them, even if the program only have "EXPORT __initial_sp" (and not the other two) the heap dont get initalized. If none of them are exported then the runtime library will call __user_initial_stackheap as expected.
It is neccessary to export a new/seperate variabel if the stack top is going to be used somewhere else, like this
EXPORT __initial_stack_top Stack_Size EQU 0x00000800 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp __initial_stack_top
One interesting observation was that if the program had
EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit The map file will contain __rtentry4.o(.ARM.Collect$$rtentry$$00000004) refers to sys_stackheap_outer.o(.text) for __user_setup_stackheap sys_stackheap_outer.o(.text) refers to startup_lpc17xx.o(.text) for __user_initial_stackheap But they was never called
Conclusive: Dont export any of __initial_sp, __heap_base or __heap_limit form the startup_XXXX.s