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
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.