Hi,
I am trying to port a library that is working with FreeRTOS to RTX. The microcontroller is the same: STM32F4. The library uses critical sections. I have tried using the same implementation for the critical section for RTX as for FreeRTOS(BASEPRI) but I often end up in UsageFault. I know that RTX uses extensively the SVC in the code.
Could it be that the Critical sections should be implemented differently ? Do you know of any other differences between FreeRTOS and RTX that could cause problems?
Best regards, Sebastian
In RTX, the RTX critical sections (i.e. the OS calls) are protected by the SVC call from Thread mode, and by a circular buffer (OS_FIFO) that gets filled up by ISR routines and processed by the PendSV Handler before returning to Thread Mode.
There is no need for you to use Critical sections for the OS code.
You may need critical sections for your code / library code, but it is not clear what you are trying to protect from so it is hard to say how you should change it.
Here are some rules (while using RTX)
1) You cannot make an OS call from Thread mode if you have disabled interrupts
2) You cannot make an OS call from Thread mode if you have set the Base Priority to prevent SVC from running.
By default SysTick and PendSV are set the to lowest possible priority and the SVC is set to the lowest possible priority + 1. It is not likely that you can set BASEPRI to mask some interrupts without making it impossible to make OS calls.
3) You cannot make an OS call that uses SVC if you are not also running with the PSP as the active stack.
Hi and thank you for the quick response.
Yes, I'm referring to the critical sections in my code, not the OS code. Actually the code that I am porting uses them. It looks like the critical sections surround the access to some global variables (rather huge structures). The critical-section entry/exit is called from interrupts also (actually just one EXTI).
I have just been looking into the options of protecting sections of code (atomic) when using the Cortex M0+ family.
Googling around there appear to be two approaches:
(1) Interrupt (SVC)
(2) Software (PRIMASK)
At the moment I have used the software (2) approach based on discussion:
www.mcuoneclipse.com/.../
__attribute__((always_inline)) __INLINE uint32_t critical_Enter (void) { uint32_t primask; primask = __get_PRIMASK(); __disable_irq(); return primask; } __attribute__((always_inline)) __INLINE void critical_Exit (uint32_t primask) { __set_PRIMASK (primask); }
Keil appears to use both of these approaches within RTX.
What are the merits / trade-offs for each approach?
You can design your code to modify and restore BASEPRI to implement critical sections while using RTX.
It is not clear why you are having a problem. I can make suggestions for things to look at, but will not likely be able to resolve it.
1) Look at why you are in a usage fault. This will likely indicate what direction you need to continue looking in.
2) IF you are nesting your Critical sections, make sure you are restoring properly (not too early).
3) Make sure the BASEPRI you are using for the Critical Section is appropriate based on the interrupts in your system.
4) Make sure you are not making any OS calls while in a Critical section
5) You may consider disabling all interrupts [__disable_irq(), __enable_irq()] for you critical sections instead of trying to leave some available. Unless you need IRQ's to be processed for the (hopefully) brief time in the critical section, this removes some of the things that can go wrong. Often easier to do it by disabling all interrupts and only modify BASEPRI when you have a real need for some interrupts to execute even while in a critical section.
"I have just been looking into the options of protecting sections of code (atomic) when using the Cortex M0+ family."
You mean protecting sections of data - not code !
Yes, poor choice of word...I meant protecting data. Any opinion on why and when to use SVCs instead of s/w (PRIMASK) for Cortex-M0.