cancel
Showing results for 
Search instead for 
Did you mean: 

Moving Function from flash to ITCM cause hard fault on sTM32H743

HAlzo
Senior

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

1 ACCEPTED SOLUTION

Accepted Solutions

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

9 REPLIES 9

>>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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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{}

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.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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

0693W000008zf72QAA.pngITCM_initalization1 & ITCM_initalization2 : code to intilize the ITCM RAM at start up

0693W000008zf7qQAA.png0693W000008zf7gQAA.pngC_Function : c code for the function which is located in ITCM

0693W000008zf31QAA.pngMemory_regions : memory regions after linking

0693W000008zf8KQAQ.pngITCMRAM : ITCM memory with function moved to it

0693W000008zf8UQAQ.pnglistfile1 : code from list file of code for calling the function located in ITCM

0693W000008zf8eQAA.pnglistfile2 : code from list file of the function located in ITCM

0693W000008zf8oQAA.pngDebug1, 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

0693W000008zfBxQAI.png0693W000008zfC7QAI.png0693W000008zfCHQAY.png0693W000008zfCRQAY.pngI wish this information give clear view of the problem

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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?

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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.