MPU port generates huge executable


I started using the MPU port recently and having the following problem.
I’m using -ffunction-sections compilation flag and --gc-sections linker flag to reduce the size of the executable.
The problem is that all the kernel functions are allocated to attribute( ( section( “privileged_functions” ) ) ), as a result the -ffunction-sections doesn’t have any effect and all the functions are placed in privileged_functions sections instead of e.g. privileged_functions.xTaskCreate .
As a result --gc-sections doesn’t remove the unused functions and I’m getting a huge executable with all the FreeRTOS APIs included.

Did some searching but didn’t find any references of this issue.
Any advice would be appriciated.

can you show us your linker command file?


__STACK_SIZE = 0x400;

FLASH (rx) : ORIGIN = 0x0000, LENGTH = 44K
RAM (rw) : ORIGIN = 0xB000, LENGTH = 20K

privileged_functions_region_size = 30K;
privileged_data_region_size = 5K;

FLASH_segment_start = ORIGIN( FLASH );
FLASH_segment_end = FLASH_segment_start + LENGTH( FLASH );

SRAM_segment_start = ORIGIN( RAM );
SRAM_segment_end = SRAM_segment_start + LENGTH( RAM );

privileged_functions_start = FLASH_segment_start;
privileged_functions_end = FLASH_segment_start + privileged_functions_region_size;

privileged_data_start = ORIGIN( RAM);
privileged_data_end = ORIGIN( RAM) + privileged_data_region_size;

.privileged_functions :
. = ALIGN(4);
. = ALIGN(4);
. = ALIGN(4);
En placed after the region reserved for
* privileged kernel code. /
Note that dot (.) actually refers to the byte offset from the start of
* the current section (.privileged_functionsure that non-privileged code iss in this case). As a result,
* setting dot (.) to a value sets the size of the section. */

.text :
. = ALIGN(4);
syscalls_flash_start = .;
syscalls_flash_end = .;
. = ALIGN(4);

*(.text*)          /* .text* sections (code) */
*(.glue_7)         /* glue arm to thumb code */
*(.glue_7t)        /* glue thumb to arm code */




.ARM.extab :
(.ARM.extab .gnu.linkonce.armextab.*)

__exidx_start = .;
.ARM.exidx :
(.ARM.exidx .gnu.linkonce.armexidx.*)
__exidx_end = .;

.copy.table :
. = ALIGN(4);
copy_table_start = .;

LONG (__etext)
LONG (__data_start__)
LONG ((__data_end__ - __data_start__) / 4)

/* Add each additional data section here */

LONG (__etext2)
LONG (data2_start)
LONG ((data2_end - data2_start) / 4)
copy_table_end = .;

.zero.table :
. = ALIGN(4);
zero_table_start = .;
/* Add each additional bss section here */
LONG (bss_start)
LONG ((bss_end - bss_start) / 4)

LONG (bss2_start)
LONG ((bss2_end - bss2_start) / 4)
zero_table_end = .;


  • Location counter can end up 2byte aligned with narrow Thumb code but
  • __etext is assumed by startup code to be the LMA of a section in RAM
  • which must be 4byte aligned
    __etext = ALIGN (4);

.privileged_data :
. = ALIGN(4);
data_start = .;
. = ALIGN(4);
Ensure that non-privileged data is placed after the region reserved for
* privileged kernel data. /
Note that dot (.) actually refers to the byte offset from the start of
* the current section (.privileged_data in this case). As a result, setting
* dot (.) to a value sets the size of the section. */
. = privileged_data_region_size;

.data :
. = ALIGN(4);

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
PROVIDE_HIDDEN (__preinit_array_end = .);

. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
PROVIDE_HIDDEN (__init_array_end = .);

. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
PROVIDE_HIDDEN (__fini_array_end = .);

. = ALIGN(4);
/* All data end */
__data_end__ = .;



  • Secondary data section, optional
  • Remember to add each additional data section
  • to the .copy.table above to asure proper
  • initialization during startup.

    __etext2 = ALIGN (4);

.data2 : AT (__etext2)
. = ALIGN(4);
data2_start = .;
. = ALIGN(4);
data2_end = .;

} > RAM2

.bss :
. = ALIGN(4);
bss_start = .;
. = ALIGN(4);
bss_end = .;
} > RAM AT > RAM


  • Secondary bss section, optional
  • Remember to add each additional bss section
  • to the .zero.table above to asure proper
  • initialization during startup.

    .bss2 :
    . = ALIGN(4);
    bss2_start = .;
    . = ALIGN(4);
    bss2_end = .;
    } > RAM2 AT > RAM2

.heap (COPY) :
. = ALIGN(8);
end = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
} > RAM

. = ALIGN(8);
__StackLimit = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
} > RAM
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, “Region RAM overflowed with stack”)

can we also see your map file? I am not quite sure if I understand your problem correctly. The FreeRTOS API functions MUST be placed somewhere if flash if they are being used by your application code, so what exactly would you like the linker to remove? What (redundant?) sections eat up your flash?

0x00000400 __STACK_SIZE = 0x400
0x00001400 __HEAP_SIZE = 0x1400
0x00007800 privileged_functions_region_size = 0x7800
0x00001400 privileged_data_region_size = 0x1400
0x00000000 FLASH_segment_start = ORIGIN (FLASH)
0x0000b000 FLASH_segment_end = (FLASH_segment_start + LENGTH (FLASH))
0x0000b000 SRAM_segment_start = ORIGIN (RAM)
0x00010000 SRAM_segment_end = (SRAM_segment_start + LENGTH (RAM))
0x00000000 privileged_functions_start = FLASH_segment_start
0x00007800 privileged_functions_end = (FLASH_segment_start + privileged_functions_region_size)
0x0000b000 privileged_data_start = ORIGIN (RAM)
0x0000c400 privileged_data_end = (ORIGIN (RAM) + privileged_data_region_size)

0x00000000 0x52c4
0x00000000 . = ALIGN (0x4)
.vectors 0x00000000 0x3c0 build/drivers/cmsis/device/armcm4/source/startup_ARMCM4.o
0x00000000 __Vectors
0x000003c0 . = ALIGN (0x4)
0x000003c0 0xeb8 build/middlware/freertos/portable/Common/mpu_wrappers_v2.o
0x000004f8 MPU_xTaskCreate
0x00000562 MPU_vTaskPrioritySet
0x00000584 MPU_xTaskCreateRestricted
0x000005cc MPU_uxTaskPriorityGetFromISR
0x000005ec MPU_xTaskResumeFromISR
0x00000608 MPU_xTaskGenericNotifyFromISR
0x0000063c MPU_vTaskGenericNotifyGiveFromISR
0x0000065e MPU_vQueueDelete
0x0000067e MPU_xQueueCreateMutex
0x000006ae MPU_xQueueCreateCountingSemaphore
0x000006e2 MPU_xQueueGenericCreate
0x0000071a MPU_xQueueGenericReset
0x0000073a MPU_xQueueGenericSendFromISR
0x00000762 MPU_xQueueGiveFromISR
0x00000782 MPU_xQueuePeekFromISR
0x000007a2 MPU_xQueueReceiveFromISR
0x000007c6 MPU_xQueueIsQueueEmptyFromISR
0x000007e2 MPU_xQueueIsQueueFullFromISR
0x000007fe MPU_uxQueueMessagesWaitingFromISR
0x0000081a MPU_xTimerCreate
0x00000864 MPU_xEventGroupCreate
0x00000890 MPU_vEventGroupDelete
0x000008b0 MPU_xEventGroupClearBitsFromISR
0x000008d0 MPU_xEventGroupSetBitsFromISR
0x000008f4 MPU_xEventGroupGetBitsFromISR
0x00000910 MPU_xStreamBufferGenericCreate
0x0000096c MPU_vStreamBufferDelete
0x0000098c MPU_xStreamBufferReset
0x000009a8 MPU_xStreamBufferSendFromISR
0x000009d0 MPU_xStreamBufferReceiveFromISR
0x000009f8 MPU_xStreamBufferSendCompletedFromISR
0x00000a18 MPU_xStreamBufferReceiveCompletedFromISR
0x00000a38 MPU_xTaskDelayUntilImpl
0x00000a5e MPU_vTaskDelayImpl
0x00000a62 MPU_uxTaskPriorityGetImpl
0x00000a82 MPU_vTaskGetInfoImpl
0x00000ac8 MPU_vTaskSuspendImpl
0x00000af0 MPU_vTaskResumeImpl
0x00000b0a MPU_xTaskGetTickCountImpl
0x00000b0e MPU_uxTaskGetNumberOfTasksImpl
0x00000b12 MPU_pcTaskGetNameImpl
0x00000b32 MPU_uxTaskGetSystemStateImpl
0x00000b70 MPU_xTaskGetCurrentTaskHandleImpl
0x00000ba0 MPU_vTaskSetTimeOutStateImpl
0x00000bbe MPU_xTaskCheckForTimeOutImpl
0x00000bf4 MPU_xTaskGenericNotifyImpl
0x00000c36 MPU_xTaskGenericNotifyWaitImpl
0x00000c6c MPU_ulTaskGenericNotifyTakeImpl
0x00000c76 MPU_xTaskGenericNotifyStateClearImpl
0x00000c9c MPU_ulTaskGenericNotifyValueClearImpl
0x00000cc6 MPU_xQueueGenericSendImpl
0x00000d62 MPU_uxQueueMessagesWaitingImpl
0x00000d7e MPU_uxQueueSpacesAvailableImpl
0x00000d9a MPU_xQueueReceiveImpl
0x00000de6 MPU_xQueuePeekImpl
0x00000e32 MPU_xQueueSemaphoreTakeImpl
0x00000e64 MPU_xQueueTakeMutexRecursiveImpl
0x00000e84 MPU_xQueueGiveMutexRecursiveImpl
0x00000ea0 MPU_vQueueAddToRegistryImpl
0x00000ebe MPU_vQueueUnregisterQueueImpl
0x00000ed8 MPU_pcQueueGetNameImpl
0x00000ef4 MPU_pvTimerGetTimerIDImpl
0x00000f10 MPU_vTimerSetTimerIDImpl
0x00000f2e MPU_xTimerIsTimerActiveImpl
0x00000f4a MPU_xTimerGetTimerDaemonTaskHandleImpl
0x00000f4e MPU_xTimerGenericCommandImpl
0x00000f94 MPU_pcTimerGetNameImpl
0x00000fb0 MPU_vTimerSetReloadModeImpl
0x00000fce MPU_xTimerGetReloadModeImpl
0x00000fea MPU_uxTimerGetReloadModeImpl
0x00001006 MPU_xTimerGetPeriodImpl
0x00001022 MPU_xTimerGetExpiryTimeImpl
0x0000103e MPU_xEventGroupWaitBitsImpl
0x0000108a MPU_xEventGroupClearBitsImpl
0x000010b0 MPU_xEventGroupSetBitsImpl
0x000010d6 MPU_xEventGroupSyncImpl
0x00001116 MPU_uxEventGroupGetNumberImpl
0x00001132 MPU_vEventGroupSetNumberImpl
0x00001150 MPU_xStreamBufferSendImpl
0x0000118e MPU_xStreamBufferReceiveImpl
0x000011cc MPU_xStreamBufferIsFullImpl
0x000011e8 MPU_xStreamBufferIsEmptyImpl
0x00001204 MPU_xStreamBufferSpacesAvailableImpl
0x00001220 MPU_xStreamBufferBytesAvailableImpl
0x0000123c MPU_xStreamBufferSetTriggerLevelImpl
0x0000125c MPU_xStreamBufferNextMessageLengthBytesImpl
fill 0x00001278 0x8
0x00001280 0x79c build/middlware/freertos/portable/GCC/ARM_CM3_MPU/port.o
0x00001314 pxPortInitialiseStack
0x000013ae vPortEndScheduler
0x000013d0 vPortStoreTaskMPUSettings
0x000014c8 xPortIsAuthorizedToAccessBuffer
0x0000151a PendSV_Handler
0x000015b4 SysTick_Handler
0x000015e2 SVC_Handler
0x0000160c vSVCHandler_C
0x00001668 vPortEnterCritical
0x00001688 vPortExitCritical
0x000016b0 vSystemCallEnter
0x00001748 vSystemCallEnter_1
0x000017f4 vSystemCallExit
0x0000186c xPortIsTaskPrivileged
0x0000187e xPortStartScheduler
0x00001a1c 0x32 build/middlware/freertos/portable/MemMang/heap_3.o
0x00001a1c pvPortMalloc
0x00001a34 vPortFree
fill 0x00001a4e 0x2
0x00001a50 0x38c build/middlware/freertos/event_groups.o
0x00001a50 xEventGroupCreate
0x00001a6a xEventGroupWaitBits
0x00001b9a xEventGroupClearBits
0x00001be0 vEventGroupClearBitsCallback
0x00001be4 xEventGroupClearBitsFromISR
0x00001bf4 xEventGroupSetBits
0x00001c7c vEventGroupSetBitsCallback
0x00001c80 xEventGroupSetBitsFromISR
0x00001c90 xEventGroupSync
0x00001d60 xEventGroupGetBitsFromISR
0x00001d7c vEventGroupDelete
0x00001dd0 uxEventGroupGetNumber
0x00001dd6 vEventGroupSetNumber
0x00001ddc 0x80 build/middlware/freertos/list.o
0x00001ddc vListInitialise
0x00001df2 vListInitialiseItem
0x00001df8 vListInsert
0x00001e26 vListInsertEnd
0x00001e3c uxListRemove
0x00001e5c 0xce0 build/middlware/freertos/queue.o
0x00001f70 xQueueGenericSend
0x000020e8 xQueuePeek
0x00002222 xQueuePeekFromISR
0x00002298 xQueueReceive
0x000023d6 uxQueueMessagesWaiting
0x000023fc uxQueueSpacesAvailable
0x00002426 xQueueGenericSendFromISR
0x000024fe xQueueGiveFromISR
0x000025be xQueueReceiveFromISR
0x00002676 xQueueIsQueueEmptyFromISR
0x00002694 xQueueIsQueueFullFromISR
0x000026b4 uxQueueMessagesWaitingFromISR
0x000026cc xQueueSemaphoreTake
0x00002834 xQueueTakeMutexRecursive
0x00002876 xQueueGiveMutexRecursive
0x000028b4 vQueueAddToRegistry
0x00002904 vQueueUnregisterQueue
0x00002948 vQueueDelete
0x0000296a pcQueueGetName
0x000029a4 vQueueWaitForMessageRestricted
0x000029ea xQueueGenericReset
0x00002a84 xQueueGenericCreate
0x00002ad8 xQueueCreateMutex
0x00002afc xQueueCreateCountingSemaphore
0x00002b26 vQueueSetQueueNumber
0x00002b2a uxQueueGetQueueNumber
0x00002b2e ucQueueGetQueueType
0x00002b34 uxQueueGetQueueItemSize
0x00002b38 uxQueueGetQueueLength
0x00002b3c 0x7bc build/middlware/freertos/stream_buffer.o
0x00002cc8 xStreamBufferReceive
0x00002d9c xStreamBufferReceiveFromISR
0x00002e26 vStreamBufferDelete
0x00002e4c xStreamBufferIsEmpty
0x00002e6c xStreamBufferReset
0x00002eec xStreamBufferSpacesAvailable
0x00002f1e xStreamBufferSend
0x00003046 xStreamBufferSendFromISR
0x000030e2 xStreamBufferIsFull
0x0000310e xStreamBufferBytesAvailable
0x00003124 xStreamBufferSetTriggerLevel
0x0000314c xStreamBufferSendCompletedFromISR
0x0000319a xStreamBufferReceiveCompletedFromISR
0x000031e8 xStreamBufferGenericCreate
0x00003296 xStreamBufferNextMessageLengthBytes
0x000032e8 vStreamBufferSetStreamBufferNumber
0x000032ec uxStreamBufferGetStreamBufferNumber
0x000032f0 ucStreamBufferGetStreamBufferType
0x000032f8 0x1a50 build/middlware/freertos/tasks.o
0x000035d4 xTaskCreate
0x0000363c xTaskCreateRestricted
0x000036a8 vTaskAllocateMPURegions
0x000036bc uxTaskPriorityGet
0x000036dc uxTaskPriorityGetFromISR
0x0000370c eTaskGetState
0x00003790 vTaskPrioritySet
0x00003878 vTaskResume
0x00003918 xTaskResumeFromISR
0x000039e0 vTaskStartScheduler
0x00003a68 vTaskEndScheduler
0x00003a88 vTaskSuspendAll
0x00003a98 xTaskGetTickCount
0x00003aa4 xTaskGetTickCountFromISR
0x00003ab4 uxTaskGetNumberOfTasks
0x00003ac0 pcTaskGetName
0x00003ae4 xTaskGenericNotify
0x00003c1c xTaskGenericNotifyFromISR
0x00003da0 xTaskGenericNotifyWait
0x00003e50 vTaskGenericNotifyGiveFromISR
0x00003f7c ulTaskGenericNotifyTake
0x00003ffc xTaskGenericNotifyStateClear
0x0000403c ulTaskGenericNotifyValueClear
0x0000407c vTaskSetTimeOutState
0x000040b4 xTaskIncrementTick
0x00004238 xTaskResumeAll
0x00004380 vTaskDelay
0x000043c8 xTaskDelayUntil
0x00004464 vTaskGetInfo
0x00004560 uxTaskGetSystemState
0x000045f0 xTaskCatchUpTicks
0x00004630 vTaskPlaceOnEventList
0x00004664 vTaskPlaceOnUnorderedEventList
0x000046e0 vTaskPlaceOnEventListRestricted
0x00004740 xTaskRemoveFromEventList
0x00004820 vTaskRemoveFromUnorderedEventList
0x000048e8 vTaskSwitchContext
0x0000495c vTaskSuspend
0x00004a14 uxTaskResetEventItemValue
0x00004a34 xTaskGetCurrentTaskHandle
0x00004a40 vTaskMissedYield
0x00004a4c xTaskGetSchedulerState
0x00004a6c xTaskPriorityInherit
0x00004b18 xTaskPriorityDisinherit
0x00004bc0 vTaskPriorityDisinheritAfterTimeout
0x00004c7c uxTaskGetTaskNumber
0x00004c84 vTaskSetTaskNumber
0x00004c8c pvTaskIncrementMutexHeldCount
0x00004ca8 vTaskInternalSetTimeOutState
0x00004cc0 xTaskCheckForTimeOut
0x00004d38 xTaskGetMPUSettings
0x00004d48 0x57c build/middlware/freertos/timers.o
0x00005004 xTimerCreate
0x0000505e pvTimerGetTimerID
0x00005084 vTimerSetTimerID
0x000050ac xTimerIsTimerActive
0x000050d8 xTimerGetTimerDaemonTaskHandle
0x000050f8 xTimerPendFunctionCallFromISR
0x00005120 xTimerPendFunctionCall
0x00005160 pcTimerGetName
0x00005178 vTimerSetReloadMode
0x000051b2 xTimerGetReloadMode
0x000051de uxTimerGetReloadMode
0x000051e2 xTimerGetPeriod
0x000051fa xTimerGetExpiryTime
0x00005212 xTimerCreateTimerTask
0x00005264 xTimerGenericCommand
0x000052bc vTimerSetTimerNumber
0x000052c0 uxTimerGetTimerNumber
0x000052c4 . = ALIGN (0x4)
FILL mask 0xdead

.text 0x000052c4 0x442
0x000052c4 . = ALIGN (0x4)
0x000052c4 syscalls_flash_start = .
0x000052c4 syscalls_flash_end = .
0x000052c4 . = ALIGN (0x4)
.text.T1 0x000052c4 0x10 build/core/main.o
0x000052c4 T1
.text.T2 0x000052d4 0x10 build/core/main.o
0x000052d4 T2
0x000052e4 0x2 build/core/main.o
0x000052e4 MemManage_Handler
0x000052e6 0x2 build/core/main.o
0x000052e6 BusFault_Handler
0x000052e8 0x2 build/core/main.o
0x000052e8 UsageFault_Handler
fill 0x000052ea 0x2
0x000052ec 0x70 build/core/main.o
0x000052ec main
.text._start 0x0000535c 0x8 build/core/syscalls.o
0x0000535c _start
0x00005364 0x2 build/core/syscalls.o
0x00005364 DebugMon_Handler
fill 0x00005366 0x2
.text._sbrk 0x00005368 0x28 build/core/syscalls.o
0x00005368 _sbrk
0x00005390 0x2 build/core/syscalls.o
0x00005390 __malloc_lock
0x00005392 0x2 build/core/syscalls.o
0x00005392 __malloc_unlock
0x00005394 0x2 build/drivers/cmsis/device/armcm4/source/startup_ARMCM4.o
0x00005394 HardFault_Handler
0x00005396 0x2 build/drivers/cmsis/device/armcm4/source/startup_ARMCM4.o
0x00005396 NMI_Handler
0x00005396 Interrupt3_Handler
0x00005396 Interrupt8_Handler
0x00005396 Interrupt5_Handler
0x00005396 Interrupt7_Handler
0x00005396 Interrupt2_Handler
0x00005396 Interrupt0_Handler
0x00005396 Interrupt4_Handler
0x00005396 Default_Handler
0x00005396 Interrupt9_Handler
0x00005396 Interrupt6_Handler
0x00005396 Interrupt1_Handler
0x00005398 0x6c build/drivers/cmsis/device/armcm4/source/startup_ARMCM4.o
0x00005398 Reset_Handler
0x00005404 0x20 build/drivers/cmsis/device/armcm4/source/system_ARMCM4.o
0x00005404 SystemInit
0x00005424 0x24 build/middlware/freertos/portable/GCC/ARM_CM3_MPU/port.o
0x00005424 vPortSetupTimerInterrupt
0x00005448 0x5c build/middlware/freertos/portable/GCC/ARM_CM3_MPU/port.o
0x00005448 vPortValidateInterruptPriority
.text.memcpy 0x000054a4 0x1c /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-memcpy-stub.o)
0x000054a4 memcpy
.text.malloc 0x000054c0 0x10 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-malloc.o)
0x000054c0 malloc 0x000054d0 0x10 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-malloc.o)
0x000054d0 free
0x000054e0 0x44 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-mallocr.o)
0x00005524 0x100 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-mallocr.o)
0x00005524 _malloc_r
.text._sbrk_r 0x00005624 0x20 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-sbrkr.o)
0x00005624 _sbrk_r
.text.memset 0x00005644 0x10 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-memset.o)
0x00005644 memset
.text._free_r 0x00005654 0x94 /opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin/…/lib/gcc/arm-none-eabi/12.3.1/…/…/…/…/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(libc_a-freer.o)
0x00005654 _free_r

The file is too big to pate and I can’t add attachment as I’m new user so I added the relevant sections part of the file.
Look at section privileged_functions it contains all the availabe FreeRTOS API not just the ones used by the applicaltion. This is opposed to .text.<func_name> appearing after that, which are collection of .text parts that are actually used ny the application

you may try something like this - look at the two lines marked <== . You can force the priviledged_code section back into the text segment, just make sure to leave your interrupt vector table at the beginning of your flash. The linker may nw be able to look at your priviledged code just like code in the text segment.

Your exact syntax may vary, ie you might need to use

(.priviledged_functions) instead of (priviledged_functions). Just check your results against the map file.

.privileged_functions :
. = ALIGN(4);
. = ALIGN(4);
(privileged_functions) <== REMOVE THIS LINE
. = ALIGN(4);
/ En placed after the region reserved for

  • privileged kernel code. /
    Note that dot (.) actually refers to the byte offset from the start of
  • the current section (.privileged_functionsure that non-privileged code iss in this case). As a result,
  • setting dot (.) to a value sets the size of the section. */
    } >FLASH

.text :
. = ALIGN(4);
syscalls_flash_start = .;
syscalls_flash_end = .;
. = ALIGN(4);

(privileged_functions)  <== INSERT THIS LINE HERE
*(.text*)          /* .text* sections (code) */
*(.glue_7)         /* glue arm to thumb code */
*(.glue_7t)        /* glue thumb to arm code */




That did make any change in the executable size. All the content just moved to different memory region. privileged_functions still contains all the FreeRTOS APIs

But that does work with your application code? Ie if you define a dummy function in your code base but never call it, it will be included without the linker directive but not with it?

If I call the dummy func it’s included in the binary, if I don’t call it it’s not included

well, yes. That must be true trivially. My question is this: If you do NOT call it, will it be included in the binary with no -ffunction-sections but not included WITH -ffunction-sections, or does that flag not make a difference?

@AMniLo - I just bumped your forum status us so hopefully you will be able to post the map file now. You might have to rename it or zip it as only certain file types can be attached to posts.

The flag works. If the func is not called, with the flag it’s not included, wihtout the flag it is included.
The problem is that the flag only affects code in the .text section. It doesn’t seem to work with custom sections.