I am using LPCXpresso v8.2.0 [Build 647] on Mac OS. My code is written in C++ and I am using asm routine for precise us delay. Processor is LPC54102.
For some reason after return from ASM call, my this pointer gets garbled, local member values are overwritten with some random values.
I am not sure if the problem is with ASM or some setting in IDE to enlarge stack size or ?
This code works fine on Cortex M3/M0 within the Keil IDE. Havent tried it with M4 in Keil.
Stepping through the routine doesnt reveal anything until the "BX lr" code returns to C++ part of code, then my values are already overwritten.
void _delay_us (int a_us)
{
asm(" CBZ R0, end");
asm(" MOV R2, R0");
asm("loop2:");
asm(" MOV R1, #15");
asm("loop:");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" SUB R1, R1, #1");
asm(" CMP R1, #0");
asm(" BNE loop");
asm(" SUB R2, R2, #1");
asm(" CMP R2, #0");
asm(" BNE loop2");
asm("end:");
asm(" BX lr");
}
And any kind of delay will cause overwrite ...
For example:
_delay_us(500);
Solved! Go to Solution.
Try disassembling your function to see exactly what the compiler has generated:
Disassembling objects and executables
Given the way that you have written your function, the C compiler will also add function entry/exit code. My suspicion is therefore that your issue is being triggered by you writing:
asm(" BX lr");
If you remove that statement, then I suspect things will then work.
Regards,
LPCXpresso Support
I would really recommend to avoid using assembly even in this case. Use normal C loop and NOP intrinsics to adjust the precise timing. If necessary modify compiler behavior with pragmas. Such code will be more portable. We do it this way. Of course you always have to check the generated code and measure its execution time (for every target and compiler).
Try disassembling your function to see exactly what the compiler has generated:
Disassembling objects and executables
Given the way that you have written your function, the C compiler will also add function entry/exit code. My suspicion is therefore that your issue is being triggered by you writing:
asm(" BX lr");
If you remove that statement, then I suspect things will then work.
Regards,
LPCXpresso Support
That really did the trick. Thanks. I would never guess :smileyhappy:
So it branched to return address from my ASM code and then at the end of c routine it did it again but this time in some weird memory location ?
Glad to hear this change fixed the problem for you. If you disassemble the function generated out of the compiler from your source, as I suggested before, you will see why. Your explicit return instruction caused your delay function to exit before the function exit code generated by the compiler was reached. Meaning the stack/registers were not restored before the return back to the caller. Hence the broken behaviour that you we seeing.
Regards,
LPCXpresso Support
Thank you for explaining. I will check the asm code as well.