[活动] 【APM32E030R Micro-EVB开发板评测】rtthread移植开发板BSP的步骤

[复制链接]
 楼主| 北方西门吹雪 发表于 2025-8-4 14:07 | 显示全部楼层 |阅读模式
#申请原创# 1 rtthread移植开发板BSP的步骤需要从以下四个步骤逐步完成。
这个过程大致相当于绣花的过程,需要不少耐心和改错的过程。

2 第一步,对比分析芯片的存储地址分布和底层数据参数
在下载官方的rtthead库之后,从现有的bsp中寻找最接近的芯片作为母版。经过对比APM32F030R8T6和本开发板的APM32E030R8T6最为接近
APM01.JPG
对比后大致内存一致,外设有一些数量上侧差别,主频有所提升,同时最重要的,都是M0架构。内存地址分布也要对比一下,比较幸运的是几乎一样。这样在后面的修改中能减少不少的工作量。
APM01.1.JPG APM01.2.JPG

3 第二步,修改各级kconfig文件 ,这个是scons用来进行硬件和软件定义的文件。
这个是驱动中的kconfig
APM01.3.JPG
这个是工程中的kconfig
APM01.4.JPG

这个kconfig文件是可以通过menuconfig的UI界面启动并嵌入式分层修改的,不过,直接用文本编辑器修改效率更高。

4 第三步, 修改
sconstruct文件,这样注意是配置引用驱动的引入和定义不同kconfig下,如何配置驱动
APM01.5.JPG
典型的代码如下
  1. Import('RTT_ROOT')
  2. Import('rtconfig')
  3. from building import *

  4. cwd = GetCurrentDir()

  5. # add the general drivers.
  6. src = Split("""
  7. """)

  8. if GetDepend(['RT_USING_PIN']):
  9.     src += ['drv_gpio.c']

  10. if GetDepend(['RT_USING_SERIAL']):
  11.     if GetDepend(['RT_USING_SERIAL_V2']):
  12.         src += ['drv_usart_v2.c']
  13.     else:
  14.         src += ['drv_usart.c']

  15. if GetDepend(['RT_USING_ADC']):
  16.     src += ['drv_adc.c']

  17. if GetDepend(['RT_USING_DAC']):
  18.     src += ['drv_dac.c']

  19. if GetDepend('BSP_USING_ONCHIP_RTC'):
  20.     src += ['drv_rtc.c']

  21. if GetDepend(['RT_USING_I2C']):
  22.     if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
  23.         src += ['drv_soft_i2c.c']

  24. if GetDepend(['RT_USING_SPI']):
  25.     src += ['drv_spi.c']

  26. if GetDepend(['RT_USING_HWTIMER']):
  27.     src += ['drv_hwtimer.c']

  28. if GetDepend(['RT_USING_PWM']):
  29.     src += ['drv_pwm.c']

  30. if GetDepend(['BSP_USING_WDT']):
  31.     src += ['drv_wdt.c']

  32. if GetDepend(['BSP_USING_ETH', 'RT_USING_LWIP']):
  33.     src += ['drv_eth.c']

  34. if GetDepend(['BSP_USING_SDIO']):
  35.     src += ['drv_sdio.c']

  36. if GetDepend(['RT_USING_CAN']):
  37.     src += ['drv_can.c']

  38. if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_APM32F0']):
  39.     src += ['drv_flash/drv_flash_f0.c']

  40. src += ['drv_common.c']

  41. path =  [cwd]
  42. path += [cwd + '/config']

  43. if GetDepend('BSP_USING_ON_CHIP_FLASH'):
  44.     path += [cwd + '/drv_flash']

  45. group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)

  46. Return('group')
以及引入link链接库的代码如下,这个就是第一步中所分析所用到的数据要进行修改
  1. import os
  2. import rtconfig
  3. from building import *

  4. Import('SDK_LIB')

  5. cwd = GetCurrentDir()

  6. # add general drivers
  7. src = Split('''
  8. board.c
  9. ''')

  10. path =  [cwd]

  11. startup_path_prefix = SDK_LIB

  12. if rtconfig.PLATFORM in ['armcc', 'armclang']:
  13.     src += [startup_path_prefix + '/APM32E0xx_Library/Device/Geehy/APM32E030/Source/arm/startup_apm32e030.s']

  14. if rtconfig.PLATFORM in ['iccarm']:
  15.     src += [startup_path_prefix + '/APM32E0xx_Library/Device/Geehy/APM32E030/Source/iar/startup_apm32e030.s']

  16. if rtconfig.PLATFORM in ['gcc']:
  17.     src += [startup_path_prefix + '/APM32E0xx_Library/Device/Geehy/APM32E030/Source/gcc/startup_apm32e030.S']

  18. # APM32E030x6 || APM32E030x8 || APM32E030xC
  19. # You can select chips from the list above
  20. CPPDEFINES = ['APM32F030x8']
  21. group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
  22. Return('group')
这个是启动startup的asm汇编代码所在

  1.   .syntax unified
  2.   .cpu cortex-m0plus
  3.   .fpu softvfp
  4.   .thumb

  5. .global g_apm32_Vectors
  6. .global Default_Handler

  7. .word _start_address_init_data
  8. .word _start_address_data
  9. .word _end_address_data
  10. .word _start_address_bss
  11. .word _end_address_bss

  12.   .section .text.Reset_Handler
  13.   .weak Reset_Handler
  14.   .type Reset_Handler, %function

  15. // Reset handler routine
  16. Reset_Handler:
  17. // User Stack and Heap initialization
  18.   ldr   r0, =_end_stack
  19.   mov   sp, r0

  20.   ldr r0, =_start_address_data
  21.   ldr r1, =_end_address_data
  22.   ldr r2, =_start_address_init_data
  23.   movs r3, #0
  24.   b L_loop0_0

  25. L_loop0:
  26.   ldr r4, [r2, r3]
  27.   str r4, [r0, r3]
  28.   adds r3, r3, #4

  29. L_loop0_0:
  30.   adds r4, r0, r3
  31.   cmp r4, r1
  32.   bcc L_loop0

  33.   ldr r2, =_start_address_bss
  34.   ldr r4, =_end_address_bss
  35.   movs r3, #0
  36.   b L_loop1

  37. L_loop2:
  38.   str  r3, [r2]
  39.   adds r2, r2, #4

  40. L_loop1:
  41.   cmp r2, r4
  42.   bcc L_loop2

  43.   bl  SystemInit
  44.   bl __libc_init_array
  45.   bl main

  46. L_loop3:
  47.     b L_loop3

  48. .size Reset_Handler, .-Reset_Handler

  49. // This is the code that gets called when the processor receives an unexpected interrupt.
  50.     .section .text.Default_Handler,"ax",%progbits
  51. Default_Handler:
  52. L_Loop_infinite:
  53.   b L_Loop_infinite
  54.   .size Default_Handler, .-Default_Handler

  55. // The minimal vector table for a Cortex M0 Plus.
  56.    .section .apm32_isr_vector,"a",%progbits
  57.   .type g_apm32_Vectors, %object
  58.   .size g_apm32_Vectors, .-g_apm32_Vectors

  59. // Vector Table Mapped to Address 0 at Reset
  60. g_apm32_Vectors:
  61.   .word  _end_stack
  62.   .word  Reset_Handler                      // Reset Handler
  63.   .word  NMI_Handler                        // NMI Handler
  64.   .word  HardFault_Handler                  // Hard Fault Handler
  65.   .word  0                                  // Reserved
  66.   .word  0                                  // Reserved
  67.   .word  0                                  // Reserved
  68.   .word  0                                  // Reserved
  69.   .word  0                                  // Reserved
  70.   .word  0                                  // Reserved
  71.   .word  0                                  // Reserved
  72.   .word  SVC_Handler                        // SVCall Handler
  73.   .word  0                                  // Reserved
  74.   .word  0                                  // Reserved
  75.   .word  PendSV_Handler                     // PendSV Handler
  76.   .word  SysTick_Handler                    // SysTick Handler

  77.   // External Interrupts
  78.   .word  WWDT_IRQHandler                    // Window Watchdog
  79.   .word  0                                  // Reserved
  80.   .word  RTC_IRQHandler                     // RTC through EINT Line
  81.   .word  FLASH_IRQHandler                   // FLASH
  82.   .word  RCM_IRQHandler                     // RCM
  83.   .word  EINT0_1_IRQHandler                 // EINT Line 0 and 1
  84.   .word  EINT2_3_IRQHandler                 // EINT Line 2 and 3
  85.   .word  EINT4_15_IRQHandler                // EINT Line 4 to 15
  86.   .word  0                                  // Reserved
  87.   .word  DMA1_CH1_IRQHandler                // DMA1 Channel 1
  88.   .word  DMA1_CH2_3_IRQHandler              // DMA1 Channel 2 and Channel 3
  89.   .word  DMA1_CH4_5_IRQHandler              // DMA1 Channel 4 and Channel 5
  90.   .word  ADC1_IRQHandler                    // ADC1
  91.   .word  TMR1_BRK_UP_TRG_COM_IRQHandler     // TMR1 Break, Update, Trigger and Commutation
  92.   .word  TMR1_CC_IRQHandler                 // TMR1 Capture Compare
  93.   .word  0                                  // Reserved
  94.   .word  TMR3_IRQHandler                    // TMR3
  95.   .word  TMR6_IRQHandler                    // TMR6
  96.   .word  0                                  // Reserved
  97.   .word  TMR14_IRQHandler                   // TMR14
  98.   .word  TMR15_IRQHandler                   // TMR15
  99.   .word  TMR16_IRQHandler                   // TMR16
  100.   .word  TMR17_IRQHandler                   // TMR17
  101.   .word  I2C1_IRQHandler                    // I2C1
  102.   .word  I2C2_IRQHandler                    // I2C2
  103.   .word  SPI1_IRQHandler                    // SPI1
  104.   .word  SPI2_IRQHandler                    // SPI2
  105.   .word  USART1_IRQHandler                  // USART1
  106.   .word  USART2_IRQHandler                  // USART2

  107. // Default exception/interrupt handler

  108.   .weak      NMI_Handler
  109.   .thumb_set NMI_Handler,Default_Handler

  110.   .weak      HardFault_Handler
  111.   .thumb_set HardFault_Handler,Default_Handler

  112.   .weak      SVC_Handler
  113.   .thumb_set SVC_Handler,Default_Handler

  114.   .weak      PendSV_Handler
  115.   .thumb_set PendSV_Handler,Default_Handler

  116.   .weak      SysTick_Handler
  117.   .thumb_set SysTick_Handler,Default_Handler

  118.   .weak      WWDT_IRQHandler
  119.   .thumb_set WWDT_IRQHandler,Default_Handler

  120.   .weak      RTC_IRQHandler
  121.   .thumb_set RTC_IRQHandler,Default_Handler

  122.   .weak      FLASH_IRQHandler
  123.   .thumb_set FLASH_IRQHandler,Default_Handler

  124.   .weak      RCM_IRQHandler
  125.   .thumb_set RCM_IRQHandler,Default_Handler

  126.   .weak      EINT0_1_IRQHandler
  127.   .thumb_set EINT0_1_IRQHandler,Default_Handler

  128.   .weak      EINT2_3_IRQHandler
  129.   .thumb_set EINT2_3_IRQHandler,Default_Handler

  130.   .weak      EINT4_15_IRQHandler
  131.   .thumb_set EINT4_15_IRQHandler,Default_Handler

  132.   .weak      DMA1_CH1_IRQHandler
  133.   .thumb_set DMA1_CH1_IRQHandler,Default_Handler

  134.   .weak      DMA1_CH2_3_IRQHandler
  135.   .thumb_set DMA1_CH2_3_IRQHandler,Default_Handler

  136.   .weak      DMA1_CH4_5_IRQHandler
  137.   .thumb_set DMA1_CH4_5_IRQHandler,Default_Handler

  138.   .weak      ADC1_IRQHandler
  139.   .thumb_set ADC1_IRQHandler,Default_Handler

  140.   .weak      TMR1_BRK_UP_TRG_COM_IRQHandler
  141.   .thumb_set TMR1_BRK_UP_TRG_COM_IRQHandler,Default_Handler

  142.   .weak      TMR1_CC_IRQHandler
  143.   .thumb_set TMR1_CC_IRQHandler,Default_Handler

  144.   .weak      TMR3_IRQHandler
  145.   .thumb_set TMR3_IRQHandler,Default_Handler

  146.   .weak      TMR6_IRQHandler
  147.   .thumb_set TMR6_IRQHandler,Default_Handler

  148.   .weak      TMR14_IRQHandler
  149.   .thumb_set TMR14_IRQHandler,Default_Handler

  150.   .weak      TMR15_IRQHandler
  151.   .thumb_set TMR15_IRQHandler,Default_Handler

  152.   .weak      TMR16_IRQHandler
  153.   .thumb_set TMR16_IRQHandler,Default_Handler

  154.   .weak      TMR17_IRQHandler
  155.   .thumb_set TMR17_IRQHandler,Default_Handler

  156.   .weak      I2C1_IRQHandler
  157.   .thumb_set I2C1_IRQHandler,Default_Handler

  158.   .weak      I2C2_IRQHandler
  159.   .thumb_set I2C2_IRQHandler,Default_Handler

  160.   .weak      SPI1_IRQHandler
  161.   .thumb_set SPI1_IRQHandler,Default_Handler

  162.   .weak      SPI2_IRQHandler
  163.   .thumb_set SPI2_IRQHandler,Default_Handler

  164.   .weak      USART1_IRQHandler
  165.   .thumb_set USART1_IRQHandler,Default_Handler

  166.   .weak      USART2_IRQHandler
  167.   .thumb_set USART2_IRQHandler,Default_Handler
5 到此,基本代码和结构调试完整,在虚拟环境中输入scons进行工程构建,应该可以如下,形成二进制文件
APM02.JPG
最后,也就是第四步,进行调试器下载的配置。这个和keil一样需要选择安装包的配置,首先查看以下是否支持芯片
使用pyord pack list命令
APM03.JPG
可以看到,本次评测的APM32E030并不在支持的范围内。那么需要安装一下
pyocd pack install
APM04.JPG
这里显示是安装成功了,但是反复多次,发现并没有安装成功。对照官网的docs介绍,发现新的安装方法已经升级,本地安装不包括在本命令中。
但是可以在每次下载中,都用引用的方式,加载这个安装包,同样可以完成下载的任务。
APM05.JPG
这个使用的是
pyocd flash xxxx.bin文件的方式。
6 小结
这个过程花费了很长的时间,也在代码库中需要增加很多配置和调试的工作。而且,对应于rtthread的驱动代码,都需要有比较大的修订。因此,具体的步骤就不能容纳在这个帖子中了,但是经过上述4个步骤,可以完成bsp代码构建,为后续更多外部驱动的构建创造比较好的基础。





您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

120

帖子

1

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