This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
FreeRTOS-Kernel/portable
Simon Beaudoin 61635d5b8b
Fix race condition when tracing is enabled (#95)
* Update port.c

I discovered a very snicky and tricky race condition scenario when integrating tracealyzer code into our project.

A little background  on CortexR5 : When the IRQ line (comming from the interrupt controller, to which every peripheral IRQ lines connect) of the processor rises and the IRQ Enable bit in the status register of the CPU permits it, the CPU traps into interrupt mode. Several things happen. First, the CPU finishes the instruction it was performing. Second, it places the content of the CPSR register into the SPSR_irq register. And third, the mode of the CPU is changed to IRQ_Mode and /!\ THE IRQ ENABLE BIT IN CPSR_irq IS AUTOMATICALLY CLEARED /!\. The reason is to ensure that upon landing into IRQ code, we find ourselves automatically in a critical section because we cannot be interrupted again because the bit is cleared. The programmer can, if he wants, re-enable IRQs inside IRQ code itself to allow interrupt nesting. But it has to be wanted and meditated. 


Now, inside portASM.S, at the end of 'FreeRTOS_IRQ_Handler' assembly function, a call to 'vTaskSwitchContextConst' is made if the variable 'ulPortYieldRequired' was set by someone while executing the interrupt. Before branching to that function, a 'CPSID	i' instruction was placed to ensure that interrupts are disabled in case someone re-enabled it. Inside 'vTaskSwitchContext', there is the macro 'traceTASK_SWITCHED_OUT' that gets populated when tracing is enabled. 

The bug is right there.. If the macro is populated and inside that macro there is a matching call to 'ulPortSetInterruptMask' and 'vPortClearInterruptMask', a race condition can occure is there is a OS Tick timer interrupt waiting at the interrupt controller's door. Upon calling 'vTaskSwitchContext', the interrupts are not masked in the interrupt controller, the only barrier against the CPU servicing that tick interrupt while already performing the function is that the IRQ Enable bit cleared. 'ulPortSetInterruptMask' 
does what's its supposed to do, but doesn't take into account the IRQ Enable bit in CPSR. Wheter or not the bit was cleared, the function sets it at the end. When calling the matching 'vPortClearInterruptMask', the function clears the interrupt mask in the interrupt controller. Because the IRQ Enable bit (that was cleared) has been set no matter what in 'ulPortSetInterruptMask', the CPU services the OS Tick Interrupt right away. 

The bug is there : instead of completing the 'vTaskSwitchContext' function, the CPU re-enters the switch context path right after 'traceTASK_SWITCHED_OUT' thus corrupting the CPU state and eventually triggering either an undefined instruction, data or instruction abort.

* Update port.c

Error on my part, this is the right inline asm code to retreive CPSR register

* Update port.c

Forgot an * while writing comment..
2020-08-10 09:46:39 -07:00
..
ARMClang Re-sync with upstream and stripping away none kernel related. 2020-02-10 13:45:57 -08:00
ARMv8M Use configSYSTICK_CLOCK_HZ to configure SysTick (#103) 2020-07-24 09:45:42 -07:00
BCC/16BitDOS Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
CCS Update incorrect port in comments (#87) 2020-07-15 19:44:57 -07:00
CodeWarrior Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
Common Change the xRunningPrivileged check from "!=true" to "==false" (#109) 2020-07-30 19:32:31 -07:00
GCC Fix race condition when tracing is enabled (#95) 2020-08-10 09:46:39 -07:00
IAR Allow application to override TEX,S,C and B bits for Flash and RAM (#113) 2020-08-08 18:37:14 -07:00
Keil Re-sync with upstream and stripping away none kernel related. 2020-02-10 13:45:57 -08:00
MemMang Place privileged symbols correctly (#84) 2020-07-14 16:22:42 -07:00
MikroC/ARM_CM4F Update portNVIC_SYSPRI2_REG to portNVIC_SHPR3_REG (#86) 2020-07-15 19:44:45 -07:00
MPLAB Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
MSVC-MingW Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
oWatcom/16BitDOS Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
Paradigm/Tern_EE Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
Renesas Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
Rowley Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
RVDS Allow application to override TEX,S,C and B bits for Flash and RAM (#113) 2020-08-08 18:37:14 -07:00
SDCC/Cygnal Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
Softune Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
Tasking/ARM_CM4F Update portNVIC_SYSPRI2_REG to portNVIC_SHPR3_REG (#86) 2020-07-15 19:44:45 -07:00
ThirdParty Update ESP32 port files (#92) 2020-07-30 20:58:51 -07:00
WizC/PIC18 Style: uncrustify kernel files 2020-07-08 10:24:06 -07:00
readme.txt Re-sync with upstream and stripping away none kernel related. 2020-02-10 13:45:57 -08:00

Each real time kernel port consists of three files that contain the core kernel
components and are common to every port, and one or more files that are
specific to a particular microcontroller and/or compiler.


+ The FreeRTOS/Source/Portable/MemMang directory contains the five sample
memory allocators as described on the http://www.FreeRTOS.org WEB site.

+ The other directories each contain files specific to a particular
microcontroller or compiler, where the directory name denotes the compiler
specific files the directory contains.



For example, if you are interested in the [compiler] port for the [architecture]
microcontroller, then the port specific files are contained in
FreeRTOS/Source/Portable/[compiler]/[architecture] directory.  If this is the
only port you are interested in then all the other directories can be
ignored.