Porting RT-Thread Nano to MCUXpresso and FRDM-MCXA346 | Technical Collection
RT-Thread Nano is a lightweight hard real-time kernel. For detailed introduction, please refer to the official link:
After introducing the official download addresses, this article focuses on porting RT-Thread Nano to MCUXpresso IDE. The porting code can be found on the nxpic.org.cn forum. A follow-up document will also cover porting to MCUXpresso VSC (Visual Studio Code).
1. Quick Run
● Prepare a PC with the latest MCUXpresso IDE installed and an FRDM-MCXA346 development board:
● Import the code package and run the result:
2. Software Downloads
1. RT-Thread Nano source code
2. MCUXpresso SDK
3. MCUXpresso IDE
4. MCUXpresso Config Tool (optional, since the IDE already includes it)
3. Porting Steps
- Import the MCUXpresso SDK into MCUXpresso IDE by dragging the SDK zip package into the IDE window:
2. Create a new project. Here, we use the lpuart polling example as a template. After creation, rename the project:
3. Copy the RT-Thread Nano source code into the project and add it to the build sequence:
4. Remove unnecessary files for the current platform, such as the bsp folder, the risc-v folder under libcpu, and the following under libcpu\arm: arm926, armv6, cortex-a, cortex-m0, cortex-m23, cortex-m3, cortex-m4, cortex-m7, cortex-r4.
(Keep libcpu\arm\common and cortex-m33 folders only.)
5. Exclude divsi3.S, context_iar.S, context_rvds.s, syscall_iar.S, syscall_rvds.S from the build:
4. Adapting RT-Thread Nano
- Rename lpuart_polling.c to main.c:
2. Add rt-thread/include and rt-thread/components/finsh to the project’s include paths:
3. Copy rtconfig.h and board.c from rt-thread nano\bsp\_template into the project’s source directory. Rename board.c to rtt_board.c:
4. After compilation, the compiler reports two missing APIs that need to be added during the porting process:
5. Add “MCXA346.h”, “app.h”, and “fsl_lpuart.h” into source/board.c:
6. In void rt_hw_board_init(void) within source/board.c, add:
BOARD_InitHardware();
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);7. Replace rt_os_tick_callback() with SysTick_Handler() in source/board.c:
8. Comment out TODO 2 and TODO 3.
a. TODO 2: UART debug initialization is already done in the example.
b. TODO 3: Add the following code:
9. Modify the header files in main.c:
10. Modify the core main function code in main.c:
11. Compilation will report duplicate definition of the HardFault function. Delete the auto-generated semihost_hardfault.c file:
12. Enable #define RT_USING_CONSOLE in rtconfig.h, then build and run. Remember to enable UART interrupts:
13. Upon running, the program enters Hardfault_Handler() and no UART output appears. First, fix the UART printing issue:
14. In startup/startup_mcxa346.c, hide the main call in ResetISR() and replace it with rt-thread nano entry(), as shown below,and the entry() function will call rt_hw_board_init() to initialize hardware. Rebuild and run, and now the hardfault should print messages:
15. HardFault printed messages: After several hours of debugging, the cause was identified — the linker script needed modification:
16. Right-click the project name → C/C++ Build -> Settings -> MCU Linker -> Managed Linker Script, and disable Manage Linker Script. Manual editing of the linker script is required:
17. Add the following section into frdmmcxa346_rt_thread_nano_mcux_Debug.ld, under the > PROGRAM_FLASH region:
-->
/***************RTOS
add**********************/
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for utest */
. = ALIGN(4);
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
/* section information for at server */
. = ALIGN(4);
__rtatcmdtab_start = .;
KEEP(*(RtAtCmdTab))
__rtatcmdtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
/* section information for modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
. = ALIGN(4);
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
. = ALIGN(4);18. Compile and run, and RT-Thread Nano will now print correctly.
