* make port exitable
* correctly set xPortRunning to False
* add suggestions from Review
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
* add suggestions from Review
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
---------
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
The introduction of `portMEMORY_BARRIER` will ensure
the places in the kernel use a barrier will work.
For example, `xTaskResumeAll` has a memory barrier
to ensure its correctness when compiled with optimization
enabled. Without the barrier `xTaskResumeAll` can fail
(e.g. start reading and writing to address 0 and/or
infinite looping) when `xPendingReadyList` contains more
than one task to restore.
In `xTaskResumeAll` the compiler chooses to cache the
`pxTCB` the first time through the loop for use
in every subsequent loop. This is incorrect as the
removal of `pxTCB->xEventListItem` will actually
change the value of `pxTCB` if it was read again
at the top of the loop. The barrier forces the compiler
to read `pxTCB` again at the top of the loop.
The compiler is operating correctly. The removal
`pxTCB->xEventListItem` executes on a `List_t *`
and `ListItem_t *`. This means that the compiler
can assume that any `MiniListItem_t` values are
unchanged by the loop (i.e. "strict-aliasing").
This allows the compiler to cache `pxTCB` as it
is obtained via a `MiniListItem_t`. This is incorrect
in this case because it is possible for a `ListItem_t *`
to actually alias a `MiniListItem_t`. This is technically
a "violation of aliasing rules" so we use the the barrier
to disable the strict-aliasing optimization in this loop.
Adds RV32E support to the IAR port. This is done by
reducing our register usage to the first 16 registers
only.
Influenced by changes in https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/543
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
* Add support for the configUSE_TASK_FPU_SUPPORT in the GCC/ARM_CR5 port
This is done almost identically as in the GCC/ARM_CA9 port
* Adjust task stack initialitation of the GCC/ARM_CR5 port
Ensure that the task stack initialization is done correctly for the
different options of configUSE_TASK_FPU_SUPPORT.
This is very similar to the GCC/ARM_CA9 port. The only meaningful
difference is, that the FPU of the Cortex-R5 has just sixteen 64-bit
floating point registers as it implements the VFPv3-D16 architecture.
You may also refer to the ARM documentation
* Add support for FPU safe interrupts to the GCC/ARM_CR5 port
Similar to GCC/ARM_CA9 port
* Clarify comment about the size of the FPU registers of Cortex R5
* Fix tickless idle when stopping systick on zero...
...and don't stop SysTick at all in the eAbortSleep case.
Prior to this commit, if vPortSuppressTicksAndSleep() happens to stop
the SysTick on zero, then after tickless idle ends, xTickCount advances
one full tick more than the time that actually elapsed as measured by
the SysTick. See "bug 1" in this forum post:
https://forums.freertos.org/t/ultasknotifytake-timeout-accuracy/9629/40
SysTick
-------
The SysTick is the hardware timer that provides the OS tick interrupt
in the official ports for Cortex M. SysTick starts counting down from
the value stored in its reload register. When SysTick reaches zero, it
requests an interrupt. On the next SysTick clock cycle, it loads the
counter again from the reload register. To get periodic interrupts
every N SysTick clock cycles, the reload register must be N - 1.
Bug Example
-----------
- Idle task calls vPortSuppressTicksAndSleep(xExpectedIdleTime = 2).
[Doesn't have to be "2" -- could be any number.]
- vPortSuppressTicksAndSleep() stops SysTick, and the current-count
register happens to stop on zero.
- SysTick ISR executes, setting xPendedTicks = 1
- vPortSuppressTicksAndSleep() masks interrupts and calls
eTaskConfirmSleepModeStatus() which confirms the sleep operation. ***
- vPortSuppressTicksAndSleep() configures SysTick for 1 full tick
(xExpectedIdleTime - 1) plus the current-count register (which is 0)
- One tick period elapses in sleep.
- SysTick wakes CPU, ISR executes and increments xPendedTicks to 2.
- vPortSuppressTicksAndSleep() calls vTaskStepTick(1), then returns.
- Idle task resumes scheduler, which increments xTickCount twice (for
xPendedTicks = 2)
In the end, two ticks elapsed as measured by SysTick, but the code
increments xTickCount three times. The root cause is that the code
assumes the SysTick current-count register always contains the number of
SysTick counts remaining in the current tick period. However, when the
current-count register is zero, there are ulTimerCountsForOneTick
counts remaining, not zero. This error is not the kind of time slippage
normally associated with tickless idle.
*** Note that a recent commit https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/e1b98f0
results in eAbortSleep in this case, due to xPendedTicks != 0. That
commit does mostly resolve this bug without specifically mentioning
it, and without this commit. But that resolution allows the code in
port.c not to directly address the special case of stopping SysTick on
zero in any code or comments. That commit also generates additional
instances of eAbortSleep, and a second purpose of this commit is to
optimize how vPortSuppressTicksAndSleep() behaves for eAbortSleep, as
noted below.
This commit also includes an optimization to avoid stopping the SysTick
when eTaskConfirmSleepModeStatus() returns eAbortSleep. This
optimization belongs with this fix because the method of handling the
SysTick being stopped on zero changes with this optimization.
* Fix imminent tick rescheduled after tickless idle
Prior to this commit, if something other than systick wakes the CPU from
tickless idle, vPortSuppressTicksAndSleep() might cause xTickCount to
increment once too many times. See "bug 2" in this forum post:
https://forums.freertos.org/t/ultasknotifytake-timeout-accuracy/9629/40
SysTick
-------
The SysTick is the hardware timer that provides the OS tick interrupt
in the official ports for Cortex M. SysTick starts counting down from
the value stored in its reload register. When SysTick reaches zero, it
requests an interrupt. On the next SysTick clock cycle, it loads the
counter again from the reload register. To get periodic interrupts
every N SysTick clock cycles, the reload register must be N - 1.
Bug Example
-----------
- CPU is sleeping in vPortSuppressTicksAndSleep()
- Something other than the SysTick wakes the CPU.
- vPortSuppressTicksAndSleep() calculates the number of SysTick counts
until the next tick. The bug occurs only if this number is small.
- vPortSuppressTicksAndSleep() puts this small number into the SysTick
reload register, and starts SysTick.
- vPortSuppressTicksAndSleep() calls vTaskStepTick()
- While vTaskStepTick() executes, the SysTick expires. The ISR pends
because interrupts are masked, and SysTick starts a 2nd period still
based on the small number of counts in its reload register. This 2nd
period is undesirable and is likely to cause the error noted below.
- vPortSuppressTicksAndSleep() puts the normal tick duration into the
SysTick's reload register.
- vPortSuppressTicksAndSleep() unmasks interrupts before the SysTick
starts a new period based on the new value in the reload register.
[This is a race condition that can go either way, but for the bug
to occur, the race must play out this way.]
- The pending SysTick ISR executes and increments xPendedTicks.
- The SysTick expires again, finishing the second very small period, and
starts a new period this time based on the full tick duration.
- The SysTick ISR increments xPendedTicks (or xTickCount) even though
only a tiny fraction of a tick period has elapsed since the previous
tick.
The bug occurs when *two* consecutive small periods of the SysTick are
both counted as ticks. The root cause is a race caused by the small
SysTick period. If vPortSuppressTicksAndSleep() unmasks interrupts
*after* the small period expires but *before* the SysTick starts a
period based on the full tick period, then two small periods are
counted as ticks when only one should be counted.
The end result is xTickCount advancing nearly one full tick more than
time actually elapsed as measured by the SysTick. This is not the kind
of time slippage normally associated with tickless idle.
After this commit the code starts the SysTick and then immediately
modifies the reload register to ensure the very short cycle (if any) is
conducted only once. This strategy requires special consideration for
the build option that configures SysTick to use a divided clock. To
avoid waiting around for the SysTick to load value from the reload
register, the new code temporarily configures the SysTick to use the
undivided clock. The resulting timing error is typical for tickless
idle. The error (commonly known as drift or slippage in kernel time)
caused by this strategy is equivalent to one or two counts in
ulStoppedTimerCompensation.
This commit also updates comments and #define symbols related to the
SysTick clock option. The SysTick can optionally be clocked by a
divided version of the CPU clock (commonly divide-by-8). The new code
in this commit adjusts these comments and symbols to make them clearer
and more useful in configurations that use the divided clock. The fix
made in this commit requires the use of these symbols, as noted in the
code comments.
* Fix tickless idle with alternate systick clocking
Prior to this commit, in configurations using the alternate SysTick
clocking, vPortSuppressTicksAndSleep() might cause xTickCount to jump
ahead as much as the entire expected idle time or fall behind as much
as one full tick compared to time as measured by the SysTick.
SysTick
-------
The SysTick is the hardware timer that provides the OS tick interrupt
in the official ports for Cortex M. SysTick starts counting down from
the value stored in its reload register. When SysTick reaches zero, it
requests an interrupt. On the next SysTick clock cycle, it loads the
counter again from the reload register. The SysTick has a configuration
option to be clocked by an alternate clock besides the core clock.
This alternate clock is MCU dependent.
Scenarios Fixed
---------------
The new code in this commit handles the following scenarios that were
not handled correctly prior to this commit.
1. Before the sleep, vPortSuppressTicksAndSleep() stops the SysTick on
zero, long after SysTick reached zero. Prior to this commit, this
scenario caused xTickCount to jump ahead one full tick for the same
reason documented here: 0c7b04bd3a
2. After the sleep, vPortSuppressTicksAndSleep() stops the SysTick
before it loads the counter from the reload register. Prior to this
commit, this scenario caused xTickCount to jump ahead by the entire
expected idle time (xExpectedIdleTime) because the current-count
register is zero before it loads from the reload register.
3. Prior to return, vPortSuppressTicksAndSleep() attempts to start a
short SysTick period when the current SysTick clock cycle has a lot of
time remaining. Prior to this commit, this scenario could cause
xTickCount to fall behind by as much as nearly one full tick because the
short SysTick cycle never started.
Note that #3 is partially fixed by 967acc9b20
even though that commit addresses a different issue. So this commit
completes the partial fix.
* Improve comments and name of preprocessor symbol
Add a note in the code comments that SysTick requests an interrupt when
decrementing from 1 to 0, so that's why stopping SysTick on zero is a
special case. Readers might unknowingly assume that SysTick requests
an interrupt when wrapping from 0 back to the load-register value.
Reconsider new "_SETTING" suffix since "_CONFIG" suffix seems more
descriptive. The code relies on *both* of these preprocessor symbols:
portNVIC_SYSTICK_CLK_BIT
portNVIC_SYSTICK_CLK_BIT_CONFIG **new**
A meaningful suffix is really helpful to distinguish the two symbols.
* Revert introduction of 2nd name for NVIC register
When I added portNVIC_ICSR_REG I didn't realize there was already a
portNVIC_INT_CTRL_REG, which identifies the same register. Not good
to have both. Note that portNVIC_INT_CTRL_REG is defined in portmacro.h
and is already used in this file (port.c).
* Replicate to other Cortex M ports
Also set a new fiddle factor based on tests with a CM4F. I used gcc,
optimizing at -O1. Users can fine-tune as needed.
Also add configSYSTICK_CLOCK_HZ to the CM0 ports to be just like the
other Cortex M ports. This change allowed uniformity in the default
tickless implementations across all Cortex M ports. And CM0 is likely
to benefit from configSYSTICK_CLOCK_HZ, especially considering new CM0
devices with very fast CPU clock speeds.
* Revert changes to IAR-CM0-portmacro.h
portNVIC_INT_CTRL_REG was already defined in port.c. No need to define
it in portmacro.h.
* Handle edge cases with slow SysTick clock
Co-authored-by: Cobus van Eeden <35851496+cobusve@users.noreply.github.com>
Co-authored-by: abhidixi11 <44424462+abhidixi11@users.noreply.github.com>
Co-authored-by: Joseph Julicher <jjulicher@mac.com>
Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com>
* Add better pointer declaration readability
I revised the declaration of single-line pointers by splitting it into
multiple lines. Now, every pointer is declared (and initialized
accordingly) on its own line. This refactoring should enhance
readability and decrease the probability of error when a new pointer is
added/removed or a current one has its initialization value modified.
Signed-off-by: Cristian Cristea <cristiancristea00@gmail.com>
* Remove unnecessary whitespace characters and lines
It removes whitespace characters at the end of lines (empty or
othwerwise) and clear lines at the end of the file (only one remains).
It is an automatic operation done by git.
Signed-off-by: Cristian Cristea <cristiancristea00@gmail.com>
Signed-off-by: Cristian Cristea <cristiancristea00@gmail.com>
* Update RISC-V IAR port to support vector mode.
* uncrustify
Co-authored-by: David Chalco <david@chalco.io>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com>
It was possible for an unprivileged task to invoke any function with
privilege by passing it as a parameter to MPU_xTaskCreate,
MPU_xTaskCreateStatic, MPU_xTimerCreate, MPU_xTimerCreateStatic, or
MPU_xTimerPendFunctionCall.
This commit ensures that MPU_xTaskCreate and MPU_xTaskCreateStatic can
only create unprivileged tasks. It also removes the following APIs:
1. MPU_xTimerCreate
2. MPU_xTimerCreateStatic
3. MPU_xTimerPendFunctionCall
We thank Huazhong University of Science and Technology for reporting
this issue.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
It was possible for a third party that had already independently gained
the ability to execute injected code to achieve further privilege
escalation by branching directly inside a FreeRTOS MPU API wrapper
function with a manually crafted stack frame. This commit removes the
local stack variable `xRunningPrivileged` so that a manually crafted
stack frame cannot be used for privilege escalation by branching
directly inside a FreeRTOS MPU API wrapper.
We thank Certibit Consulting, LLC, Huazhong University of Science and
Technology and the SecLab team at Northeastern University for reporting
this issue.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
ARMv7-M allows overlapping MPU regions. When 2 MPU regions overlap, the
MPU configuration of the higher numbered MPU region is applied. For
example, if a memory area is covered by 2 MPU regions 0 and 1, the
memory permissions for MPU region 1 are applied.
We use 5 MPU regions for kernel code and kernel data protections and
leave the remaining for the application writer. We were using lowest
numbered MPU regions (0-4) for kernel protections and leaving the
remaining for the application writer. The application writer could
configure those higher numbered MPU regions to override kernel
protections.
This commit changes the code to use highest numbered MPU regions for
kernel protections and leave the remaining for the application writer.
This ensures that the application writer cannot override kernel
protections.
We thank the SecLab team at Northeastern University for reporting this
issue.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This allows the application write to set FREERTOS_CONFIG_FILE_DIRECTORY
to whichever directory the FreeRTOSConfig.h file exists in.
This was reported here - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/545
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
When the heap is exhausted (no free block), start and end markers are
the only blocks present in the free block list:
+---------------+ +-----------> NULL
| | |
| V |
+ ----- + + ----- +
| | | | | |
| | | | | |
+ ----- + + ----- +
xStart pxEnd
The code block which traverses the list of free blocks to calculate heap
stats used a do..while loop that moved past the end marker when the heap
had no free block resulting in a NULL pointer dereference. This commit
changes the do..while loop to while loop thereby ensuring that we never
move past the end marker.
This was reported here - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/534
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
* Add xPortRemoveInterruptHandler API
This API is added to the MicroBlazeV9 port. It enables the application
writer to remove an interrupt handler.
This was originally contributed in this PR - https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/523
* Change API signature to return void
This makes the API similar to vPortDisableInterrupt.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gavin Lambert <uecasm@users.noreply.github.com>
* Clarify Cortex M7 r0p1 errata number in r0p1 specific port.
* Add ARM Cortex M7 r0p0 / r0p1 Errata 837070 workaround to CM4 MPU ports.
Optionally, enable the errata workaround by defining configTARGET_ARM_CM7_r0p0 or configTARGET_ARM_CM7_r0p1 in FreeRTOSConfig.h.
* Add r0p1 errata support to IAR port as well
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
* Change macro name to configENABLE_ERRATA_837070_WORKAROUND
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
After the xEventGroupWaitBits in vProtLockInternalSpinUnlockWithWait there was an assertion about
pxYiledSpinLock being NULL, however when xEventGroupWaitBits returns, IRQs have been re-enabled
and so it is no longer safe to assert on the state which is protected by IRQs being disabled.
Co-authored-by: graham sanderson <graham.sanderson@raspeberryi.com>
* Let each stream/message can use its own sbSEND_COMPLETED
In FreeRTOS.h, set the default value of configUSE_SB_COMPLETED_CALLBACK
to zero, and add additional space for the function pointer when
the buffer created statically.
In stream_buffer.c, modify the macro of sbSEND_COMPLETED which let
the stream buffer to use its own implementation, and then add an
pointer to the stream buffer's structure, and modify the
implementation of the buffer creating and initializing
Co-authored-by: eddie9712 <qw1562435@gmail.com>
* Add supposrt for ARM CM55
* Fix file header
* Remove duplicate code
* Refactor portmacro.h
1. portmacro.h is re-factored into 2 parts - portmacrocommon.h which is
common to all ARMv8-M ports and portmacro.h which is different for
different compiler and architecture. This enables us to provide
Cortex-M55 ports without code duplication.
2. Update copy_files.py so that it copies Cortex-M55 ports correctly -
all files except portmacro.h are used from Cortex-M33 ports.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
vApplicationMallocFailedHook was declared in each Heap file. which forces users to declare it and can cause problems if the prototype of the function changes.
Co-authored-by: Pierre-Noel Bouteville <pnb990@gmail.com>
This is needed to support the case when SysTick timer is not clocked
from the same source as CPU. This support already exists in other
Cortex-M ports.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
* Add a guard around mpu_wrappers.c
This avoid linker errors when this file is accidently compiled in
projects using non-MPU ports.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
* Fix formatting check
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>