ctxp corrupted in _port_irq_epilogue

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

AndreR
Posts: 24
Joined: Mon Apr 28, 2014 2:01 pm

Re: ctxp corrupted in _port_irq_epilogue

Post by AndreR »

I don't have very much knowledge about the CM4 internals, but the ARMv7-M Reference Manual states:
Software can use a VMRS instruction to transfer flags in FPSCR to the APSR, and they then control
conditional execution...

I could not find any relation between VMRS and automatic stack frame storage. Furthermore, the STM32 programming manual states that the FPSCR is stacked automatically upon exception entry.

Additionally the commenting out of VMRS shouldn't have any effect to the stack at all, because it is an operation between two registers, but it apparently does.
I don't know if it makes much sense what I am talking about, but maybe you can get something out of it.

I am using the most recent GCC 4.8-2014q1 from https://launchpad.net/gcc-arm-embedded/+download.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ctxp corrupted in _port_irq_epilogue

Post by Giovanni »

The FP part of the stack frame is written in "lazy" mode, this means that the first FP instruction triggers the store. That instruction just make sure that the store has been triggered, its real operation is not important, it could have been any other FP instruction.

Giovanni
AndreR
Posts: 24
Joined: Mon Apr 28, 2014 2:01 pm

Re: ctxp corrupted in _port_irq_epilogue

Post by AndreR »

I just read this to get more insight into the topic:
http://infocenter.arm.com/help/topic/co ... index.html

I could not find any hint which requires it to explicitly trigger a FP lazy store in IRQ handling. Do you have additional material on this topic, which you used?

Furthermore, although the real operation is not important, it is executed. And in this case the VMRS instruction might change the behavior of a following instruction using APSR unpredictably.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ctxp corrupted in _port_irq_epilogue

Post by Giovanni »

I need to save the FP registers in the frame before a context switch or the thread FP context is lost. The save is not triggered if the ISR does not cause a context switch.

Code: Select all

Furthermore, although the real operation is not important, it is executed. And in this case the VMRS instruction might change the behavior of a following instruction using APSR unpredictably.


Good point but at source level it is:

Code: Select all

#if CORTEX_USE_FPU
      /* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
      (void) __get_FPSCR();
#endif


The status register is a register that the compiler assumes changed after a function call.

Giovanni
AndreR
Posts: 24
Joined: Mon Apr 28, 2014 2:01 pm

Re: ctxp corrupted in _port_irq_epilogue

Post by AndreR »

Okay, thanks for the info so far. Unfortunately I now have more important things to do in my project.
Hopefully I can find some time to create an hardware independent MWE. Maybe it is sufficient to use multiple timers triggering very fast, some with FPU operations, some without. And also some fast IRQs and some normal IRQs.

I guess it makes debugging much easier if you have the code running in front of an expert ;)
AndreR
Posts: 24
Joined: Mon Apr 28, 2014 2:01 pm

Re: ctxp corrupted in _port_irq_epilogue

Post by AndreR »

Hey Giovanni,

I finally had the time to modify my source to be hardware inpedendent. The setup is now as follows:
TIM2 + TIM4: fast IRQ, priority=2, no FPU usage
TIM1 + TIM8: fast IRQ, priority=3, uses FPU
TIM3: fast IRQ, priority=4, uses FPU
TIM7: normal IRQ, priority=12, no FPU usage, uses Mailbox as event system

Just call DriveInit() from your main(), it will setup all timers and start a dummy processing task for an event Mailbox. The code is somewhat dirty and still has some code in there, which used to be my FOC motor control. Nevertheless, it is required to put some load on the MCU, and to use FPU instructions.

I tested it on a STM32F303 at 72MHz on a custom board. It results in random faults after a few seconds (DEBUG build). Sometimes illegal access, usage fault, bus fault. Total MCU load is approx. 80%.
The IRQ frequency of TIM2+TIM4 (drive.c:176) and TIM7 (drive.c:188), somehow influences the fault, just play around with these values.

Please tell me if this examples also faults on your testboard, and if you have some time to investigate it.
Attachments
src.zip
MWE
(27.4 KiB) Downloaded 446 times
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ctxp corrupted in _port_irq_epilogue

Post by Giovanni »

Hi,

Thanks for the example, I am not ignoring it, it is the next thing in my list but this week I am a bit busy, I'll give it a try during next weekend.


Giovanni
AndreR
Posts: 24
Joined: Mon Apr 28, 2014 2:01 pm

Re: ctxp corrupted in _port_irq_epilogue

Post by AndreR »

Perfect, good to hear you are on it.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ctxp corrupted in _port_irq_epilogue

Post by Giovanni »

Hi,

You setup is very different from usual chibios demos, I can't just use that code because it assumes different vector names and ST libraries. Could you post a compilable project?

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ctxp corrupted in _port_irq_epilogue

Post by Giovanni »

I think that I found a possible cause for the problem, the workaround should be to not use the FPU from fast ISRs, compiling with -Os just makes hitting the race condition much less likely.

The problem is that the prologue ISR code does not prevent fast ISRs from occurring so a fast interrupt can overwrite the saved FP state after this line:

Code: Select all

      /* Now the FPCCR is modified in order to not restore the FPU status
         from the artificial return context.*/
      SCB_FPCCR = fpccr | FPCCR_LSPACT;


I am working on a fix.

Giovanni
Post Reply