Azure RTOS (Threadx) tx_initialize_low_level.S文件编译错误

2022-10-12 23:58:50 浏览数 (3)

tx_initialize_low_level.S文件编译错误

AzureRTOS 提供了针对不同处理器的接口文件,这些文件可以无需任何修改的情况下移植到目标系统。

但是,移植时还有一个汇编文件 tx_initialize_low_level.S,这个文件位于接口文件夹,处理器目录的 demo 目录里。将该文件,添加到目标系统编译后,会出现错误,下面对遇到的问题分别说明。

1. 提示处理器不支持

编译输出下面的错误:

代码语言:txt复制
xxxxxxx/tx_initialize_low_level.S

C:/.../azure_rtos/tx_initialize_low_level.S: Assembler messages: 
C:/.../azure_rtos/tx_initialize_low_level.S:100: Error: selected processor does not support `cpsid i' in Thumb mode  
C:/.../azure_rtos/tx/_initialize/_low/_level.S:106: Error: lo register required -- `add r1,r1,#4'  
C:/.../azure_rtos/tx_initialize_low_level.S:111: Error: cannot honor width suffix -- `mov r0,#0xE000E000'  
C:/.../azure_rtos/tx_initialize_low_level.S:126: Error: cannot honor width suffix -- `orr r1,r1,#1'  
C:/.../azure_rtos/tx_initialize_low_level.S:131: Error: cannot honor width suffix -- `mov r0,#0xE000E000'

这是由于,.s 文件包含了与处理器架构相关的指令,而汇编器没有增加对指令的支持(主要是没有指定处理器架构)。所以只需要在汇编器参数中指定处理器架构类型。

Cmake 的处理如下:在汇编器参数中增加 ${MCPU_FLAGS} ${VFP_FLAGS}

代码语言:text复制
    # 定义通用编译器参数;
    set(CFCOMMON "${MCPU_FLAGS} ${VFP_FLAGS} --specs=nano.specs --specs=nosys.specs -Wall -fmessage-length=0 -ffunction-sections -fdata-sections")
    # ${MCPU_FLAGS} 这是自定义 Cmake 变量,表示处理内核版本;
    # ${VFP_FLAGS} 这也是自定义的 Cmake 变量,表示处理器浮点类型;

    # 定义最快运行速度发行模式的编译参数;
    set(CMAKE_C_FLAGS_RELEASE   "-Os ${CMAKE_C_FLAGS} ${CFCOMMON}")
    set(CMAKE_CXX_FLAGS_RELEASE "-Os ${CMAKE_CXX_FLAGS} ${CFCOMMON} -fno-exceptions")
    set(CMAKE_ASM_FLAGS_RELEASE "${MCPU_FLAGS} ${VFP_FLAGS} ${COMMON_COMPILE_FLAGS} -x assembler-with-cpp")

    # 定义最小尺寸且包含调试信息的编译参数;
    set(CMAKE_C_FLAGS_RELWITHDEBINFO   "-Os -g ${CMAKE_C_FLAGS} ${CFCOMMON}")
    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -g ${CMAKE_CXX_FLAGS} ${CFCOMMON} -fno-exceptions")
    set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "${MCPU_FLAGS} ${VFP_FLAGS} ${COMMON_COMPILE_FLAGS} -x assembler-with-cpp")

    # 定义最小尺寸的编译参数;
    set(CMAKE_C_FLAGS_MINSIZEREL   "-Os ${CMAKE_C_FLAGS} ${CFCOMMON}")
    set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os ${CMAKE_CXX_FLAGS} ${CFCOMMON} -fno-exceptions")
    set(CMAKE_ASM_FLAGS_MINSIZEREL "${MCPU_FLAGS} ${VFP_FLAGS} ${COMMON_COMPILE_FLAGS} -x assembler-with-cpp")

    # 定义调试模式编译参数;
    set(CMAKE_C_FLAGS_DEBUG   "-O0 -g ${CMAKE_C_FLAGS} ${CFCOMMON}")
    set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ${CMAKE_CXX_FLAGS} ${CFCOMMON} -fno-exceptions")
    set(CMAKE_ASM_FLAGS_DEBUG "${MCPU_FLAGS} ${VFP_FLAGS} ${COMMON_COMPILE_FLAGS} -x assembler-with-cpp")

2. undefined reference to RAM_segment_used_end'

RAM_segment_used_end 保存的是,当前已经使用的RAM区的结束地址,也就是空闲区域的起始地址。

通过下面的会变语句把该变量赋值给全局变 _tx_initialize_unused_memory

代码语言:text复制
@ Build address of unused memory pointer
LDR     r0, =_tx_initialize_unused_memory  
@ Build first free address
LDR     r1, =__RAM_segment_used_end__      

ADD     r1, r1, #4      

@ Setup first unused memory pointer
STR     r1, [r0]          

在操作系统启动调度之前会将该参数 _tx_initialize_unused_memory 传入函数 ***void  tx_application_define(void first_unused_memory)*** 完成动态内存起始地址的绑定。

对于 GCC 需要在连接文件 =xxx.ld 如下字段增加 RAM_segment_used_end = .

代码语言:text复制
._user_heap_stack :
{
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = .   _Min_Heap_Size;
    . = .   _Min_Stack_Size;
    . = ALIGN(8);
    __RAM_segment_used_end__ = .;

} >RAM

3. undefined reference to ‘_vectors'

该变量应该是中断向量表的入口。

只需要用 cmsis 提供的处理器的启动文件中的中断向量表入口替换这个变量就可以了。

STM32F429BIT6 为例。其 GCC 启动文件中定义中断向量表的代码为:

代码语言:text复制
    .section  .isr_vector,"a",%progbits
    .type  g_pfnVectors, %object
    .size  g_pfnVectors, .-g_pfnVectors

g_pfnVectors:

    .word  _estack
    .word  Reset_Handler    
    .word  NMI_Handler
    .word  HardFault_Handler
    .word  MemManage_Handler
    .word  BusFault_Handler
    .word  UsageFault_Handler

    .word  0
    .word  0

    .word  0

    .word  0        

那么,需要使用 g_pfnVectors 替换 _**tx

1 人点赞