Skip to content

Conversation

@malsyned
Copy link
Contributor

@malsyned malsyned commented Aug 4, 2025

Description

Add "ax" flags to .section directives for freertos_system_calls in mpu_wrappers_v2_asm.S and privileged_functions in portASM.S.

GNU as makes unrecognized sections loadable and writable by default, but LLVM's assembler requires specifying flags explicitly. Without them, the linker generates "has non-ABS relocation" errors when trying to link the resulting object files.

Test Steps

  • Download ARM Toolchain for Embedded (ATfE) from https://github.com/arm/arm-toolchain/tags
  • Unpack ATfE somewhere.
  • Apply the patch below to the CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC Demo (Github wouldn't let me attach it, despite claiming to support patch file attachments -- sorry)
  • Modify the demo's CMakeLists.txt to point CMAKE_C_COMPILER and CMAKE_ASM_COMPILER to the bin/clang in your newly unpacked ATfE tree.
  • Attempt to build the demo: cmake -B build-clang -S . && cmake --build build-clang --parallel

Built against FreeRTOS-Kernel's main branch, you should see many "non-ABS relocation" linker errors. They look like these two examples below:

ld.lld: error: .../portASM.S.obj:(privileged_functions+0x100): has non-ABS relocation R_ARM_CALL against symbol 'vTaskSwitchContext'
ld.lld: error: .../mpu_wrappers_v2_asm.S.obj:(freertos_system_calls+0x1e8): has non-ABS relocation R_ARM_JUMP24 against symbol 'MPU_vTaskDelayImpl'

These errors should be resolved by this PR, and the demo binary images should compile and link without error (albeit with plenty of warnings).

NOTE: I don't have a LAUNCHXL2-RM46 or TMDXRM46HDK development kit, so I was only able to confirm that the demo compiles after my PR, not that it runs. I have tested this same change on my own project, though, and it works for me.

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request.

CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC-clang.patch

diff --git a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_link.ld b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_link.ld
index e94c71c18..cce3cadbf 100644
--- a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_link.ld
+++ b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_link.ld
@@ -199,7 +199,7 @@ SECTIONS
     . = ALIGN(4);
     /* Mark the start of the region for debugging purposes. */
     __start_privileged_stack_region = .;
-    . = __privileged_stack_region_size;
+    . += __privileged_stack_region_size;
     . = ALIGN(4);
     /* Mark the end of the region for debugging purposes. */
     __end_privileged_stack_region = .;
@@ -214,7 +214,7 @@ SECTIONS
     /* 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__;
+    . = __start_privileged_stack_region + __privileged_data_region_size__;
     . = ALIGN(4);
   } >RAM AT> FLASH
 
diff --git a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_startup.c b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_startup.c
index 551ca666b..35ca88349 100644
--- a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_startup.c
+++ b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/BoardFiles/source/sys_startup.c
@@ -94,6 +94,13 @@ __attribute__( ( naked ) )
 void _c_int00( void )
 {
     /* USER CODE BEGIN (5) */
+    __asm__(
+        "bl _coreInitRegisters_\n\t"
+        "bl _coreInitStackPointer_\n\t"
+        "b _c_int01"
+    );
+}
+#if 0
     /* USER CODE END */
 
     /* Initialize Core Registers to avoid CCM Error */
@@ -106,6 +113,8 @@ void _c_int00( void )
     _coreInitStackPointer_();
 
     /* USER CODE BEGIN (7) */
+#endif
+void _c_int01(void) __attribute__((noreturn)) {
     /* USER CODE END */
 
     /* Enable CPU Event Export */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/CMakeLists.txt b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/CMakeLists.txt
index c35b86b79..f4b29988f 100644
--- a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/CMakeLists.txt
+++ b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/CMakeLists.txt
@@ -7,8 +7,11 @@ SET(CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment t
 SET(CMAKE_OSX_SYSROOT "" CACHE STRING "Force unset of the deployment target for iOS" FORCE)
 
 # Set the compiler before declaring the project for the test build
-SET(CMAKE_C_COMPILER "arm-none-eabi-gcc")
-SET(CMAKE_ASM_COMPILER "arm-none-eabi-gcc")
+SET(CMAKE_C_COMPILER "/home/malsyned/packages/ATfE-20.1.0-Linux-x86_64/bin/clang")
+SET(CMAKE_ASM_COMPILER "/home/malsyned/packages/ATfE-20.1.0-Linux-x86_64/bin/clang")
+SET(CMAKE_C_COMPILER_TARGET arm-none-eabi)
+SET(CMAKE_ASM_COMPILER_TARGET arm-none-eabi)
+SET(CMAKE_C_COMPILER_WORKS ON)
 
 # Set the system processor and name before declaring the project
 # Needs to be set here otherwise it will fail the test compilation
@@ -17,8 +20,8 @@ SET(CMAKE_SYSTEM_PROCESSOR "armv7-r" CACHE STRING "Target system is an ARM7r Pro
 
 # Set the ASM and C compilation flags
 SET(CMAKE_ASM_FLAGS "-mcpu=cortex-r4 -mfpu=vfpv3-d16 -Og -g -ggdb -Wall -MMD -MP")
-SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -specs=\"nosys.specs\" -specs=\"nano.specs\"")
 SET(CMAKE_C_FLAGS "${CMAKE_ASM_FLAGS} -marm -mfloat-abi=hard")
+SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -x assembler-with-cpp -Dfmxr=vmsr -Dfmdrr=vmov -Dcpu=extern")
 
 project(RM46_FreeRTOS C ASM)
 
@@ -152,7 +155,7 @@ ADD_LIBRARY(FREERTOS_PORT OBJECT
 # On Mac the C_LINK flags by default adds "-Wl,-search_paths_first -Wl,-headerpad_max_install_names" which
 # Causes the executable that gets built to strip the symbols, so force set it to empty here.
 SET(CMAKE_C_LINK_FLAGS "")
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map,\"RTOSDemo.map\" -Wl,-T\"${BOARD_FILES_DIR}/source/sys_link.ld\"")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map,\"RTOSDemo.map\" -Wl,-T\"${BOARD_FILES_DIR}/source/sys_link.ld\" -nostartfiles")
 
 # Debug
 MESSAGE("Demo Sources: ${FREERTOS_DEMO_SOURCES}")
diff --git a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/main.c b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/main.c
index 005500421..aee4af084 100644
--- a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/main.c
+++ b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/main.c
@@ -91,6 +91,12 @@ extern PRIVILEGED_DATA volatile uint32_t ulPortYieldRequired;
 
 /* ------------------------------------------------------------------------- */
 
+void _exit(int n)
+{
+    for (;;)
+        ;
+}
+
 int main( void )
 {
     UBaseType_t xReturn = pdPASS;
diff --git a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/reg_test_GCC.S b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/reg_test_GCC.S
index 43b8fc7d0..45d54166b 100644
--- a/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/reg_test_GCC.S
+++ b/FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC/source/reg_test_GCC.S
@@ -181,7 +181,7 @@ reg1_error_loopf:
     /* If this line is hit then a VFP register value was found to be
     incorrect. */
     B       reg1_error_loopf
-    B        0xDEACFC
+    /* B        0xDEACFC */
 
 reg1_loopf_pass:
 
@@ -239,7 +239,7 @@ reg1_loopf_pass:
 reg1_error_loop:
     /* If this line is hit then there was an error in a core register value.
     The loop ensures the loop counter stops incrementing. */
-    B       0xDEACFD
+    /* B       0xDEACFD */
     NOP
 
 /*-----------------------------------------------------------*/
@@ -384,7 +384,7 @@ reg2_loop:
 reg2_error_loopf:
     /* If this line is hit then a VFP register value was found to be
     incorrect. */
-    B        0xDEACFE
+    /* B        0xDEACFE */
 
 reg2_loopf_pass:
 
@@ -439,7 +439,7 @@ reg2_loopf_pass:
 reg2_error_loop:
     /* If this line is hit then there was an error in a core register value.
     The loop ensures the loop counter stops incrementing. */
-    B     0xDEACFF
+    /* B     0xDEACFF */
     NOP
 
 /* End of file */

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

GNU as makes unrecognized sections loadable and writable by default, but
LLVM's assembler requires specifying flags explicitly. Without them, the
linker generates "has non-ABS relocation" errors when trying to link the
resulting object files.
@malsyned malsyned requested a review from a team as a code owner August 4, 2025 21:57
@sonarqubecloud
Copy link

sonarqubecloud bot commented Aug 4, 2025

@aggarg
Copy link
Member

aggarg commented Aug 5, 2025

Thank you for providing the detailed instructions. I have verified using these instructions. I have also verified the demo on RM57 board and it works with these changes.

@aggarg aggarg merged commit c5bec0e into FreeRTOS:main Aug 5, 2025
17 checks passed
moninom1 pushed a commit to moninom1/FreeRTOS-Kernel that referenced this pull request Sep 30, 2025
* Update Community-Supported-Demos submodule pointer

Signed-off-by: Gaurav Aggarwal <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants