From 733021ebf8254d4598792e5ac9a09637e6506f98 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Tue, 21 Jun 2022 17:58:22 +0800 Subject: [PATCH] freertos: Move some SMP FreeRTOS functions to flash The CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH allows some FreeRTOS functions to be placed into flash, thus saving some IRAM. However, this feature was previously not supported for SMP FreeRTOS. This commit adds CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH support for SMP FreeRTOS. There are now separate linker fragment files for IDF FreeRTOS and SMP FreeRTOS, named "linker.lf" and "linker_smp.lf" respectively. --- components/freertos/CMakeLists.txt | 4 +- components/freertos/linker.lf | 251 ++++++++++++++--------------- components/freertos/linker_smp.lf | 176 ++++++++++++++++++++ 3 files changed, 303 insertions(+), 128 deletions(-) create mode 100644 components/freertos/linker_smp.lf diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index 92f9efd385..b62e112596 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -7,6 +7,7 @@ endif() idf_build_get_property(target IDF_TARGET) if(CONFIG_FREERTOS_SMP) + set(ldfragments linker_smp.lf) if(CONFIG_IDF_TARGET_ARCH_XTENSA) set(srcs "FreeRTOS-Kernel-SMP/portable/xtensa/port.c" @@ -68,6 +69,7 @@ if(CONFIG_FREERTOS_SMP) endif() else() + set(ldfragments linker.lf) if(CONFIG_IDF_TARGET_ARCH_XTENSA) set(srcs "FreeRTOS-Kernel/portable/xtensa/port.c" @@ -134,7 +136,7 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS ${include_dirs} PRIV_INCLUDE_DIRS ${private_include_dirs} - LDFRAGMENTS linker.lf + LDFRAGMENTS "${ldfragments}" PRIV_REQUIRES soc esp_pm) idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR) diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index f10057ef34..df6cdefd96 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -1,130 +1,127 @@ +# Linker fragment file for IDF FreeRTOS (i.e., CONFIG_FREERTOS_SMP=n) [mapping:freertos] archive: libfreertos.a entries: - if FREERTOS_SMP = y: - # Currently no linker conditions for FreeRTOS SMP - * (noflash_text) - else: - * (noflash_text) - if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: - task_snapshot (default) - if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: - port: pxPortInitialiseStack (default) - port: xPortStartScheduler (default) - if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y : - port: vPortReleaseTaskMPUSettings (default) - tasks: xTaskCreateRestricted (default) - port: vPortStoreTaskMPUSettings (default) - tasks: vTaskAllocateMPURegions (default) - tasks: prvTaskCheckFreeStackSpace (default) - tasks: prvInitialiseNewTask (default) - tasks: prvInitialiseTaskLists (default) - tasks: prvDeleteTCB (default) - tasks: prvCheckTasksWaitingTermination (default) - tasks: prvIdleTask (default) - tasks: prvAddNewTaskToReadyList (default) - tasks: xTaskCreatePinnedToCore (default) - tasks: xTaskCreateStaticPinnedToCore (default) - tasks: vTaskResume (default) - tasks: vTaskStartScheduler (default) - tasks: vTaskSuspendAll (default) - tasks: uxTaskGetNumberOfTasks (default) - tasks: xTaskGetIdleTaskHandle (default) - tasks: vTaskRemoveFromUnorderedEventList (default) - tasks: uxTaskPriorityGet (default) - tasks: vTaskPrioritySet (default) - tasks: vTaskSetThreadLocalStoragePointerAndDelCallback (default) - tasks: pvTaskGetThreadLocalStoragePointer (default) - tasks: xTaskGetCurrentTaskHandleForCPU (default) - tasks: vTaskDelete (default) - tasks: vTaskDelayUntil (default) - tasks: xTaskDelayUntil (default) - tasks: vTaskDelay (default) - tasks: vTaskSuspend (default) - tasks: xTaskResumeAll (default) - tasks: uxTaskResetEventItemValue (default) - tasks: ulTaskNotifyTake (default) - tasks: ulTaskGenericNotifyTake (default) - tasks: xTaskNotifyWait (default) - tasks: xTaskGenericNotifyWait (default) - tasks: xTaskGenericNotify (default) - tasks: eTaskGetState (default) - tasks: pxTaskGetStackStart (default) - tasks: uxTaskGetStackHighWaterMark (default) - tasks: vTaskEndScheduler (default) - tasks: vTaskMissedYield (default) - tasks: vTaskSetThreadLocalStoragePointer (default) - tasks: xTaskGetAffinity (default) - tasks: xTaskGetIdleTaskHandleForCPU (default) - if FREERTOS_USE_TRACE_FACILITY = y: - tasks: uxTaskGetSystemState (default) - tasks: uxTaskGetTaskNumber (default) - tasks: vTaskSetTaskNumber (default) - if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: - tasks: vTaskList (default) - if FREERTOS_GENERATE_RUN_TIME_STATS = y: - tasks: vTaskGetRunTimeStats (default) - timers: prvInsertTimerInActiveList (default) - timers: prvCheckForValidListAndQueue (default) - timers: prvInitialiseNewTimer (default) - timers: prvTimerTask (default) - timers: prvSwitchTimerLists (default) - timers: prvSampleTimeNow (default) - timers: prvProcessExpiredTimer (default) - timers: prvProcessTimerOrBlockTask (default) - timers: prvProcessReceivedCommands (default) - timers: xTimerCreateTimerTask (default) - timers: xTimerCreate (default) - timers: xTimerCreateStatic (default) - timers: xTimerGenericCommand (default) - timers: xTimerGetPeriod (default) - timers: xTimerGetExpiryTime (default) - timers: xTimerIsTimerActive (default) - timers: pvTimerGetTimerID (default) - timers: vTimerSetTimerID (default) - timers: prvGetNextExpireTime (default) - if FREERTOS_USE_TRACE_FACILITY = y: - timers: uxTimerGetTimerNumber (default) - timers: vTimerSetTimerNumber (default) - event_groups: prvTestWaitCondition (default) - event_groups: xEventGroupCreate (default) - event_groups: xEventGroupCreateStatic (default) - event_groups: xEventGroupWaitBits (default) - event_groups: xEventGroupClearBits (default) - event_groups: xEventGroupSetBits (default) - event_groups: xEventGroupSync (default) - event_groups: vEventGroupDelete (default) - queue: prvIsQueueFull (default) - queue: prvInitialiseNewQueue (default) - queue: prvInitialiseMutex (default) - queue: uxQueueSpacesAvailable (default) - queue: xQueueGenericReset (default) - queue: xQueueGenericCreate (default) - queue: xQueueGetMutexHolder (default) - queue: xQueueCreateCountingSemaphore (default) - queue: xQueueGenericSend (default) - queue: xQueueCreateMutex (default) - queue: xQueueGiveMutexRecursive (default) - queue: xQueueTakeMutexRecursive (default) - queue: uxQueueMessagesWaiting (default) - queue: vQueueDelete (default) - queue: vQueueWaitForMessageRestricted (default) - queue: xQueueCreateSet (default) - queue: xQueueAddToSet (default) - queue: xQueueRemoveFromSet (default) - queue: xQueueSelectFromSet (default) - queue: xQueueGenericCreateStatic (default) - queue: xQueueCreateMutexStatic (default) - queue: xQueueCreateCountingSemaphoreStatic (default) - if FREERTOS_QUEUE_REGISTRY_SIZE > 0: - queue: pcQueueGetName (default) - queue: vQueueAddToRegistry (default) - queue: vQueueUnregisterQueue (default) - if FREERTOS_USE_TRACE_FACILITY = y: - queue: uxQueueGetQueueNumber (default) - queue: vQueueSetQueueNumber (default) - queue: ucQueueGetQueueType (default) - port_common:main_task (default) - port:esp_startup_start_app (default) - if ESP_SYSTEM_SINGLE_CORE_MODE = n: - port:esp_startup_start_app_other_cores (default) + * (noflash_text) + if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: + task_snapshot (default) + if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: + port: pxPortInitialiseStack (default) + port: xPortStartScheduler (default) + if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y : + port: vPortReleaseTaskMPUSettings (default) + tasks: xTaskCreateRestricted (default) + port: vPortStoreTaskMPUSettings (default) + tasks: vTaskAllocateMPURegions (default) + tasks: prvTaskCheckFreeStackSpace (default) + tasks: prvInitialiseNewTask (default) + tasks: prvInitialiseTaskLists (default) + tasks: prvDeleteTCB (default) + tasks: prvCheckTasksWaitingTermination (default) + tasks: prvIdleTask (default) + tasks: prvAddNewTaskToReadyList (default) + tasks: xTaskCreatePinnedToCore (default) + tasks: xTaskCreateStaticPinnedToCore (default) + tasks: vTaskResume (default) + tasks: vTaskStartScheduler (default) + tasks: vTaskSuspendAll (default) + tasks: uxTaskGetNumberOfTasks (default) + tasks: xTaskGetIdleTaskHandle (default) + tasks: vTaskRemoveFromUnorderedEventList (default) + tasks: uxTaskPriorityGet (default) + tasks: vTaskPrioritySet (default) + tasks: vTaskSetThreadLocalStoragePointerAndDelCallback (default) + tasks: pvTaskGetThreadLocalStoragePointer (default) + tasks: xTaskGetCurrentTaskHandleForCPU (default) + tasks: vTaskDelete (default) + tasks: vTaskDelayUntil (default) + tasks: xTaskDelayUntil (default) + tasks: vTaskDelay (default) + tasks: vTaskSuspend (default) + tasks: xTaskResumeAll (default) + tasks: uxTaskResetEventItemValue (default) + tasks: ulTaskNotifyTake (default) + tasks: ulTaskGenericNotifyTake (default) + tasks: xTaskNotifyWait (default) + tasks: xTaskGenericNotifyWait (default) + tasks: xTaskGenericNotify (default) + tasks: eTaskGetState (default) + tasks: pxTaskGetStackStart (default) + tasks: uxTaskGetStackHighWaterMark (default) + tasks: vTaskEndScheduler (default) + tasks: vTaskMissedYield (default) + tasks: vTaskSetThreadLocalStoragePointer (default) + tasks: xTaskGetAffinity (default) + tasks: xTaskGetIdleTaskHandleForCPU (default) + if FREERTOS_USE_TRACE_FACILITY = y: + tasks: uxTaskGetSystemState (default) + tasks: uxTaskGetTaskNumber (default) + tasks: vTaskSetTaskNumber (default) + if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: + tasks: vTaskList (default) + if FREERTOS_GENERATE_RUN_TIME_STATS = y: + tasks: vTaskGetRunTimeStats (default) + timers: prvInsertTimerInActiveList (default) + timers: prvCheckForValidListAndQueue (default) + timers: prvInitialiseNewTimer (default) + timers: prvTimerTask (default) + timers: prvSwitchTimerLists (default) + timers: prvSampleTimeNow (default) + timers: prvProcessExpiredTimer (default) + timers: prvProcessTimerOrBlockTask (default) + timers: prvProcessReceivedCommands (default) + timers: xTimerCreateTimerTask (default) + timers: xTimerCreate (default) + timers: xTimerCreateStatic (default) + timers: xTimerGenericCommand (default) + timers: xTimerGetPeriod (default) + timers: xTimerGetExpiryTime (default) + timers: xTimerIsTimerActive (default) + timers: pvTimerGetTimerID (default) + timers: vTimerSetTimerID (default) + timers: prvGetNextExpireTime (default) + if FREERTOS_USE_TRACE_FACILITY = y: + timers: uxTimerGetTimerNumber (default) + timers: vTimerSetTimerNumber (default) + event_groups: prvTestWaitCondition (default) + event_groups: xEventGroupCreate (default) + event_groups: xEventGroupCreateStatic (default) + event_groups: xEventGroupWaitBits (default) + event_groups: xEventGroupClearBits (default) + event_groups: xEventGroupSetBits (default) + event_groups: xEventGroupSync (default) + event_groups: vEventGroupDelete (default) + queue: prvIsQueueFull (default) + queue: prvInitialiseNewQueue (default) + queue: prvInitialiseMutex (default) + queue: uxQueueSpacesAvailable (default) + queue: xQueueGenericReset (default) + queue: xQueueGenericCreate (default) + queue: xQueueGetMutexHolder (default) + queue: xQueueCreateCountingSemaphore (default) + queue: xQueueGenericSend (default) + queue: xQueueCreateMutex (default) + queue: xQueueGiveMutexRecursive (default) + queue: xQueueTakeMutexRecursive (default) + queue: uxQueueMessagesWaiting (default) + queue: vQueueDelete (default) + queue: vQueueWaitForMessageRestricted (default) + queue: xQueueCreateSet (default) + queue: xQueueAddToSet (default) + queue: xQueueRemoveFromSet (default) + queue: xQueueSelectFromSet (default) + queue: xQueueGenericCreateStatic (default) + queue: xQueueCreateMutexStatic (default) + queue: xQueueCreateCountingSemaphoreStatic (default) + if FREERTOS_QUEUE_REGISTRY_SIZE > 0: + queue: pcQueueGetName (default) + queue: vQueueAddToRegistry (default) + queue: vQueueUnregisterQueue (default) + if FREERTOS_USE_TRACE_FACILITY = y: + queue: uxQueueGetQueueNumber (default) + queue: vQueueSetQueueNumber (default) + queue: ucQueueGetQueueType (default) + port_common:main_task (default) + port: esp_startup_start_app (default) + if ESP_SYSTEM_SINGLE_CORE_MODE = n: + port: esp_startup_start_app_other_cores (default) diff --git a/components/freertos/linker_smp.lf b/components/freertos/linker_smp.lf new file mode 100644 index 0000000000..ff9ba77f55 --- /dev/null +++ b/components/freertos/linker_smp.lf @@ -0,0 +1,176 @@ +# Linker fragment file for SMP FreeRTOS (i.e., CONFIG_FREERTOS_SMP=y) +[mapping:freertos] +archive: libfreertos.a +entries: + # Default all FreeRTOS functions to IRAM + * (noflash_text) + # Todo: Check if flash placements are missing or can be further optimized IDF-5259 + if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: + # event_groups.c + event_groups: xEventGroupCreateStatic (default) + event_groups: xEventGroupCreate (default) + event_groups: xEventGroupSync (default) + event_groups: xEventGroupWaitBits (default) + event_groups: xEventGroupClearBits (default) + event_groups: xEventGroupSetBits (default) + event_groups: vEventGroupDelete (default) + event_groups: vEventGroupSetBitsCallback (default) + event_groups: vEventGroupClearBitsCallback (default) + event_groups: prvTestWaitCondition (default) + if FREERTOS_USE_TRACE_FACILITY = y: + event_groups: uxEventGroupGetNumber (default) + event_groups: vEventGroupSetNumber (default) + # list.c + # queue.c + queue: xQueueGenericReset (default) + queue: xQueueGenericCreateStatic (default) + queue: xQueueGenericCreate (default) + queue: prvInitialiseNewQueue (default) + queue: prvInitialiseMutex (default) + queue: xQueueCreateMutex (default) + queue: xQueueCreateMutexStatic (default) + queue: xQueueGetMutexHolder (default) + queue: xQueueGiveMutexRecursive (default) + queue: xQueueTakeMutexRecursive (default) + queue: xQueueCreateCountingSemaphoreStatic (default) + queue: xQueueCreateCountingSemaphore (default) + queue: xQueueGenericSend (default) + queue: xQueueReceive (default) + queue: xQueueSemaphoreTake (default) + queue: xQueuePeek (default) + queue: uxQueueMessagesWaiting (default) + queue: uxQueueSpacesAvailable (default) + queue: vQueueDelete (default) + if FREERTOS_USE_TRACE_FACILITY = y: + queue: uxQueueGetQueueNumber (default) + queue: vQueueSetQueueNumber (default) + queue: ucQueueGetQueueType (default) + queue: prvGetDisinheritPriorityAfterTimeout (default) + queue: prvUnlockQueue (default) + queue: prvIsQueueEmpty (default) + queue: prvIsQueueFull (default) + if FREERTOS_QUEUE_REGISTRY_SIZE > 0: + queue: vQueueAddToRegistry (default) + queue: pcQueueGetName (default) + queue: vQueueUnregisterQueue (default) + queue: vQueueWaitForMessageRestricted (default) + queue: xQueueCreateSet (default) + queue: xQueueAddToSet (default) + queue: xQueueRemoveFromSet (default) + queue: xQueueSelectFromSet (default) + # stream_buffer.c + # tasks.c: Vanilla + tasks: xTaskCreateStatic (default) + tasks: xTaskCreate (default) + if FREERTOS_UNICORE = n: + tasks: xTaskCreateStaticAffinitySet (default) + tasks: xTaskCreateAffinitySet (default) + tasks: vTaskCoreAffinitySet (default) + tasks: vTaskCoreAffinityGet (default) + tasks: prvMinimalIdleTask (default) + tasks: prvInitialiseNewTask (default) + tasks: prvAddNewTaskToReadyList (default) + tasks: vTaskDelete (default) + tasks: xTaskDelayUntil (default) + tasks: vTaskDelay (default) + tasks: eTaskGetState (default) + tasks: uxTaskPriorityGet (default) + tasks: vTaskPrioritySet (default) + tasks: vTaskSuspend (default) + tasks: vTaskResume (default) + tasks: prvCreateIdleTasks (default) + tasks: vTaskStartScheduler (default) + tasks: vTaskEndScheduler (default) + tasks: vTaskSuspendAll (default) + #Todo: prvGetExpectedIdleTime + tasks: xTaskResumeAll (default) + tasks: uxTaskGetNumberOfTasks (default) + tasks: pcTaskGetName (default) + tasks: prvSearchForNameWithinSingleList (default) + tasks: xTaskGetHandle (default) + if FREERTOS_USE_TRACE_FACILITY = y: + tasks: uxTaskGetSystemState (default) + tasks: uxTaskGetTaskNumber (default) + tasks: vTaskSetTaskNumber (default) + tasks: vTaskGetInfo (default) + tasks: prvListTasksWithinSingleList (default) + tasks: prvTaskCheckFreeStackSpace (default) + tasks: xTaskGetIdleTaskHandle (default) + tasks: xTaskAbortDelay (default) + tasks: vTaskPlaceOnEventList (default) + tasks: vTaskRemoveFromUnorderedEventList (default) + tasks: vTaskPlaceOnEventListRestricted (default) + tasks: vTaskSetTimeOutState (default) + tasks: vTaskInternalSetTimeOutState (default) + tasks: xTaskCheckForTimeOut (default) + tasks: vTaskMissedYield (default) + tasks: prvIdleTask (default) + if FREERTOS_THREAD_LOCAL_STORAGE_POINTERS > 0: + tasks: vTaskSetThreadLocalStoragePointer (default) + tasks: pvTaskGetThreadLocalStoragePointer (default) + tasks: prvInitialiseTaskLists (default) + tasks: prvCheckTasksWaitingTermination (default) + tasks: uxTaskGetStackHighWaterMark (default) + tasks: prvDeleteTCB (default) + if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: + tasks: prvWriteNameToBuffer (default) + tasks: vTaskList (default) + if FREERTOS_GENERATE_RUN_TIME_STATS = y: + tasks: vTaskGetRunTimeStats (default) + tasks: ulTaskGetIdleRunTimeCounter (default) + tasks: uxTaskResetEventItemValue (default) + tasks: pvTaskIncrementMutexHeldCount (default) + tasks: ulTaskGenericNotifyTake (default) + tasks: xTaskGenericNotifyWait (default) + tasks: xTaskGenericNotify (default) + tasks: xTaskGenericNotifyStateClear (default) + tasks: ulTaskGenericNotifyValueClear (default) + # tasks.c: Additions + if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: + tasks: non_ready_task_lists (default) + tasks: pxGetNextTaskList (default) + tasks: pxTaskGetNext (default) + tasks: vTaskGetSnapshot (default) + tasks: uxTaskGetSnapshotAll (default) + tasks: xTaskCreatePinnedToCore (default) + tasks: xTaskCreateStaticPinnedToCore (default) + tasks: xTaskGetCurrentTaskHandleForCPU (default) + tasks: xTaskGetIdleTaskHandleForCPU (default) + tasks: xTaskGetAffinity (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + tasks: vTaskSetThreadLocalStoragePointerAndDelCallback (default) + # port + port: pxPortInitialiseStack (default) + port: xPortStartScheduler (default) + port: main_task (default) + port: esp_startup_start_app (default) + if ESP_SYSTEM_SINGLE_CORE_MODE = n: + port:esp_startup_start_app_other_cores (default) + # timers.c + timers: xTimerCreateTimerTask (default) + timers: xTimerCreate (default) + timers: xTimerCreateStatic (default) + timers: prvInitialiseNewTimer (default) + timers: xTimerGenericCommandFromTask (default) + timers: xTimerGetTimerDaemonTaskHandle (default) + timers: xTimerGetPeriod (default) + timers: vTimerSetReloadMode (default) + timers: uxTimerGetReloadMode (default) + timers: xTimerGetExpiryTime (default) + timers: pcTimerGetName (default) + timers: prvProcessExpiredTimer (default) + timers: prvTimerTask (default) + timers: prvProcessTimerOrBlockTask (default) + timers: prvGetNextExpireTime (default) + timers: prvSampleTimeNow (default) + timers: prvInsertTimerInActiveList (default) + timers: prvProcessReceivedCommands (default) + timers: prvSwitchTimerLists (default) + timers: prvCheckForValidListAndQueue (default) + timers: xTimerIsTimerActive (default) + timers: pvTimerGetTimerID (default) + timers: vTimerSetTimerID (default) + timers: xTimerPendFunctionCall (default) + if FREERTOS_USE_TRACE_FACILITY = y: + timers: uxTimerGetTimerNumber (default) + timers: vTimerSetTimerNumber (default)