MQX not restoring the stack on K70 Tower?

cancel
Showing results for 
Search instead for 
Did you mean: 

MQX not restoring the stack on K70 Tower?

Jump to solution
1,020 Views
Larry5335
Contributor IV

Customer created a very small test program to recreate the issue on the tower using MK70FN1M0VMJ12 mask 4N96B. Running this test program recreates the issue very quickly and very often.

 

What seems to be happening is that when a task is performing work using the floating point registers and it is interrupted by another task of higher priority that also uses the same floating point registers, then the lower priority task ends up with corrupted data in those floating point registers. For example, this code returns true very often:

 

test = 0.5f;

        if(test < 0.4f || test > 0.6f)

        {

retVal++;

        }

        else

        {

retVal++;

        }

 

If you look at the screen shots, you can see that the floating point register S0 is being used by the lower priority task. Then after a context switch, the higher priority task uses the same register. Then when the lower priority task resumes, the register S0 has the wrong value. If I make the tasks the same priority or I do this:

 

_int_disable();

        test = 0.5f;

        if(test < 0.4f || test > 0.6f)

        {

retVal++;

        }

        else

        {

retVal++;

        }

        _int_enable();

 

Then everything works fine. It’s like the RTOS is not restoring the stack properly. Can you please help us with this issue?

Original Attachment has been moved to: BugTest-(2).zip

0 Kudos
1 Solution
397 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Larry,

I investigated about this issue. I dont know why in the dispatcher the register store function is skipping FPU registers (you can refer to image at the bottom).

You can force this code to be executed by setting MQX_SAVE_FP_ALWAYS macro in mqx_cnfg.h and rebuilding PSP and BSP.

I hope this helps.

pastedImage_0.png

Regards,

Carlos

View solution in original post

0 Kudos
4 Replies
397 Views
sandeepgeorgema
Contributor I

Hi Carlos,

I'm facing the same issue. I have a few tasks doing floating point calculations. After context switching I'm getting junk values. If i do the calculations in critical section, I'm getting the expected results.

I tried the solution suggested by you (setting MQX_SAVE_FP_ALWAYS). But after that my code resets continuously.

On debugging, I find that after a reset, code branches to __boot() from the below part causing an infinite loop

#if MQX_SAVE_FP_ALWAYS && PSP_HAS_FPU
ldr r3, =_psp_push_fp_context
blx r3
#endif

 

Could you please help me on this issue??

Regards,

Sandeep

0 Kudos
397 Views
daweiyou
NXP Employee
NXP Employee

Hi all:

recently I meet same issue, but I have solved it, so post some conclusion here for reference.

Yes, as carlos mentioned, MQX don't save FPU register before enter isr, if MQX_SAVE_FP_ALWAYS == 0.

seem it's gap, but reference manual never suggest how to use FPU in ISR.

Normally there are three ways to implement fpu register save/restore as I understand.

1.#define MQX_SAVE_FP_ALWAYS 1

in dispatch.s, you could see, whatever task switch or interrupt isr always save fpu registers, and restore them when back;

but seem the engineer also told me the MQX crash, I guess too much or frequent save/restore maybe damage MQX, even in isr, they save fpu registers in SP, at least we must keep stack large enough.

2.define related floating point task with MQX_FLOATING_POINT_TASK

which could save/restore fpu register when task switch, same code in dispatch.s, in _pend_svc().

but as carlos's snapshot, if isr have floating operation, and MQX_SAVE_FP_ALWAYS=0, the FPU register will be changed in isr.

3.use below function in task to protect floating operation in task, 
bool _task_enable_fp(void);
/* Do your FPU calculation Here */
void _task_disable_fp(void);

actually, this solution is same as (2), this is for temporary FPU operation.

so from above description, I have some suggestion how to use FPU in MQX:

1.never use MQX_SAVE_FP_ALWAYS== 1, for there are some potential issue to crash MQX, we have no root cause now; and this solution always save/restore fpu registers, which take more time and memory resource;

2.don't use above (3) solution, which seem same as (2);

3.indentify which task use floating point operation, and define these tasks as MQX_FLOATING_POINT_TASK.

   if only task have floating point operation, which is enough.

if isr have fpu operation also, indentify which isr, and add _psp_push_fp_context() and _psp_pop_fp_context() call to include fpu operation, which wil save fpu content into C stack.

0 Kudos
398 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Larry,

I investigated about this issue. I dont know why in the dispatcher the register store function is skipping FPU registers (you can refer to image at the bottom).

You can force this code to be executed by setting MQX_SAVE_FP_ALWAYS macro in mqx_cnfg.h and rebuilding PSP and BSP.

I hope this helps.

pastedImage_0.png

Regards,

Carlos

0 Kudos
397 Views
kappa74
Contributor IV

Hi Carlos,

I have the same issue.

I use KDS2.0 MQX4.1.1 on micro MK60FN1M0VLQ12.

I tried to define MQX_SAVE_FP_ALWAYS as 1 but the problem is not solved.

Have you any suggest?

Thank you

Mirko

0 Kudos