This commit updates the FreeRTOS port FPU unit tests so that they run for
multiple iterations, thus checking that a task's FPU context is properly
cleaned up on deletion.
Previously, IDF FreeRTOS would restrict the clean up of task memory (done by
vTaskDelete() or the Idle task) to only tasks pinned to the current core or
unpinned tasks. This was due to the need to clear the task's coprocessor
ownership on the other core (i.e., "_xt_coproc_owner_sa"). But this restriction
can be lifted by simply protecting access of "_xt_coproc_owner_sa" with a
spinlock.
This commit implements a "_xt_coproc_owner_sa_lock" to protect the access of
"_xt_coproc_owner_sa", thus vTaskDelete() and prvDeleteTCB() can now delete
tasks pinned to the other core so long as that task is not currently running.
Note: This fix was copied from the Xtensa port of Amazon SMP FreeRTOS
This commit removes the dependency on portUSING_MPU_WRAPPERS on the Xtensa port
of IDF FreeRTOS. This dependency was added due to a hack implemented in the
upstream port that required the usage of the "xMPUSettings" member of the TCB.
The "xMPUSettings" would be used as a pointer to the task's coprocessor save
area on the stack, even though FreeRTOS MPU support was not available.
The hack has now been removed, and the CPSA pointer is now calculated using
a combination of constant offsets values and the pxEndOfStack member of the
TCB.
Note: This impelemtation was copied from the Xtensa port of Amazon SMP FreeRTOS.
This commit refactors the FPU handling code on the Xtensa port of Amazon SMP
FreeRTOS in the following ways:
Auto-pinning via XT_RTOS_CP_EXC_HOOK
------------------------------------
The "_xt_coproc_exc" exception would previously automatically pin a task that
uses the FPU to the current core (to ensure that we can lazy save the task's FPU
context). However, this would mean that "xtensa_vectors.S" would need to be
OS-aware (to read the task's TCB structure).
This is now refactored so that "_xt_coproc_exc" calls a CP exception hook
function ("XT_RTOS_CP_EXC_HOOK") implemented in "portasm.S", thus allowing
"xtensa_vectors.S" to remain OS agnostic.
Using macros to acquire owner spinlock
--------------------------------------
The taking and relasing of the "_xt_coproc_owner_sa_lock" is now mostly
abstracted as the "spinlock_take" and "spinlock_release" macro. As a result,
"_xt_coproc_release" and "_xt_coproc_exc" are refactored so that:
- They are closer to their upstream (original) versions
- The spinlock is only taken when building for multicore
- The spinlock held region is shortened (now only protects the instructions
that access the "_xt_coproc_owner_sa" array
Other Changes
-------------
- Updated placing and comments of various "offset_..." constants used by
portasm.S
- Update description of "get_cpsa_from_tcb" assembly macro
- Tidied up some typos in the ".S" files
This commit fixes the following FPU/Coprocessor bugs in the Xtensa port of
Amazon SMP FreeRTOS:
- vPortCleanUpCoprocArea() does not calculate the correct pointer to the
task's CPSA (located on the task's stack). This can result in
- _xt_coproc_release() not releasing the task's CP ownership
- The next coprocessor exception will write the current CP owner (i.e., the
deleted task's CPSA) leading to memory corruption
- _xt_coproc_release() writes xCoreID instead of 0 when clearing a CP owner.
This results in the next CP exception trying to load the CP owner's CPSA at
the address of "xCoreID", leading to a double exception.
This commit updates variousf pytest scripts to expect
"main_task: Calling app_main()" instead of "cpu_start: Starting scheduler" as
indicator of the start of an application.
This commit refactors port_common.c so that it only contains implementation of
FreeRTOS port functions that are common to all FreeRTOS ports (i.e., on all
architectures and on all FreeRTOS implementations).
This commit refactors the OS startup functions as follows:
- Moved the OS/app startup functions listed below to "app_startup.c". Their
implementations are now common to all ports (RISC-V and Xtensa) of all
FreeRTOS implementations (IDF and Amazon SMP).
- esp_startup_start_app()
- esp_startup_start_app_other_cores()
- Removed esp_startup_start_app_common() as app startup functions are now
already common to all ports.
- Added extra logs to "main_task" to help with user debugging
Note: Increased startup delay on "unity_task". The "unity_run_menu()" is non
blocking, thus if the main task or other startup tasks have not been freed
by the time "unity_run_menu()" is run, those tasks will be freed the next time
"unity_task" blocks. This could cause some tests to have a memory leak, thus
the "unity_task" startup delay has increased.
FreeRTOS(IDF): Restore vanilla task selection algorithm if building for single core with optimized selection is disabled
See merge request espressif/esp-idf!21001
Since core affinity is supported in task stats by default in Amazon
FreeRTOS SMP, the Kconfig option
CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID is now made only available for
IDF-FreeRTOS.
This commit restores the vanilla behavior for taskSELECT_HIGHEST_PRIORITY_TASK
when configNUM_CORES == 1 && configUSE_PORT_OPTIMISED_TASK_SELECTION == 0. This
results in the SMP selection algorithm (taskSelectHighestPriorityTaskSMP) to
only be run when configNUM_CORES > 1.
This commit adds preprocessing time checks to ensure that
- configNUM_CORES is defined to 1 or 2
- Incompatible configurations are not set depending on configNUM_CORES
Macros that need to reteurn a value should use GCC statement expression macro
syntax. This commit fixes the portTRY_ENTER_CRITICAL() in the RISC-V port of
SMP FreeRTOS to be a statement expression macro.
Due to SMP, critical sections have been added to xTaskIncrementTick() and
vTaskSwitchContext() (to take the xKernelLock). However, this is technically
not necessary when building for single-core as FreeRTOS expect these funcitons
to be called with interrupts already disabled.
This commit makes the critical secitons in those functions depend on
"configNUM_CORES > 1", and ensures that interrupts are disabled when calling
those functions. This effectively restores the vanilla behavior for these
functions when building for single-core.
In IDF FreeRTOS, when building for SMP, there are numerous functions
which require different critical sections when compared to single-core. This
commit encapsulates those difference into a common set of macros whose
behavior depends on "configNUM_CORES > 1". As such...
- Vanilla behavior has been restored for some functions when building for
single core (i.e., used to call taskENTER_CRITICAL, now disables interrupts
mactching vanilla behavior).
- Reduces number of "#ifdef (configNUM_CORES > 1)" in functions
- Any SMP only critical sections are now wrapped by
"#ifdef (configNUM_CORES > 1)" and properly documented via comments.
The portDISABLE_INTERRUPTS() macro on Xtensa should return only the interrupt
mask/level before the interrupts were disabled. Previously, the entire contents
of PS register were returned (i.e., direct return from RSIL instruction without
any bit masking or shifting).
This commit fixes the portDISABLE_INTERRUPTS() macro to return the INTLEVEL
bitfield of the PS register.
This commit updates how configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS is defined
by default it to 0 if not defined elsewhere. Dependent code now check for
"configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1" instead.
This commit synchronize the cosmetic differences of IDF FreeRTOS to upstream
Vanilla v10.4.3. Comsetic differences include:
- Out of date doxygen API descriptions
- Misnamed parameters
- Missing examples
- Fixed/added missing @cond/@code directives
- Extra/missing comments/lines
- Code formatting (uncrustify)
Other changes:
- Some ESP_PLATFORM directives were also removed
- xTaskIncrementTickOtherCores() now depends on "configNUM_CORES > 1"
- Updated some multi-core dummy variable names in FreeRTOS.h
This commit removes the updates the usage of queue locks in IDF FreeRTOS
Queue locks are present in Vanilla FreeRTOS to ensure that queue functions
behave deterministicly in critical sections (i.e., no walking linked lists
while interrupts are disabled). However, currently in IDF FreeRTOS...
- When configNUM_CORES > 1, IDF FreeRTOS drops the determinism requirement.
Thus, queue functions could be simplified if queue locks were not used at all
(and have a queue function do everything inside the same critical section).
- When configNUM_CORES == 1, the current queue implementation in IDF FreeRTOS
does not meet the determinism requirements, as critical sections are used
(instead of scheduler suspension) when locking/unlocking the queues.
There, this commit updates multiple queue functions so that
- When configNUM_CORES > 1
- Queue locks are no longer used. All actions are done within the same
critical section.
- Affected queue functions now need 40% less CPU clock cycles when blocking
- When configNUM_CORES = 1
- Queue locks are still used.
- Vanilla behavior of suspending the scheduler is restored when locking
the queue. Thus queue fucntions are now deterministic and have the same
behavior as Vanilla FreeRTOS.
- Affected queue functions now takes 36% more CPU clock cycles when
blocking (due to the scheduler suspension/resumption).
The following changes have been made in this commit:
1. configMINIMAL_STACK_SIZE is now defined as CONFIG_FREERTOS_IDLE_TASK_STACKSIZE.
2. Removed configIDLE_TASK_STACK_SIZE config as it was redundant.
3. Updates the order of allocating the TCB and stack memory to avoid the
stack memory overriding the TCB memory when the stack grows downwards.
4. CONFIG_FREERTOS_IDLE_TASK_STACKSIZE is now incorporated into the
FreeRTOSConfig_smp.h to configure the IDLE0 stack size.
This commit fixes flakey task delay tests when running on IDF FreeRTOS. IN IDF
FreeRTOS, core 1's tick interrupts could be up to (< 1 tick) out of phase from
core 0's tick interrupt, thus the measured delay time on core 1 could last 1
tick longer. This commit makes the test detla 2 ticks for IDF FreeRTOS.
This commit adds a copy of upstream vanilla FreeRTOS uncrustify.cfg files from
the following upstream commit:
89e4823a49
Note: "pp_indent_brace" is commented out as that was enabled after v10.4.3
Also also added a note in the ESP-IDF style guide aobut formatting FreeRTOS
source code using Uncrustify.
This commit refactors the way stream buffers initialize their spinlock.
- "prvInitialiseNewStreamBuffer()" now initializes the stream buffer fields
manually (instead of using memset()) to avoid resetting the spin lock
- Stream buffer creation functions now manually initialize the spinlock after
the other fields are initialized using "prvInitialiseNewStreamBuffer()"
Also added comments to event group spinlock initializtion.
The llvm asm pasrser doesn't support some gnu asm extensions,
like using "&" with macro arguments. So, replace such code with
code which could be compiled by llvm.
An explicit check of the mutex owner during a mutex release operation is
not necessary for FreeRTOS SMP as this is checked by default. Hence, the
corresponding Kconfig option is removed.
This commit fixes/ignores flakey freertos unit tests after migrating them to
the test app:
- Added vTaskDelay() before teardown to prevent memory leaks
- Adjusted the "main" task's priority so that scheudling tasks would work
- pytest now only runs tests that are not ignored
- Reset tests are temporarily ignored. Will be enabled to dedicate reset tests.
- Some flakey tests are fixed by adjusting delays and stack sizes.
This commit adds the sdkconfig files for the FreeRTOS test app. These
configurations were dervied from the various legacy unit test app's
config files that included the FreeRTOS component.
This commit tries to keep a 1 to 1 config parity with the legacy test app.
Meaning, if FreeRTOS test were run on a particular target with a particular
config, that config will be represented in one of the test app's
sdkconfig.ci.XXX files.
However, the following configurations were removed for FreeRTOS tests:
- The "freertos_flash" option was removed due to redudancy (already tested in
freertos_options)
Some tests were placed in the incorrect test groups (i.e., kernel, port,
performance etc). This commit fixes those placements.
The following redundant tests were also removed:
- "test_panic.c" as behavior is already covered in esp_system tests
This commit fixes a bug where if an unpinned task is interrupted by a level 1
ISR that users the FPU, the FPU usage will cause the interrupted task to
become pinned to the current core.
Note: This bug was already fixed in SMP FreeRTOS in commit
d69361779e. This commit simply backports the
fix to IDF FreeRTOS.
This commit refactors the existing FPU unit tests as follows
- Rename them from coproc to FPU
- Reorganize test placement
- Make existing tests work on both IDF and SMP FreeRTOS
- Update test documentation
- Remove old "test_float_in_isr.c"
This commit refactors the pxPortInitialiseStack() function of the riscv
FreeRTOS ports (both IDF and SMP FreeRTOS).
- Each stack area is now separated into their own functions
- Each function will individually
- Push the stack pointer to allocate the stack area
- Initiaze the allocated stack area
- Each stack area's size and usage is now clearly documented in code
This commit refactors the pxPortInitialiseStack() function of the xtensa
FreeRTOS ports (both IDF and SMP FreeRTOS).
- Each stack area is now separated into their own functions
- Each function will individually
- Push the stack pointer to allocate the stack area
- Initiaze the allocated stack area
- Each stack area's size and usage is now clearly documented in code
* Added port layer from the FreeRTOS POSIX port, added
additional port code for ESP-IDF.
* Created another hello world example using that POSIX
port in tools/test_apps.
* Removed old linux app
This commit adds a priority scheduling unit test to test that the scheduler
always schedules the highest priority ready state task. Single core and SMP
variants of the test are both added.
This commit adds a README.md containing guidelines on how to refactor the
FreeRTOS unit tests for upstreaming. A portTestMacro.h header was also added
which contains port implementation specific macros used by the test cases.
This commit places some functions in port.c and port_common.c into flash by
default. These functions are mostly called once during startup, thus shouldn't
affect applications much when placed into flash instead of the default IRAM.
This commit synchronizes multiple functions in tasks.c with upstream v10.4.3
that contain minor differences.
The following functions have had their parameter names or code formatting
updated:
- xTaskCreateStaticPinnedToCore()
- xTaskCreatePinnedToCore()
- prvInitialiseNewTask()
- prvTaskIsTaskSuspended()
- vTaskStartScheduler()
- xTaskResumeAll()
- xTaskCheckForTimeOut()
- uxTaskResetEventItemValue()
The following functions have had their missing "xAlreadyYielded" restored
- xTaskDelayUntil()
- vTaskDelay()
The following functions have had their critical section/interrupt disdable
usage update
- vTaskSuspendAll()
- xTaskGetTickCountFromISR()
- xTaskGetApplicationTaskTagFromISR()
This commit synchronizes multiple functions that contain major differences with
upstream v10.4.3. Multi-core modifications are then reapplied to the function.
Vanilla code uses "pxTCB == pxCurrentTCB" to check whether a task is currently
running. This commit adds the following macros instead.
- taskIS_CURRENTLY_RUNNING()
- taskIS_CURRENTLY_RUNNING_ON_CORE()
The following functions have been updated to use those macros instead.
- eTaskGetState()
- vTaskPrioritySet()
- vTaskResume()
The following functions have been synchronized with upstream v10.4.3.
Multi-core modifications are then reapplied.
- vTaskSuspend()
- vTaskDelete()
- prvGetExpectedIdleTime()
This commit synchronizes multiple functions in queue.c with upstream v10.4.3.
Multi-core modifications are then reapplied to these functions. The following
functions were modified:
prvNotifyQueueSetContainer()
xQueueGenericCreateStatic()
xQueueGenericCreate()
xQueueGetMutexHolder()
xQueueCreateCountingSemaphoreStatic()
xQueueCreateCountingSemaphore()
xQueueGenericSend()
xQueueGenericSendFromISR()
xQueueReceiveFromISR()
uxQueueMessagesWaiting()
prvUnlockQueue()
prvIsQueueFull()
xQueueAddToSet()
xQueueRemoveFromSet()
prvNotifyQueueSetContainer()
Note: The SEGGER_SYSVIEW traceQUEUE_SEND() macro was updated as the
xCopyPosition argument is no longer available in scenarios where the
macro is called.