返回列表 发新帖我要提问本帖赏金: 80.00元(功能说明)

[MM32生态] 使用 rt-thread env 构建开源免费的 mm32f3270 开发环境

[复制链接]
3503|1
 楼主| yang377156216 发表于 2022-9-15 13:40 | 显示全部楼层 |阅读模式
本帖最后由 yang377156216 于 2022-9-15 13:43 编辑
#申请原创#  @21小跑堂

前言
刚刚接手的一个项目是一个严格要求国产化替代项目,所有器件都必须使用国产料,并且 MCU 的编译环境也必须是免费和开源的,调试和烧录器也得用国内厂家的工具,不得带有任何外商色彩。好吧,我第一个就想到了  RT-Thread 和配套的 IDE ,由于对 MM32 比较熟悉,在灵动官网一番选型后确认使用 MM32F3273G7P 这颗 M3 内核的 MCU 了,各种资源都较为符合应用需求,最让我欣慰的是 rtthread 的官方 github 仓中的 bsp 已经包含了 mm32f327x 系列芯片,这样缩短了我的开发周期,所以开始了全国产化平台开发之旅。
github rtt bsp 中自带 mm32f3270 .png

RT-Thread ENV 开发环境搭建
首先需要了解 RT-Thread 以及其配套开发环境的话,可以直接进入官网提供的文档中心,里面包含了入门学习、进阶学习和应用开发这三个层次的文档,开发者可以根据自己的实际情况进行选择。接着要进行的是搭建好对应的开发环境,这里选择使用 ENV 环境而先不用 IDE 工具,因为这样所占 PC 资源要小很多。
RT-Thread 的 ENV 工具到底是个什么东西呢?它由以下内容构成:
env 构成.png
ENV 是 RT-Thread 推出的开发辅助工具,针对基于 RT-Thread 操作系统的项目工程,为用户提供编译构建环境 scons、图形化系统配置 meunuconfig 及在线软件包管理三大功能。menuconfig 提供了简单易用的配置剪裁工具,可对内核、组件和软件包进行自由裁剪,使整个系统可以像搭积木的方式进行构建。scons 作为默认的构建工具,它基于 Python 开发,因此我们需要先安装python 并且把它添加到环境变量中,这里我用的是 Python 2.7 版本,貌似 Python 3.X 是不能正常运行 SCons 的。另外最好也把 git 安装并设置好,因为很多源码组件都会用到它。
接着到官网将 ENV 工具下载好,下载链接如下:
ENV工具下载链接:https://www.rt-thread.org/page/download.html
1.rtthread env tool下载.png
下载好后可以有两种方式进行打开 ENV 工具,一个是简单的双击 env.exe / env.bat ,二个是先将它进行一番设置后则可以在任意文件夹空白处右击控制台了,具体设置步骤如下图所示:
Add_Env_To_Right-click_Menu.png
这里有一点需要注意,ENV 工具包所在的目录路径不能包含中文或空格,否则会报以下错误:
env 不能有中文路径.png
接着到 rtthread 的官方 github 仓中将源码包下载好,下载链接如下:
https://github.com/RT-Thread/rt-thread
得到的源码包目录结构如下,其中 bsp 中包含了一些已经添加进去了的开发板或者芯片源工程:
rtthread sdk 目录结构.png
如果前面说的 python 、git 以及相关注意事项都已经处理好,那么接下来可以进入到 bsp\mm32f327x 路径下并且在该路径下打开 env 控制台,使用 scons 进行编译构建示例源码了,其中包括了工程模板,通过 scons 构建好的工程,rtconfig.py 构建脚本等,如下图所示:
mm32f327x bsp 目录.png
如果是使用 IAR 或 MDK 来进行工程开发,可以使用以下命令构建对应的工程:
  • 构建IAR工程:scons --target=iar
  • 构建MDK工程:scons --target=mdk5 或 scons --target=mdk4
为了验证环境是否正常,这里使用 scons --target=mdk5 命令进行编译,可以看到已经可以正确编译了:
keil 工程编译 ok.png
但由于 keil 和 iar 都属于商业开发软件而且都不属于国产的或者开源免费的,有违背本次的导入目标,于是想到使用 scons 的 gcc 构建方式,因为 ENV工具就已经带有 ARM GCC 编译器,输入 scons 命令直接编译 BSP,这时候默认使用的是 ARM GCC 编译器了。
但是又发现 mm32f327x 这个支持包中并没有将 gcc 的方式添加进去,所以得自己参照 stm32f103 任意一款开发板的支持包进行添加。

MM32F327X ENV GCC 支持
首先需要添加芯片的 gcc 启动文件,在路径 bsp\mm32f327x\Libraries\MM32F327x\Source 下添加 startup_mm32f327x_gcc.s ,内容如下:
  1. /**
  2.   *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
  3.   * [url=home.php?mod=space&uid=288409]@file[/url]      startup_mm32f3273g9p.s
  4.   * [url=home.php?mod=space&uid=187600]@author[/url]    MCD Application Team
  5.   * [url=home.php?mod=space&uid=247401]@brief[/url]     MM32F3273G9PDevices vector table for Atollic toolchain.
  6.   *            This module performs:
  7.   *                - Set the initial SP
  8.   *                - Set the initial PC == Reset_Handler,
  9.   *                - Set the vector table entries with the exceptions ISR address
  10.   *                - Configure the clock system   
  11.   *                - Configure external SRAM mounted on MM32F3273G9P EVAL board
  12.   *                  to be used as data memory (optional, to be enabled by user)
  13.   *                - Branches to main in the C library (which eventually
  14.   *                  calls main()).
  15.   *            After Reset the Cortex-M3 processor is in Thread mode,
  16.   *            priority is Privileged, and the Stack is set to Main.
  17.   ******************************************************************************
  18.   * @attention
  19.   *
  20.   * <h2><center>© Copyright (c) 2017 STMicroelectronics.
  21.   * All rights reserved.</center></h2>
  22.   *
  23.   * This software component is licensed by ST under BSD 3-Clause license,
  24.   * the "License"; You may not use this file except in compliance with the
  25.   * License. You may obtain a copy of the License at:
  26.   *                        opensource.org/licenses/BSD-3-Clause
  27.   *
  28.   ******************************************************************************
  29.   */

  30.   .syntax unified
  31.   .cpu cortex-m3
  32.   .fpu softvfp
  33.   .thumb

  34. .global g_pfnVectors
  35. .global Default_Handler

  36. /* start address for the initialization values of the .data section.
  37. defined in linker script */
  38. .word _sidata
  39. /* start address for the .data section. defined in linker script */
  40. .word _sdata
  41. /* end address for the .data section. defined in linker script */
  42. .word _edata
  43. /* start address for the .bss section. defined in linker script */
  44. .word _sbss
  45. /* end address for the .bss section. defined in linker script */
  46. .word _ebss

  47. .equ  BootRAM,        0xF1E0F85F
  48. /**
  49. * [url=home.php?mod=space&uid=247401]@brief[/url]  This is the code that gets called when the processor first
  50. *          starts execution following a reset event. Only the absolutely
  51. *          necessary set is performed, after which the application
  52. *          supplied main() routine is called.
  53. * @param  None
  54. * @retval : None
  55. */

  56.   .section .text.Reset_Handler
  57.   .weak Reset_Handler
  58.   .type Reset_Handler, %function
  59. Reset_Handler:

  60. /* Copy the data segment initializers from flash to SRAM */
  61.   movs r1, #0
  62.   b LoopCopyDataInit

  63. CopyDataInit:
  64.   ldr r3, =_sidata
  65.   ldr r3, [r3, r1]
  66.   str r3, [r0, r1]
  67.   adds r1, r1, #4

  68. LoopCopyDataInit:
  69.   ldr r0, =_sdata
  70.   ldr r3, =_edata
  71.   adds r2, r0, r1
  72.   cmp r2, r3
  73.   bcc CopyDataInit
  74.   ldr r2, =_sbss
  75.   b LoopFillZerobss
  76. /* Zero fill the bss segment. */
  77. FillZerobss:
  78.   movs r3, #0
  79.   str r3, [r2], #4

  80. LoopFillZerobss:
  81.   ldr r3, = _ebss
  82.   cmp r2, r3
  83.   bcc FillZerobss

  84. /* Call the clock system intitialization function.*/
  85.     bl  SystemInit
  86. /* Call static constructors */
  87.     bl __libc_init_array
  88. /* Call the application's entry point.*/
  89.   bl entry
  90.   bx lr
  91. .size Reset_Handler, .-Reset_Handler

  92. /**
  93. * @brief  This is the code that gets called when the processor receives an
  94. *         unexpected interrupt.  This simply enters an infinite loop, preserving
  95. *         the system state for examination by a debugger.
  96. *
  97. * @param  None
  98. * @retval : None
  99. */
  100.     .section .text.Default_Handler,"ax",%progbits
  101. Default_Handler:
  102. Infinite_Loop:
  103.   b Infinite_Loop
  104.   .size Default_Handler, .-Default_Handler
  105. /******************************************************************************
  106. *
  107. * The minimal vector table for a Cortex M3.  Note that the proper constructs
  108. * must be placed on this to ensure that it ends up at physical address
  109. * 0x0000.0000.
  110. *
  111. ******************************************************************************/
  112.   .section .isr_vector,"a",%progbits
  113.   .type g_pfnVectors, %object
  114.   .size g_pfnVectors, .-g_pfnVectors


  115. g_pfnVectors:

  116.   .word _estack
  117.   .word Reset_Handler
  118.   .word NMI_Handler
  119.   .word HardFault_Handler
  120.   .word MemManage_Handler
  121.   .word BusFault_Handler
  122.   .word UsageFault_Handler
  123.   .word 0
  124.   .word 0
  125.   .word 0
  126.   .word 0
  127.   .word SVC_Handler
  128.   .word DebugMon_Handler
  129.   .word 0
  130.   .word PendSV_Handler
  131.   .word SysTick_Handler
  132.   .word WWDG_IRQHandler
  133.   .word PVD_IRQHandler
  134.   .word TAMPER_IRQHandler
  135.   .word RTC_IRQHandler
  136.   .word FLASH_IRQHandler
  137.   .word RCC_CRS_IRQHandler
  138.   .word EXTI0_IRQHandler
  139.   .word EXTI1_IRQHandler
  140.   .word EXTI2_IRQHandler
  141.   .word EXTI3_IRQHandler
  142.   .word EXTI4_IRQHandler
  143.   .word DMA1_Channel1_IRQHandler
  144.   .word DMA1_Channel2_IRQHandler
  145.   .word DMA1_Channel3_IRQHandler
  146.   .word DMA1_Channel4_IRQHandler
  147.   .word DMA1_Channel5_IRQHandler
  148.   .word DMA1_Channel6_IRQHandler
  149.   .word DMA1_Channel7_IRQHandler
  150.   .word ADC1_2_IRQHandler
  151.   .word FlashCache_IRQHandler
  152.   .word 0
  153.   .word CAN1_RX_IRQHandler
  154.   .word 0
  155.   .word EXTI9_5_IRQHandler
  156.   .word TIM1_BRK_IRQHandler
  157.   .word TIM1_UP_IRQHandler
  158.   .word TIM1_TRG_COM_IRQHandler
  159.   .word TIM1_CC_IRQHandler
  160.   .word TIM2_IRQHandler
  161.   .word TIM3_IRQHandler
  162.   .word TIM4_IRQHandler
  163.   .word I2C1_IRQHandler
  164.   .word 0
  165.   .word I2C2_IRQHandler
  166.   .word 0
  167.   .word SPI1_IRQHandler
  168.   .word SPI2_IRQHandler
  169.   .word UART1_IRQHandler
  170.   .word UART2_IRQHandler
  171.   .word UART3_IRQHandler
  172.   .word EXTI15_10_IRQHandler
  173.   .word RTCAlarm_IRQHandler
  174.   .word OTG_FS_WKUP_IRQHandler
  175.   .word TIM8_BRK_IRQHandler
  176.   .word TIM8_UP_IRQHandler
  177.   .word TIM8_TRG_COM_IRQHandler
  178.   .word TIM8_CC_IRQHandler
  179.   .word ADC3_IRQHandler
  180.   .word 0
  181.   .word SDIO_IRQHandler
  182.   .word TIM5_IRQHandler
  183.   .word SPI3_IRQHandler
  184.   .word UART4_IRQHandler
  185.   .word UART5_IRQHandler
  186.   .word TIM6_IRQHandler
  187.   .word TIM7_IRQHandler
  188.   .word DMA2_Channel1_IRQHandler
  189.   .word DMA2_Channel2_IRQHandler
  190.   .word DMA2_Channel3_IRQHandler
  191.   .word DMA2_Channel4_IRQHandler
  192.   .word DMA2_Channel5_IRQHandler
  193.   .word ETH_IRQHandler
  194.   .word 0
  195.   .word 0
  196.   .word COMP1_2_IRQHandler
  197.   .word 0
  198.   .word 0
  199.   .word OTG_FS_IRQHandler
  200.   .word 0
  201.   .word 0
  202.   .word 0
  203.   .word UART6_IRQHandler
  204.   .word 0
  205.   .word 0
  206.   .word 0
  207.   .word 0
  208.   .word 0
  209.   .word 0
  210.   .word 0
  211.   .word 0
  212.   .word 0
  213.   .word 0
  214.   .word UART7_IRQHandler
  215.   .word UART8_IRQHandler
  216.   .word BootRAM      

  217. /*******************************************************************************
  218. *
  219. * Provide weak aliases for each Exception handler to the Default_Handler.
  220. * As they are weak aliases, any function with the same name will override
  221. * this definition.
  222. *
  223. *******************************************************************************/

  224.   .weak NMI_Handler
  225.   .thumb_set NMI_Handler,Default_Handler

  226.   .weak HardFault_Handler
  227.   .thumb_set HardFault_Handler,Default_Handler

  228.   .weak MemManage_Handler
  229.   .thumb_set MemManage_Handler,Default_Handler

  230.   .weak BusFault_Handler
  231.   .thumb_set BusFault_Handler,Default_Handler

  232.   .weak UsageFault_Handler
  233.   .thumb_set UsageFault_Handler,Default_Handler

  234.   .weak SVC_Handler
  235.   .thumb_set SVC_Handler,Default_Handler

  236.   .weak DebugMon_Handler
  237.   .thumb_set DebugMon_Handler,Default_Handler

  238.   .weak PendSV_Handler
  239.   .thumb_set PendSV_Handler,Default_Handler

  240.   .weak SysTick_Handler
  241.   .thumb_set SysTick_Handler,Default_Handler

  242.   .weak WWDG_IRQHandler
  243.   .thumb_set WWDG_IRQHandler,Default_Handler

  244.   .weak PVD_IRQHandler
  245.   .thumb_set PVD_IRQHandler,Default_Handler

  246.   .weak TAMPER_IRQHandler
  247.   .thumb_set TAMPER_IRQHandler,Default_Handler

  248.   .weak RTC_IRQHandler
  249.   .thumb_set RTC_IRQHandler,Default_Handler

  250.   .weak FLASH_IRQHandler
  251.   .thumb_set FLASH_IRQHandler,Default_Handler

  252.   .weak RCC_CRS_IRQHandler
  253.   .thumb_set RCC_CRS_IRQHandler,Default_Handler

  254.   .weak EXTI0_IRQHandler
  255.   .thumb_set EXTI0_IRQHandler,Default_Handler

  256.   .weak EXTI1_IRQHandler
  257.   .thumb_set EXTI1_IRQHandler,Default_Handler

  258.   .weak EXTI2_IRQHandler
  259.   .thumb_set EXTI2_IRQHandler,Default_Handler

  260.   .weak EXTI3_IRQHandler
  261.   .thumb_set EXTI3_IRQHandler,Default_Handler

  262.   .weak EXTI4_IRQHandler
  263.   .thumb_set EXTI4_IRQHandler,Default_Handler

  264.   .weak DMA1_Channel1_IRQHandler
  265.   .thumb_set DMA1_Channel1_IRQHandler,Default_Handler

  266.   .weak DMA1_Channel2_IRQHandler
  267.   .thumb_set DMA1_Channel2_IRQHandler,Default_Handler

  268.   .weak DMA1_Channel3_IRQHandler
  269.   .thumb_set DMA1_Channel3_IRQHandler,Default_Handler

  270.   .weak DMA1_Channel4_IRQHandler
  271.   .thumb_set DMA1_Channel4_IRQHandler,Default_Handler

  272.   .weak DMA1_Channel5_IRQHandler
  273.   .thumb_set DMA1_Channel5_IRQHandler,Default_Handler

  274.   .weak DMA1_Channel6_IRQHandler
  275.   .thumb_set DMA1_Channel6_IRQHandler,Default_Handler

  276.   .weak DMA1_Channel7_IRQHandler
  277.   .thumb_set DMA1_Channel7_IRQHandler,Default_Handler

  278.   .weak ADC1_2_IRQHandler
  279.   .thumb_set ADC1_2_IRQHandler,Default_Handler

  280.   .weak FlashCache_IRQHandler
  281.   .thumb_set FlashCache_IRQHandler,Default_Handler

  282.   .weak CAN1_RX_IRQHandler
  283.   .thumb_set CAN1_RX_IRQHandler,Default_Handler

  284.   .weak EXTI9_5_IRQHandler
  285.   .thumb_set EXTI9_5_IRQHandler,Default_Handler

  286.   .weak TIM1_BRK_IRQHandler
  287.   .thumb_set TIM1_BRK_IRQHandler,Default_Handler

  288.   .weak TIM1_UP_IRQHandler
  289.   .thumb_set TIM1_UP_IRQHandler,Default_Handler

  290.   .weak TIM1_TRG_COM_IRQHandler
  291.   .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler

  292.   .weak TIM1_CC_IRQHandler
  293.   .thumb_set TIM1_CC_IRQHandler,Default_Handler

  294.   .weak TIM2_IRQHandler
  295.   .thumb_set TIM2_IRQHandler,Default_Handler

  296.   .weak TIM3_IRQHandler
  297.   .thumb_set TIM3_IRQHandler,Default_Handler

  298.   .weak TIM4_IRQHandler
  299.   .thumb_set TIM4_IRQHandler,Default_Handler

  300.   .weak I2C1_IRQHandler
  301.   .thumb_set I2C1_IRQHandler,Default_Handler

  302.   .weak I2C2_IRQHandler
  303.   .thumb_set I2C2_IRQHandler,Default_Handler

  304.   .weak SPI1_IRQHandler
  305.   .thumb_set SPI1_IRQHandler,Default_Handler

  306.   .weak SPI2_IRQHandler
  307.   .thumb_set SPI2_IRQHandler,Default_Handler

  308.   .weak UART1_IRQHandler
  309.   .thumb_set UART1_IRQHandler,Default_Handler

  310.   .weak UART2_IRQHandler
  311.   .thumb_set UART2_IRQHandler,Default_Handler

  312.   .weak UART3_IRQHandler
  313.   .thumb_set UART3_IRQHandler,Default_Handler

  314.   .weak EXTI15_10_IRQHandler
  315.   .thumb_set EXTI15_10_IRQHandler,Default_Handler

  316.   .weak RTCAlarm_IRQHandler
  317.   .thumb_set RTCAlarm_IRQHandler,Default_Handler

  318.   .weak OTG_FS_WKUP_IRQHandler
  319.   .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler

  320.   .weak TIM8_BRK_IRQHandler
  321.   .thumb_set TIM8_BRK_IRQHandler,Default_Handler

  322.   .weak TIM8_UP_IRQHandler
  323.   .thumb_set TIM8_UP_IRQHandler,Default_Handler

  324.   .weak TIM8_TRG_COM_IRQHandler
  325.   .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler

  326.   .weak TIM8_CC_IRQHandler
  327.   .thumb_set TIM8_CC_IRQHandler,Default_Handler

  328.   .weak ADC3_IRQHandler
  329.   .thumb_set ADC3_IRQHandler,Default_Handler

  330.   .weak SDIO_IRQHandler
  331.   .thumb_set SDIO_IRQHandler,Default_Handler

  332.   .weak TIM5_IRQHandler
  333.   .thumb_set TIM5_IRQHandler,Default_Handler

  334.   .weak SPI3_IRQHandler
  335.   .thumb_set SPI3_IRQHandler,Default_Handler

  336.   .weak UART4_IRQHandler
  337.   .thumb_set UART4_IRQHandler,Default_Handler

  338.   .weak UART5_IRQHandler
  339.   .thumb_set UART5_IRQHandler,Default_Handler

  340.   .weak TIM6_IRQHandler
  341.   .thumb_set TIM6_IRQHandler,Default_Handler

  342.   .weak TIM7_IRQHandler
  343.   .thumb_set TIM7_IRQHandler,Default_Handler

  344.   .weak DMA2_Channel1_IRQHandler
  345.   .thumb_set DMA2_Channel1_IRQHandler,Default_Handler

  346.   .weak DMA2_Channel2_IRQHandler
  347.   .thumb_set DMA2_Channel2_IRQHandler,Default_Handler

  348.   .weak DMA2_Channel3_IRQHandler
  349.   .thumb_set DMA2_Channel3_IRQHandler,Default_Handler

  350.   .weak DMA2_Channel4_IRQHandler
  351.   .thumb_set DMA2_Channel4_IRQHandler,Default_Handler

  352.   .weak DMA2_Channel5_IRQHandler
  353.   .thumb_set DMA2_Channel5_IRQHandler,Default_Handler

  354.   .weak ETH_IRQHandler
  355.   .thumb_set ETH_IRQHandler,Default_Handler

  356.   .weak COMP1_2_IRQHandler
  357.   .thumb_set COMP1_2_IRQHandler,Default_Handler

  358.   .weak OTG_FS_IRQHandler
  359.   .thumb_set OTG_FS_IRQHandler,Default_Handler

  360.   .weak UART6_IRQHandler
  361.   .thumb_set UART6_IRQHandler,Default_Handler

  362.   .weak UART7_IRQHandler
  363.   .thumb_set UART7_IRQHandler,Default_Handler

  364.   .weak UART8_IRQHandler
  365.   .thumb_set UART8_IRQHandler,Default_Handler

  366. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
阅读 scons 构建脚本可知,gcc 方式的 link 文件需要放在 drivers\linker_scripts ,并且得知可以设置 ENV 工具自带的 gcc 以外的编译器路径,只要自己在 rtconfig.py 中实际修改好即可:
rtconfig.py 的 gcc 构建.png
于是添加 link.lds 在此目录下,内容如下:
  1. /*
  2. * linker script for MM32F3273 with GNU ld
  3. */

  4. /* Program Entry, set to mark it as "used" and avoid gc */
  5. MEMORY
  6. {
  7.     ROM (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */
  8.     RAM (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128KB sram */
  9. }
  10. ENTRY(Reset_Handler)
  11. _system_stack_size = 0x800;

  12. SECTIONS
  13. {
  14.     .text :
  15.     {
  16.         . = ALIGN(4);
  17.         _stext = .;
  18.         KEEP(*(.isr_vector))            /* Startup code */

  19.         . = ALIGN(4);
  20.         *(.text)                        /* remaining code */
  21.         *(.text.*)                      /* remaining code */
  22.         *(.rodata)                      /* read-only data (constants) */
  23.         *(.rodata*)
  24.         *(.glue_7)
  25.         *(.glue_7t)
  26.         *(.gnu.linkonce.t*)

  27.         /* section information for finsh shell */
  28.         . = ALIGN(4);
  29.         __fsymtab_start = .;
  30.         KEEP(*(FSymTab))
  31.         __fsymtab_end = .;

  32.         . = ALIGN(4);
  33.         __vsymtab_start = .;
  34.         KEEP(*(VSymTab))
  35.         __vsymtab_end = .;

  36.         /* section information for initial. */
  37.         . = ALIGN(4);
  38.         __rt_init_start = .;
  39.         KEEP(*(SORT(.rti_fn*)))
  40.         __rt_init_end = .;

  41.         . = ALIGN(4);

  42.         PROVIDE(__ctors_start__ = .);
  43.         KEEP (*(SORT(.init_array.*)))
  44.         KEEP (*(.init_array))
  45.         PROVIDE(__ctors_end__ = .);

  46.         . = ALIGN(4);

  47.         _etext = .;
  48.     } > ROM = 0

  49.     /* .ARM.exidx is sorted, so has to go in its own output section.  */
  50.     __exidx_start = .;
  51.     .ARM.exidx :
  52.     {
  53.         *(.ARM.exidx* .gnu.linkonce.armexidx.*)

  54.         /* This is used by the startup in order to initialize the .data secion */
  55.         _sidata = .;
  56.     } > ROM
  57.     __exidx_end = .;

  58.     /* .data section which is used for initialized data */

  59.     .data : AT (_sidata)
  60.     {
  61.         . = ALIGN(4);
  62.         /* This is used by the startup in order to initialize the .data secion */
  63.         _sdata = . ;

  64.         *(.data)
  65.         *(.data.*)
  66.         *(.gnu.linkonce.d*)

  67.         PROVIDE(__dtors_start__ = .);
  68.         KEEP(*(SORT(.dtors.*)))
  69.         KEEP(*(.dtors))
  70.         PROVIDE(__dtors_end__ = .);

  71.         . = ALIGN(4);
  72.         /* This is used by the startup in order to initialize the .data secion */
  73.         _edata = . ;
  74.     } >RAM

  75.     .stack :
  76.     {
  77.         . = ALIGN(4);
  78.         _sstack = .;
  79.         . = . + _system_stack_size;
  80.         . = ALIGN(4);
  81.         _estack = .;
  82.     } >RAM

  83.     __bss_start = .;
  84.     .bss :
  85.     {
  86.         . = ALIGN(4);
  87.         /* This is used by the startup in order to initialize the .bss secion */
  88.         _sbss = .;

  89.         *(.bss)
  90.         *(.bss.*)
  91.         *(COMMON)

  92.         . = ALIGN(4);
  93.         /* This is used by the startup in order to initialize the .bss secion */
  94.         _ebss = . ;
  95.         
  96.         *(.bss.init)
  97.     } > RAM
  98.     __bss_end = .;

  99.     _end = .;

  100.     /* Stabs debugging sections.  */
  101.     .stab          0 : { *(.stab) }
  102.     .stabstr       0 : { *(.stabstr) }
  103.     .stab.excl     0 : { *(.stab.excl) }
  104.     .stab.exclstr  0 : { *(.stab.exclstr) }
  105.     .stab.index    0 : { *(.stab.index) }
  106.     .stab.indexstr 0 : { *(.stab.indexstr) }
  107.     .comment       0 : { *(.comment) }
  108.     /* DWARF debug sections.
  109.      * Symbols in the DWARF debugging sections are relative to the beginning
  110.      * of the section so we begin them at 0.  */
  111.     /* DWARF 1 */
  112.     .debug          0 : { *(.debug) }
  113.     .line           0 : { *(.line) }
  114.     /* GNU DWARF 1 extensions */
  115.     .debug_srcinfo  0 : { *(.debug_srcinfo) }
  116.     .debug_sfnames  0 : { *(.debug_sfnames) }
  117.     /* DWARF 1.1 and DWARF 2 */
  118.     .debug_aranges  0 : { *(.debug_aranges) }
  119.     .debug_pubnames 0 : { *(.debug_pubnames) }
  120.     /* DWARF 2 */
  121.     .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  122.     .debug_abbrev   0 : { *(.debug_abbrev) }
  123.     .debug_line     0 : { *(.debug_line) }
  124.     .debug_frame    0 : { *(.debug_frame) }
  125.     .debug_str      0 : { *(.debug_str) }
  126.     .debug_loc      0 : { *(.debug_loc) }
  127.     .debug_macinfo  0 : { *(.debug_macinfo) }
  128.     /* SGI/MIPS DWARF 2 extensions */
  129.     .debug_weaknames 0 : { *(.debug_weaknames) }
  130.     .debug_funcnames 0 : { *(.debug_funcnames) }
  131.     .debug_typenames 0 : { *(.debug_typenames) }
  132.     .debug_varnames  0 : { *(.debug_varnames) }
  133. }
到这里基本已经搭建好了 mm32f327x 的 ENV 的 gcc 编译环境,于是可以运行 scons 命令直接构建编译了,正常的话可以看到成功编译结果如下:
gcc 工程编译 ok.png


接下来可以使用 menuconfig 命令对整个工程的组件包进行增删配置,每次使用 menuconfig 对 bsp 进行配置后,都需要再使用 scons 命令对相应的工程进行重新生成,以便配置能生效,以下为配置主页:
menuconfig 主页.png
为了使 bsp 包中只与本芯片/开发板有关,而其它无关项全部删除,可以使用 scons --dist 命令进行搭建项目框架,命令执行后,会在 bsp 包目录里面生成 dist 目录,它包含了整个mm32f327x 的工程,这样就打包成功了,只是需要注意生成 mdk 或者 iar 的时候需要避坑(需要手动将 keil 对应的context_rvds.S 文件,放入 dist 对应的 libcpu 目录下):
scons dist.png

另外涉及到的知识点
已经搭建好 rt-thread 的 env 开发环境了,还需要关注的一些开发时候会涉及到的知识点整理如下:
pkgs --update 和 pkgs --upgrade 软件包管理和更新命令的使用 ;
使用 ENV 工具的条件有:RT-Thread 3.0+版本,低版本要做一些迁移,要有kconfig配置文件 ;
menuconfig 启动后默认到当前目录下寻找 Kconfig 文件并解析。Kconfig 中可以通过 source 指定加载子 Kconfig 文件,这样根据 Kconfig 文件的内部调用结构,menuconfig 依次解析所有被引用的Kconfig 文件,生成内部的配置选项数据库解析 .config 文件,根据上一次的配置结果初始化各个配置选项的初值。给用户展示配置界面,并根据用户的选择更新内部数据库,最后 menuconfig 生成 .config 文件会自动生成配置头文件 rtconfig.h ,该文件对整个操作系统以及中间件进行裁剪、配置 ;
每一个 RT-Thread bsp 目录下都会存在下面三个文件:rtconfig.py、SConstruct 和 SConscript,它们控制 bsp 的编译。SConstruct 文件是 scons 默认解析的第一个脚本,因此 scons 命令必须在它所在的路径下执行,一般建议将 SConstruct 脚本与 rtconfig.py 脚本置于用户工程目录中。rtconfig.py 文件主要用于指定编译器以及安装路径。除此之外,该文件中定义了大量的变量,这些变量包括编译选项,汇编选项,链接选项。同目录下的 SConscript 文件表示 scons 中间加载类脚本,applications 目录下的 SConscript 文件为 scons 代码组织类脚本,它可以添加用户需要额外编译的 .c 文件,比如 led.c 。

开发环境已经搭建准备好,后面只需要在这个框架中添加自己的驱动和应用代码,以及编写好正确的编译脚本,结合 RT-Thread 丰富的组件以及 MM32-Link Mini 调试器(CMSIS-DAP Link)+PyOCD 方式的 RTT 输出打印功能,相信这趟国产替代之旅会很顺畅,大家也可以同我一起来尝试哟!
下面我附上我改过的 bsp-mm32f327x 支持包。
rt-thread bsp mm32f327x.zip (1.13 MB, 下载次数: 2)

打赏榜单

21小跑堂 打赏了 80.00 元 2022-09-19
理由:恭喜通过原创文章审核!请多多加油哦!

评论

深入浅出搭建RT-Thread开发环境,作者将每一步介绍清晰,设计要点均有涉猎,对后来者有较好的帮助。开发环境和微控制器全国产,构建国内工程师新的开发历程,未来的路还很长,好的开头更需要大家的共同支持和努力。  发表于 2022-9-19 15:02
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

240

帖子

13

粉丝
快速回复 在线客服 返回列表 返回顶部