- Instead, when MPU wrappers are not used, allow port to override
PRIVILEGED_FUNCTION, PRIVILEGED_DATA, or FREERTOS_SYSTEM_CALL
selectively, permitting custom section placement at link-time.
- Allows critical data to be placed in port-specific location for
improved performance, notably for cache-coherent SMP.
- Does not require enabling the full MPU wrappers.
Restore the original SVCall priority for the ARMv7-M MPU ports from
before #832. This change reduces the SVCall preemption priority from
zero (the highest) to a priority just higher than
configMAX_SYSCALL_INTERRUPT_PRIORITY (numerically lower).
---------
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
The task command path validated the command ID only against the upper bound. Add the corresponding lower-bound check so the accepted range is fully constrained.
Fix several documentation and example-code issues in the kernel header comments:
* queue.h: remove a stray semicolon after the 'if' and correct the
xHigherPriorityTaskWoken variable casing in the xQueueReceiveFromISR()
example; add the missing comma between parameters in the
xQueueGenericSend() prototype example.
* list.h: correct the doxygen \page tag for listGET_ITEM_VALUE_OF_HEAD_ENTRY.
* task.h: fix the uxIndexToCLear typo (-> uxIndexToClear).
These are documentation/example only changes that do not affect the
compiled library.
Signed-off-by: chenrongjun <chenrongjun@zepp.com>
* New API xTaskPeriodicDelay (#1349)
New function to be used for periodic tasks to ensure a constant
execution frequency. It is intended to supersede xTaskDelayUntil to
overcome its shortcomings, that is:
- avoid run away of pxPreviousWakeTime (#1339)
- catch up any skipped period immediately (and update pxPreviousWakeTime
accordingly), notify the caller of the number of periods skipped (by
returning them) and wait until the next period (it could be less than
xTimeIncrement if we are close to the next period)
- notify the caller when not enough ticks have been elapsed (by
returning 0) and handle the situation gracefully (by properly waiting
until the next wake time)
Signed-off-by: Nicola Fontana <ntd@entidi.it>
Co-authored-by: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com>
Defect: prvWriteMessageToBuffer() can write a truncated message-length header
into a message buffer when the data length does not fit the configured
configMESSAGE_BUFFER_LENGTH_TYPE and configASSERT() is compiled out,
desynchronizing framing at the receiver.
Root cause: the writer stores the length as a configMESSAGE_BUFFER_LENGTH_TYPE
value xMessageLength and only guards the "fits without truncation" condition
with configASSERT( ( size_t ) xMessageLength == xDataLengthBytes ). The
subsequent write was gated solely on available space, so with asserts disabled
a length that overflows the length type is written truncated while the full
data is copied, corrupting the message framing seen by the receiver.
Fix: gate the length-plus-data write on
( ( size_t ) xMessageLength == xDataLengthBytes ) in addition to the space
check. When the length cannot be represented without truncation, take the
"not enough space" path and write nothing. This runtime check is the only guard
against truncation when asserts are disabled.
A host regression test kept outside this repository demonstrates the fault
before the change and its absence afterwards (red then green).
Defect: xStreamBufferSend() and xStreamBufferSendFromISR() on a message buffer
can perform an out-of-bounds write when the required-space computation for a
message overflows size_t and configASSERT() is compiled out.
Root cause: for message buffers the code computes
xRequiredSpace = xDataLengthBytes + sbBYTES_TO_STORE_MESSAGE_LENGTH and guards
it only with configASSERT( xRequiredSpace > xDataLengthBytes ). When the
addition wraps size_t, the wrapped (smaller) xRequiredSpace passes the
subsequent space checks and the send proceeds to copy xDataLengthBytes bytes,
writing past the buffer. With asserts disabled there is no guard at all.
Fix: add a runtime check that returns 0 (nothing sent) when
xRequiredSpace <= xDataLengthBytes, in both the task and FromISR send paths, so
a wrapping message length is rejected regardless of the configASSERT() setting.
A host regression test kept outside this repository demonstrates the fault
before the change and its absence afterwards (red then green).
Defect: vPortGenerateSimulatedInterruptFromWindowsThread() in the MSVC-MingW
simulator port performs a shift by a caller-supplied interrupt number without
range checking it, giving undefined behavior for out-of-range values.
Root cause: the function pends an interrupt via ( 1UL << ulInterruptNumber )
into ulPendingInterrupts, but does not verify ulInterruptNumber is within the
width of that variable. A value greater than or equal to portMAX_INTERRUPTS
makes the shift undefined. The task-context sibling
vPortGenerateSimulatedInterrupt() already performs this bounds check.
Fix: gate the operation on ( ulInterruptNumber < portMAX_INTERRUPTS ) in
addition to the existing xPortRunning check, mirroring the task-context sibling
so both entry points are consistent.
A host regression test kept outside this repository demonstrates the fault
before the change and its absence afterwards (red then green).
Defect: xTaskCreate() / prvCreateTask() can under-allocate a task stack when a
caller supplies a very large uxStackDepth, leading to out-of-bounds writes when
the initial stack frame is set up.
Root cause: the stack is allocated as
( ( size_t ) uxStackDepth ) * sizeof( StackType_t ). If that product wraps
size_t, the allocation is far smaller than requested, yet
prvInitialiseNewTask() still computes the top of stack from the full
uxStackDepth and writes the initial context past the end of the allocation.
Fix: before allocating, reject creation when
( ( size_t ) uxStackDepth ) > ( SIZE_MAX / sizeof( StackType_t ) ), returning
NULL (task not created) instead of proceeding with an under-sized buffer.
A host regression test kept outside this repository demonstrates the fault
before the change and its absence afterwards (red then green).
Defect: pvPortMalloc() in heap_1.c can return a pointer outside the ucHeap
array when configTOTAL_HEAP_SIZE is configured smaller than or equal to
portBYTE_ALIGNMENT.
Root cause: configADJUSTED_HEAP_SIZE is defined as
( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ). When configTOTAL_HEAP_SIZE is
not larger than portBYTE_ALIGNMENT this unsigned subtraction underflows to a
very large size_t value. The "enough room left" check in pvPortMalloc()
compares an unsigned index against configADJUSTED_HEAP_SIZE, so the underflowed
value defeats the check and an allocation can be handed out past the end of the
heap array.
Fix: add a compile-time (compiler, not preprocessor) size check so a
nonsensical, too-small heap is rejected during the build. The compiler-level
check still works when configTOTAL_HEAP_SIZE is defined with a cast such as
( ( size_t ) 0x2000 ).
A host regression test kept outside this repository demonstrates the fault
before the change and its absence afterwards (red then green).
Document that MemoryRegion_t.ulParameters macros are port specific so users select the tskMPU_REGION_* or portMPU_REGION_* values that match their MPU port.
Signed-off-by: Old-Ding <ai.neo.ae86@gmail.com>
Co-authored-by: Old-Ding <ai.neo.ae86@gmail.com>
When using MPU wrappers v2, xTimerDelete needs to be a real function
rather than a macro so that the kernel object pool index can be freed
after the timer is successfully deleted. Without this, deleting a timer
leaks the kernel object pool entry.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
When MPU is enabled, the first item in the TCB is not the top of the
stack but the stored context location. As a result, xSecureContext
is located at a negative offset from that position rather than at
offset 0. The current implementation unconditionally reads
xSecureContext at offset 0, which returns an incorrect value when MPU
is enabled.
This commit updates vPortFreeSecureContext to read xSecureContext at
the correcct offset based on the port configuration:
- CM33/CM35P/CM52/CM55/CM85/STAR_MC3: -20 (or -36 with PAC enabled)
- CM23: -20 (no PAC support)
- Without MPU: 0 (xSecureContext remains at the top of stack)
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Read uxCurrentNumberOfTasks once into uxArraySize and use that local
variable for both the size check and pvPortMalloc() call. The previous
code read the volatile variable twice, allowing a task to be created
between the reads, resulting in an undersized allocation that could
cause a buffer overflow in uxTaskGetSystemState().
When using MPU wrappers version 2 (configUSE_MPU_WRAPPERS_V1 == 0),
portRAISE_PRIVILEGE() is a no-op because the portSVC_RAISE_PRIVILEGE
handler is compiled only for MPU wrappers version 1. As a result, an
unprivileged task that calls taskENTER_CRITICAL() does not actually raise
its privilege, so the subsequent BASEPRI write is ignored by the hardware
and the critical section silently fails to mask interrupts. This produces
latent, hard-to-debug faults.
configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is therefore not supported with
MPU wrappers version 2. In the ARMv7-M MPU ports:
- When the option is left undefined under v2, default it to 0 instead of 1
so the dangerous default configuration is safe.
- When the option is explicitly set to 1 under v2, raise a compile-time
#error so the unsupported configuration is rejected loudly rather than
failing silently at run time.
Behaviour for MPU wrappers version 1 is unchanged.
uxTaskBasePriorityGet reused the \defgroup id 'uxTaskPriorityGet'
already defined by uxTaskPriorityGet, only with a different title.
Doxygen reported:
task.h: warning: group uxTaskPriorityGet: ignoring title
"uxTaskBasePriorityGet" that does not match old title
"uxTaskPriorityGet"
Give uxTaskBasePriorityGet its own group id so both functions are
documented correctly.
Batching stream buffers are documented to unblock receivers only after the buffered byte count exceeds the trigger level, but both xStreamBufferSend() paths currently notify as soon as the count reaches it.
That equality case wakes the blocked receiver too early, causing xStreamBufferReceive() to return 0 bytes while the buffer still holds exactly trigger-level data. Route both task and ISR send paths through a shared trigger helper so batching buffers require a strict greater-than check while existing stream and message buffer semantics remain unchanged.
Fixes#1375
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Windows defines a long as a 32-bit value regardless if a 32 or 64 bit
OS is used. This makes a 64-bit tick an `unsigned long long` which was
introduced after C90.
When configENABLE_HEAP_PROTECTOR is 1 and a pvPortMalloc() request cannot
be satisfied by any free block, the free list search advances onto the end
marker (pxEnd) and validates it with heapVALIDATE_BLOCK_POINTER().
pxEnd is located at pucHeapHighAddress and is not part of the usable heap,
so the macro's "( pxBlock ) < pucHeapHighAddress" bounds check fails and the
configASSERT() fires on what is a normal out-of-memory condition. The code
should instead fall through and call the malloc failed hook.
Exclude the end marker from validation in the search loop so an allocation
that cannot be satisfied returns NULL (and invokes vApplicationMallocFailedHook
when configUSE_MALLOC_FAILED_HOOK is 1) without asserting.
* Fix MISRA C 2012 Rule 20.4: Replace `#define static` with STATIC macro
Replace `#define static` with `#define STATIC static` to prevent the macro
from shadowing the C `static` keyword. This also ensures static variables
in `vApplicationGetIdleTaskMemory()` and `vApplicationGetPassiveIdleTaskMemory()`
remain static even when portREMOVE_STATIC_QUALIFIER is defined, preventing
use-after-free bugs from stack-allocated storage.
croutine.c: #if condition is ( configUSE_CO_ROUTINES != 0 ) but the
#endif comment incorrectly said == 0, reversing the logic.
queue.c: #if condition is ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
but the #endif comment incorrectly said configSUPPORT_STATIC_ALLOCATION,
naming the wrong configuration option.
These are purely cosmetic comment fixes with zero runtime impact.
Signed-off-by: hanzhijian <hanzhijian@zepp.com>
Mark vPortYield as a weak symbol so chips with a dedicated software
interrupt register can substitute their own yield trigger.
Default behaviour is unchanged when no strong override is linked.
Signed-off-by: Maxim De Clercq <maximdeclercq00@gmail.com>
Replace `( 1 << n )` with `( 1UL << n )` in all left-shift expressions
in portable/MSVC-MingW/port.c. Shifting a signed int by >= 31 is
undefined behavior per ISO C11 §6.5.7.
Both the WIN32-MSVC and WIN32-MingW demos
are failing due to long file paths. This is
because of a transitive dependency path which is
submodules further extending the path length. Enabling
windows long path support fixes this.
Validate that ulSecureStackSize + securecontextSTACK_SEAL_SIZE does not
overflow before calling pvPortMalloc in the ARMv8-M secure context ports.
Reported by Jordan Mecom (Block, Inc.)
The comment after vPortSetupTimerInterrupt in GCC and IAR RISC-V port.c duplicated configMTIME_BASE_ADDRESS and omitted configMTIMECMP_BASE_ADDRESS. Align the comment with the matching #if condition.
* ARMv8-M: Add SMP support to CM33 NTZ non-MPU port
* Enable SMP for Arm Cortex-M33 NTZ port for
GCC, ArmClang, and IAR toolchains.
* Add per-core scheduler/port state: critical nesting.
* Introduce spinlocks and inter-core yield/wakeup (SEV/WFE) plus
primary/secondary core bring-up sync.
* Update PendSV (i.e., context switch assembly) for core-safe
preemption and restore paths.
* Extend port macros/hooks for SMP in portmacrocommon.h,
single-core builds remain unchanged.
* Add the SMP boot sequence along with the necessary steps to enable
SMP on Armv8-M based ports. This should help developers understand
the requirements and process for enabling SMP on their
Armv8-M based applications.
* Update the kernel checker script to accept comma separated years
in the copyright header.
Signed-off-by: Ahmed Ismail <Ahmed.Ismail@arm.com>
* Armv8-M: Copy SMP changes to all Armv8-M based ports
This commit executes the `copy_files.py` python script
to copy the changes applied in the previous commit
(i.e., SMP changes) to all the Armv8-M based ports.
Signed-off-by: Ahmed Ismail <Ahmed.Ismail@arm.com>
---------
Signed-off-by: Ahmed Ismail <Ahmed.Ismail@arm.com>
* Remove github_token input
Inputs need to be literal, static values.
Instead we should simply use `${{ secrets.GITHUB_TOKEN }}`
which is resolved at runtime
* Copy over generated SBOM files
The SBOM generator currently outputs the files
at the workspace root.