Greetings,
We're running uC/OS-II on the MPC5675K and are facing a few issues in development. We're using CW IDE 10.5
I have two questions in particular and would greatly appreciate if someone can help us debug or resolve the issue. Thanks in advance!
Question 1
At some points in task execution, we notice that the values of global variables and local variables are not in agreement.
For example, as part of the task, we read the global value and store it into the local variable.
However, at certain times, we notice that these values are different from each other.
We have ensured that non-atomic accesses are not the issue, since we have kept mutexes in place.
Also, this issue occurs when the system is handling a lot of interrupts (FlexCAN, UART).
Any pointers on how to debug this?
Question 2
To comply with the EABI, does the stack pointer need to be 8-byte aligned or 16-byte aligned, for Power e200z760n3?
Also, depending on that, could someone provide an example on how to correctly set up the stack frame for context switching?
Thanks once again.
Any help is much appreciated.
Solved! Go to Solution.
Hi Dhiraj,
Yes, stack frame has to be 16 bytes aligned.
You can inspire by the interrupt prologue/epilogue generated by the compiler:
; 13:
; 14: __declspec(interrupt)
; 15: void TestIsr(void)
; 16: {
//interrupt prolog
stwu rsp,-160(rsp)
stw r0,36(rsp)
mfmsr r0
oris r0,r0,0x0200
mtmsr r0
evmergelohi r0,r0,r0
stw r0,32(rsp)
mfctr r0
stw r0,16(rsp)
mfxer r0
stw r0,20(rsp)
mfcr r0
stw r0,24(rsp)
mflr r0
stw r0,28(rsp)
evstdd r3,40(rsp)
evstdd r4,48(rsp)
evstdd r5,56(rsp)
evstdd r6,64(rsp)
evstdd r7,72(rsp)
evstdd r8,80(rsp)
evstdd r9,88(rsp)
evstdd r10,96(rsp)
evstdd r11,104(rsp)
evstdd r12,112(rsp)
li r0,152
evstddx r31,rsp,r0
li r0,144
evstddx r30,rsp,r0
li r0,136
evstddx r29,rsp,r0
//...jump to a ISR or execute ISR code here
//interrupt epilog
li r0,152
evlddx r31,rsp,r0
li r0,144
evlddx r30,rsp,r0
li r0,136
evlddx r29,rsp,r0
evldd r3,40(rsp)
evldd r4,48(rsp)
evldd r5,56(rsp)
evldd r6,64(rsp)
evldd r7,72(rsp)
evldd r8,80(rsp)
evldd r9,88(rsp)
evldd r10,96(rsp)
evldd r11,104(rsp)
evldd r12,112(rsp)
lwz r0,16(rsp)
mtctr r0
lwz r0,20(rsp)
mtxer r0
lwz r0,24(rsp)
mtcrf 0xff,r0
lwz r0,28(rsp)
mtlr r0
evldd r0,32(rsp)
addi rsp,rsp,160
rfi
Hope it helps.
Stan
Hello,
SPE/SPE2 instructions are described in SPE2PIM document available here:
The issue you observe is caused by the fact that R0 has special meaning in most of store instructions - destination address is 0x0 instead of a real register value.
See the instruction description:
So the solution is easy - use other register then R0 as a destination address register
Hope it helps.
Stan
Hello,
regarding Q#1:
If SPE compiler support is enabled the compiler might use optimization which takes advantage of the unused high half of the gpr vectors as storage and therefore avoids loading and storing to the stack.
It may cause some problems if interrupt prolog/epilog does not save/restore entire 64bit GPRs.
So it would be worth trying to disable this optimization by pragma below:
#pragma spill_to_spe off
or you can pass it via command line:
-pragma "spill_to_spe off"
Stan
Hi Stan,
Our interrupt prologue/epilogue is saving and restroring the entire 64-bit GPRs.
I took a look at the stack frame defined as part of the "Stack Frame Requirements" under "Function Calling Sequence" in the document Power-Arch-32-bit-ABI-supp-1.0-Embedded .
Do you have any suggestions/pointers about the rules to be followed for stack frame population by Interrupt handlers?
Are we expected to adhere to the stack frame requirements mentioned in the above document? Or does it just suffice that we save and restore all the register values, but using a stack frame not as defined by the document above?
Thanks in advance.
Hi Dhiraj,
Yes, stack frame has to be 16 bytes aligned.
You can inspire by the interrupt prologue/epilogue generated by the compiler:
; 13:
; 14: __declspec(interrupt)
; 15: void TestIsr(void)
; 16: {
//interrupt prolog
stwu rsp,-160(rsp)
stw r0,36(rsp)
mfmsr r0
oris r0,r0,0x0200
mtmsr r0
evmergelohi r0,r0,r0
stw r0,32(rsp)
mfctr r0
stw r0,16(rsp)
mfxer r0
stw r0,20(rsp)
mfcr r0
stw r0,24(rsp)
mflr r0
stw r0,28(rsp)
evstdd r3,40(rsp)
evstdd r4,48(rsp)
evstdd r5,56(rsp)
evstdd r6,64(rsp)
evstdd r7,72(rsp)
evstdd r8,80(rsp)
evstdd r9,88(rsp)
evstdd r10,96(rsp)
evstdd r11,104(rsp)
evstdd r12,112(rsp)
li r0,152
evstddx r31,rsp,r0
li r0,144
evstddx r30,rsp,r0
li r0,136
evstddx r29,rsp,r0
//...jump to a ISR or execute ISR code here
//interrupt epilog
li r0,152
evlddx r31,rsp,r0
li r0,144
evlddx r30,rsp,r0
li r0,136
evlddx r29,rsp,r0
evldd r3,40(rsp)
evldd r4,48(rsp)
evldd r5,56(rsp)
evldd r6,64(rsp)
evldd r7,72(rsp)
evldd r8,80(rsp)
evldd r9,88(rsp)
evldd r10,96(rsp)
evldd r11,104(rsp)
evldd r12,112(rsp)
lwz r0,16(rsp)
mtctr r0
lwz r0,20(rsp)
mtxer r0
lwz r0,24(rsp)
mtcrf 0xff,r0
lwz r0,28(rsp)
mtlr r0
evldd r0,32(rsp)
addi rsp,rsp,160
rfi
Hope it helps.
Stan
Hi .Where can I find the manual for the spe instructions like evstdd / evldd. I cannot get evstdd r4, 8(r0) to work when r0 points to memory area. But it passes compiling and linking process.I use MPC5675K evb and booke instruction set.
Hi Stan,
Thanks very much for this.
I also tried to let the compiler generate the prolog/epilog for me by using __declspec(interrupt) but I do not see the vector instructions (evstdd/evldd) like yours.
I am seeing se_stw and se_lwz in my compiler generated code.
Any pointers?
Thanks once again.
Other option is to declare interrupt routine with "save_spe" option:
__declspec(interrupt save_spe)
void testIsr()
{
...
}
Stan
Hi Stan,
Thank you very much for your help and patient support.
We seemed to have found the problem.
In our ISR Prolog/Epilog, some instructions (e_add2i.) were modifying the state of the Condition Register CR0 just after the interrupt arrived. This effectively changed the task's state from the time that it was interrupted.
We were then saving the wrong CR value in the task's context.
So, when we restored the tasks context, maybe it was branching absurdly due to wrong CR0, leading to strange code behaviour.
After accounting for the CR0 change in our Prolog/Epilog, it looks like the problem seems to have been solved.
Please do let us know what you think about this.
Thank you once again for your continued support.
Regards,
Dhiraj
Hi Dhiraj,
This prolog/epilog is generated by the compiler automatically e.g. if it detects usage of 64bit SPE vector data type:
#include <spe.h>
__ev64_opaque__ ev64SaveReg;
void test()
{
asm("nop");
}
__declspec(interrupt)
void TestIsr(void)
{
ev64SaveReg = __ev_create_u64(0);
test();
}
Stan
Hi Stan,
Thank you very much for your reply.
We will try this and update you.
Regards,
Dhiraj