• 采用arm-none-eabi-gcc交叉编译工具链 以及使用xmake构建 STM32 RT-Thread nano工程 笔记


    xmake构建工程

    由于多余的文件目录太多,所以删除了bsp目录

    xmake.lua构建文件编写

    -- 设置工程名
    set_project("stm32_rtt_nano_demo")
    
    -- 设置工程版本
    set_version("1.0.0")
    
    add_rules("mode.debug", "mode.release")
    
    -- 自定义工具链
    toolchain("arm-none-eabi")
        -- 标记为自定义独立工具链
        set_kind("standalone")
        -- 定义交叉编译工具链地址,根据工具链的实际位置修改
        set_sdkdir("C:\\gcc-arm-none-eabi\\10 2021.10")   
    toolchain_end()
    
    target("rtt_thread.elf")
        -- 编译为二进制程序
        set_kind("binary") 
        -- 设置使用的交叉编译工具链
        set_toolchains("arm-none-eabi")  
    
        -- 设置平台
        set_plat("cross")
        -- 设置架构
        set_arch("m3")
    
        -- 设置编译生成程序名字,不设置就会使用target("rtt_thread.elf")里面的名字
        --set_filename("rtt_thread.elf")
    
        add_defines(
            "USE_HAL_DRIVER",  -- 使用HAL库
            "STM32F103xB"  -- 参考 libraries\STM32F1xx_HAL\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h 60行 进行设置   
        )
    
        -- 添加链接库
        add_links("c", "m");  -- 或者链接选项添加 :-lc -lm -lnosys -lrdimon 
        
        add_cflags(
            "-Og",
            "-mcpu=cortex-m3",
            "-mthumb",
            "-Wall",
            "-fdata-sections",
            "-ffunction-sections",
            "-g3 -gdwarf-2",
            "--specs=nano.specs", 
            {force = true}
        )
    
        add_asflags(
            "-Og",
            "-mcpu=cortex-m3",
            "-mthumb",
           "-x assembler-with-cpp",
            "-Wall",
            "-fdata-sections", 
            "-ffunction-sections",
            "-g3 -gdwarf-2",
            {force = true}
        )
    
        add_ldflags(
            "-Og",
            "-mcpu=cortex-m3",
            "-TSTM32F103C8Tx_FLASH.ld",  -- 不同芯片需要修改链接脚本 STM32F103XE_FLASH.ld STM32F103C8Tx_FLASH.ld
            "-Wl,--gc-sections",
            "--specs=nosys.specs",
            "--specs=nano.specs",  -- 减小代码尺寸
            "-u _printf_float",  -- 支持printf打印浮点数
            {force = true}
        )
        
        -- 源文件和头文件路径
        local src_path = {
            "applications",
            "drivers",
            "libraries/STM32F1xx_HAL_Driver/Src",
            "drivers/bsp",
        }
        -- 头文件路径
        local inc_path = {
            "applications",
            "drivers",
            "drivers/bsp",
            "libraries/STM32F1xx_HAL_Driver/Inc",
            "libraries/CMSIS/Device/ST/STM32F1xx/Include",
            "libraries/CMSIS/Include",
            "config",
        }
        -- RT-Thread source files
        local rtt_src = {
            "rt-thread/src",
            "rt-thread/libcpu/arm/cortex-m3",
            "rt-thread/components/finsh",
        }
        -- RT-Thread header files
        local rtt_inc = {
            "rt-thread/include",
            "rt-thread",
            "rt-thread/components/finsh",
            "rt-thread/components/drivers/include/drivers"
        }
        -- RT-Thread 线程调度相关的汇编文件
        add_files("rt-thread/libcpu/arm/cortex-m3/context_gcc.S")
    
        -- 添加启动文件(根据芯片选择) 
        add_files("startup_stm32f103xb.s");
    
        for _, dir in ipairs(src_path) do  -- 遍历 src_path
            add_files(dir.."/*.c"); 
        end
    
         for _, dir in ipairs(rtt_src) do  -- 遍历 rtt_src
            add_files(dir.."/*.c"); 
        end
    
        -- 添加头文件路径
        for _, inc in ipairs(inc_path) do
            add_includedirs(inc);
        end
    
        for _, inc in ipairs(rtt_inc) do
            add_includedirs(inc);
        end
       
        if is_mode("debug") then 
            -- add_cflags("-g", "-gdwarf-2")
            add_defines("DEBUG")
        end
    
        after_build(
            function(target)
            cprint("Compile finished!!!")
    
            if is_mode("release") then
                print("release finished")
                os.exec("arm-none-eabi-objcopy -O ihex ./build/cross/m3/release/rtt_thread.elf ./build/rtt_thread.hex")
                os.exec("arm-none-eabi-objcopy -O binary ./build/cross/m3/release/rtt_thread.elf ./build/rtt_thread.bin")
            end
    
            if is_mode("debug") then
                print("debug finished")
                os.exec("arm-none-eabi-objcopy -O ihex ./build/cross/m3/debug/rtt_thread.elf ./build/rtt_thread.hex")
                os.exec("arm-none-eabi-objcopy -O binary ./build/cross/m3/debug/rtt_thread.elf ./build/rtt_thread.bin")
            end
    
            print("Generate hex and bin files ok!!!")
    
            print(" ");
            print("********************储存空间占用情况*****************************")
            if is_mode("release") then
                os.exec("arm-none-eabi-size -Ax ./build/cross/m3/release/rtt_thread.elf")
                os.exec("arm-none-eabi-size -Bx ./build/cross/m3/release/rtt_thread.elf")
                os.exec("arm-none-eabi-size -Bd ./build/cross/m3/release/rtt_thread.elf")
            end
    
            if is_mode("debug") then
                os.exec("arm-none-eabi-size -Ax ./build/cross/m3/debug/rtt_thread.elf")
                os.exec("arm-none-eabi-size -Bx ./build/cross/m3/debug/rtt_thread.elf")
                os.exec("arm-none-eabi-size -Bd ./build/cross/m3/debug/rtt_thread.elf")
            end
            --print("heap-堆, stack-栈, .data-已初始化的变量全局/静态变量, .bss-未初始化的data, .text-代码和常量")
            -- os.run("arm-none-eabi-objdump.exe -D ./build/cross/m3/release/rtt_thread.elf > rtt_thread.s")
            -- os.exec("arm-none-eabi-objdump -h -S ./build/cross/m3/debug/rtt_thread.elf > rtt_thread.list")
        end)
    

    RT-Thread nano 自动初始化段添加

     /* The program code and other data goes into FLASH */
      .text :
      {
        . = ALIGN(4);
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */
        *(.glue_7)         /* glue arm to thumb code */
        *(.glue_7t)        /* glue thumb to arm code */
        *(.eh_frame)
    
        KEEP (*(.init))
        KEEP (*(.fini))
        
        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code */
    
               /* section information for finsh shell */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))
        __fsymtab_end = .; */
     
        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))
        __vsymtab_end = .; 
    
        /* section information for initial. */
        . = ALIGN(4);
        __rt_init_start = .;
        KEEP(*(SORT(.rti_fn*)))
        __rt_init_end = .;
        
      } >FLASH
    
    

    RT-Thread nano在gcc下自动初始化段不能失效,原因是gcc的自定义段需要在链接脚本中添加自定义段

    添加的自定义段如下:

             /* section information for finsh shell */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))
        __fsymtab_end = .; */
     
        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))
        __vsymtab_end = .; 
    
        /* section information for initial. */
        . = ALIGN(4);
        __rt_init_start = .;
        KEEP(*(SORT(.rti_fn*)))
        __rt_init_end = .;
    

    如果使用的容量太小的MCU,如64K小容量的,不要开启Finsh组件。

    多数情况下也不要shell组件。

    给RT-Thread定义的堆内存不要太大,够用就行。否则小容量的单片机RAM只有20K,其他地方定义大数组就会超过RAM大小,程序编译链接失败:

    "arm-none-eabi-ld.exe: region `ram' overflowed xxx bytes" 
    

    修改链接地址和重设中断向量

    修改链接地址为0x800B000,也是加载地址

    /* Entry Point */
    ENTRY(Reset_Handler)
    
    /* Highest address of the user mode stack */
    _estack = 0x20005000;    /* end of RAM */
    /* Generate a link error if heap and stack don't fit into RAM */
    _Min_Heap_Size = 0x400;      /* required amount of heap  */
    _Min_Stack_Size = 0x800; /* required amount of stack */
    
    /* Specify the memory areas */
    MEMORY
    {
      RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K
      FLASH (rx)      : ORIGIN = 0x800B000, LENGTH = 64K
    }
    
    • FLASH (rx) : ORIGIN = 0x8000000 改 FLASH (rx) : ORIGIN = 0x800B000

    根据芯片不同,修改不同头文件
    libraries/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:

    #define FLASH_BASE            0x0800B000U /*!< FLASH base address in the alias region */
    #define FLASH_BANK1_END       0x0801FFFFU /*!< FLASH END address of bank1 */
    #define SRAM_BASE             0x20000000U /*!< SRAM base address in the alias region */
    
    • FLASH_BASE改为0x0800B000U

    常用的xmake编译操作

    1、编译

    xmake
    

    2、根据xmake配置生成makefile

     xmake project -k makefile
    

    3、切换到debug模式编译

    xmake f -m debug   // 切换为debug模式 
    xmake    //编译
    

    4、编译且输出警告信息

    xmake -w 或 xmake --warning
    

    5、看详细的编译参数信息

    xmake -v 或 xmake --verbose
    

    6、编译以及获取出错时xmake的调试栈信息

    xmake -v --backtrace
    

    xmake编译需要注意的问题

    1、xmake.lua 如果是其他工程拷贝过来的,可以删除.xmake文件夹和build文件夹,或者执行xmake f -c强制清除配置缓存,主要是.xmake缓存了上一个工程的配置信息等,会编译失败

    2、修改链接地址后不生效,生成反汇编如果不生效的话,先xmake clean清除上一次编译缓存的obj文件,再执行xmake编译

    3、如果前一次编译没有错误,而此次编译出现错误,可以尝试使用xmake f -c清除配置缓存再次进行编译。

    代码

    https://github.com/guangjieMVP/stm32_m3_rtt_nano_xmake_template

  • 相关阅读:
    探秘磁盘的奥秘:物理结构、缓存和虚拟内存的作用
    工业物联网网关在机房动力环境监控系统有何作用?
    Spring基于Annotation装配Bean
    CSS常见选择器
    flutter 的 in_app_web_view实现下载功能
    景联文科技:深度探究自动驾驶重要方向——车路协同
    rsync远程同步+inotify监控
    VS c++多文件编译
    2023华为杯研究生数学建模C题分析
    大数据Hadoop之——部署hadoop+hive+Mysql环境(Linux)
  • 原文地址:https://blog.csdn.net/qq_36413982/article/details/126888055