2021-04-14 07:49 AM
Hi,
I am following the guide lines to move some functions from flash to ITCM .
1st I modified the linker file , then add itcm section parameters as extern variables in main file and after that I copied this function code after start up from flash to itcm section and finaly used section attribute to tell the linked to move this function to itcm section.
Always I get a hard fault at exiting from the moved function.
after some investigations I found that the called function push {lr} only when it's called on the other hand at the end of the function it pop {r4,r7,pc} and hard fault is caused at this point.
If I don't move this function to itcm section it will push {r4,r7,lr} and pop {r4,r7,pc} and will not cause any fault.
If I modified the stack so it pops the correct values in pc , it didn't cause hard fault.
in the generated list file I found that it push {r4,r7,lr} which is not consistent with actual assembly.
code is compiled from c with g3 and o0 options for debugging and optimizations.
How I can overcome this problem?
Thanks
Solved! Go to Solution.
2021-04-15 07:00 AM
The disassembly of the instruction at zero is not consistent with the code shown previously.
You really want to see the hex opcodes printed out in the disassembly listing.
Pretty sure push {nothing} is an illegal opcode.
2021-04-14 09:46 AM
>>How I can overcome this problem?
Perhaps by looking at how you're doing the control transfer to the subroutine?
Using the debugger, inspecting the stack and reporting what's there. Review that in the context of how the MCU is documented to function, and the expectations for registers, etc.
Watch also that you copy literals to RAM properly, and the code doesn't call any other functions outside it's scope. ie relative calls to functions you haven't copied.
Hard Faults are an indication you're doing something fundamentally incorrect, understand how the core functions.
Pushing LR implies you have other dependencies, the subroutine is not free-standing and calls other things.
2021-04-15 02:19 AM
Should all functions which are called from the function moved to ITCM be located as well in ITCM?!
I tried to use very simple function for testing, just a function which returns one value without calling any function, it cases hard fault at the befgining of the function at instruction push{}
2021-04-15 03:01 AM
What address are you calling? Is it odd? What about the stack?
Provide some register dumps, it shouldn't be necessary to guess what's wrong.
2021-04-15 06:21 AM
ICTM is located at 0x00000000 so if only one function is located in ITCM it will be located at the beginning which is not an odd address
you can find attached here some snapshoots which may help
linker: the linker with memory layout and mapping of itcm section
ITCM_initalization1 & ITCM_initalization2 : code to intilize the ITCM RAM at start up
C_Function : c code for the function which is located in ITCM
Memory_regions : memory regions after linking
ITCMRAM : ITCM memory with function moved to it
listfile1 : code from list file of code for calling the function located in ITCM
listfile2 : code from list file of the function located in ITCM
Debug1, Debug2, Debug3 and Debug4 : snapshoots for debugging from calling the function until hard fault with C, assembly , registers and stack shown .
4 snap shoots in next reply because system don't allow more pictures
2021-04-15 06:25 AM
I wish this information give clear view of the problem
2021-04-15 07:00 AM
The disassembly of the instruction at zero is not consistent with the code shown previously.
You really want to see the hex opcodes printed out in the disassembly listing.
Pretty sure push {nothing} is an illegal opcode.
2021-04-15 07:08 AM
This was my conclusion from the beginning.
push command pushes less registers than the required registers and if it's very simple function, push command pushes empty register list.
my question was and is why this happens and how to overcome this problem?
2021-04-15 07:19 AM
Look at what's moving the code into RAM, and what it's putting there. Cause it's not B480 / push {r7} which is what listfile2 claims it should be.
>>why this happens
&_sitcm is NOT ZERO!, fix the memcpy() to move aligned words, would be easier if the source could be cut-n-pasted
>>how to overcome this problem
memcpy ((void *)((uint32_t)&_sitcm & ~1), (void *)((uint32_t)&_siitcm & ~1), (uint32_t)&_eitcm - (uint32_t)&_sitcm)); // and tilde one, font looks like a minus
>>This was my conclusion from the beginning.
Not exactly, pushing registers is not the problem here. The disassembly shows different code. Enable the hex codes if your tool permits that
2021-04-15 08:00 AM
Thanks
I found the cause of the problem.
a pointer to string is used to update the string , the null case of this pointer was not handled which caued writing to address 00 which corrupt the Push instruction.