- Import('RTT_ROOT')
- Import('rtconfig')
- from building import *
- cwd = GetCurrentDir()
- # add the general drivers.
- src = Split("""
- """)
- if GetDepend(['RT_USING_PIN']):
- src += ['drv_gpio.c']
- if GetDepend(['RT_USING_SERIAL']):
- if GetDepend(['RT_USING_SERIAL_V2']):
- src += ['drv_usart_v2.c']
- else:
- src += ['drv_usart.c']
- if GetDepend(['RT_USING_ADC']):
- src += ['drv_adc.c']
- if GetDepend(['RT_USING_DAC']):
- src += ['drv_dac.c']
- if GetDepend('BSP_USING_ONCHIP_RTC'):
- src += ['drv_rtc.c']
- if GetDepend(['RT_USING_I2C']):
- if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
- src += ['drv_soft_i2c.c']
- if GetDepend(['RT_USING_SPI']):
- src += ['drv_spi.c']
- if GetDepend(['RT_USING_HWTIMER']):
- src += ['drv_hwtimer.c']
- if GetDepend(['RT_USING_PWM']):
- src += ['drv_pwm.c']
- if GetDepend(['BSP_USING_WDT']):
- src += ['drv_wdt.c']
- if GetDepend(['BSP_USING_ETH', 'RT_USING_LWIP']):
- src += ['drv_eth.c']
- if GetDepend(['BSP_USING_SDIO']):
- src += ['drv_sdio.c']
- if GetDepend(['RT_USING_CAN']):
- src += ['drv_can.c']
- if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_APM32F0']):
- src += ['drv_flash/drv_flash_f0.c']
- src += ['drv_common.c']
- path = [cwd]
- path += [cwd + '/config']
- if GetDepend('BSP_USING_ON_CHIP_FLASH'):
- path += [cwd + '/drv_flash']
- group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
- Return('group')
以及引入link链接库的代码如下,这个就是第一步中所分析所用到的数据要进行修改
- import os
- import rtconfig
- from building import *
- Import('SDK_LIB')
- cwd = GetCurrentDir()
- # add general drivers
- src = Split('''
- board.c
- ''')
- path = [cwd]
- startup_path_prefix = SDK_LIB
- if rtconfig.PLATFORM in ['armcc', 'armclang']:
- src += [startup_path_prefix + '/APM32E0xx_Library/Device/Geehy/APM32E030/Source/arm/startup_apm32e030.s']
- if rtconfig.PLATFORM in ['iccarm']:
- src += [startup_path_prefix + '/APM32E0xx_Library/Device/Geehy/APM32E030/Source/iar/startup_apm32e030.s']
- if rtconfig.PLATFORM in ['gcc']:
- src += [startup_path_prefix + '/APM32E0xx_Library/Device/Geehy/APM32E030/Source/gcc/startup_apm32e030.S']
- # APM32E030x6 || APM32E030x8 || APM32E030xC
- # You can select chips from the list above
- CPPDEFINES = ['APM32F030x8']
- group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
- Return('group')
这个是启动startup的asm汇编代码所在
- .syntax unified
- .cpu cortex-m0plus
- .fpu softvfp
- .thumb
- .global g_apm32_Vectors
- .global Default_Handler
- .word _start_address_init_data
- .word _start_address_data
- .word _end_address_data
- .word _start_address_bss
- .word _end_address_bss
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
- // Reset handler routine
- Reset_Handler:
- // User Stack and Heap initialization
- ldr r0, =_end_stack
- mov sp, r0
- ldr r0, =_start_address_data
- ldr r1, =_end_address_data
- ldr r2, =_start_address_init_data
- movs r3, #0
- b L_loop0_0
- L_loop0:
- ldr r4, [r2, r3]
- str r4, [r0, r3]
- adds r3, r3, #4
- L_loop0_0:
- adds r4, r0, r3
- cmp r4, r1
- bcc L_loop0
- ldr r2, =_start_address_bss
- ldr r4, =_end_address_bss
- movs r3, #0
- b L_loop1
- L_loop2:
- str r3, [r2]
- adds r2, r2, #4
- L_loop1:
- cmp r2, r4
- bcc L_loop2
- bl SystemInit
- bl __libc_init_array
- bl main
- L_loop3:
- b L_loop3
- .size Reset_Handler, .-Reset_Handler
- // This is the code that gets called when the processor receives an unexpected interrupt.
- .section .text.Default_Handler,"ax",%progbits
- Default_Handler:
- L_Loop_infinite:
- b L_Loop_infinite
- .size Default_Handler, .-Default_Handler
- // The minimal vector table for a Cortex M0 Plus.
- .section .apm32_isr_vector,"a",%progbits
- .type g_apm32_Vectors, %object
- .size g_apm32_Vectors, .-g_apm32_Vectors
- // Vector Table Mapped to Address 0 at Reset
- g_apm32_Vectors:
- .word _end_stack
- .word Reset_Handler // Reset Handler
- .word NMI_Handler // NMI Handler
- .word HardFault_Handler // Hard Fault Handler
- .word 0 // Reserved
- .word 0 // Reserved
- .word 0 // Reserved
- .word 0 // Reserved
- .word 0 // Reserved
- .word 0 // Reserved
- .word 0 // Reserved
- .word SVC_Handler // SVCall Handler
- .word 0 // Reserved
- .word 0 // Reserved
- .word PendSV_Handler // PendSV Handler
- .word SysTick_Handler // SysTick Handler
- // External Interrupts
- .word WWDT_IRQHandler // Window Watchdog
- .word 0 // Reserved
- .word RTC_IRQHandler // RTC through EINT Line
- .word FLASH_IRQHandler // FLASH
- .word RCM_IRQHandler // RCM
- .word EINT0_1_IRQHandler // EINT Line 0 and 1
- .word EINT2_3_IRQHandler // EINT Line 2 and 3
- .word EINT4_15_IRQHandler // EINT Line 4 to 15
- .word 0 // Reserved
- .word DMA1_CH1_IRQHandler // DMA1 Channel 1
- .word DMA1_CH2_3_IRQHandler // DMA1 Channel 2 and Channel 3
- .word DMA1_CH4_5_IRQHandler // DMA1 Channel 4 and Channel 5
- .word ADC1_IRQHandler // ADC1
- .word TMR1_BRK_UP_TRG_COM_IRQHandler // TMR1 Break, Update, Trigger and Commutation
- .word TMR1_CC_IRQHandler // TMR1 Capture Compare
- .word 0 // Reserved
- .word TMR3_IRQHandler // TMR3
- .word TMR6_IRQHandler // TMR6
- .word 0 // Reserved
- .word TMR14_IRQHandler // TMR14
- .word TMR15_IRQHandler // TMR15
- .word TMR16_IRQHandler // TMR16
- .word TMR17_IRQHandler // TMR17
- .word I2C1_IRQHandler // I2C1
- .word I2C2_IRQHandler // I2C2
- .word SPI1_IRQHandler // SPI1
- .word SPI2_IRQHandler // SPI2
- .word USART1_IRQHandler // USART1
- .word USART2_IRQHandler // USART2
- // Default exception/interrupt handler
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
- .weak WWDT_IRQHandler
- .thumb_set WWDT_IRQHandler,Default_Handler
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
- .weak RCM_IRQHandler
- .thumb_set RCM_IRQHandler,Default_Handler
- .weak EINT0_1_IRQHandler
- .thumb_set EINT0_1_IRQHandler,Default_Handler
- .weak EINT2_3_IRQHandler
- .thumb_set EINT2_3_IRQHandler,Default_Handler
- .weak EINT4_15_IRQHandler
- .thumb_set EINT4_15_IRQHandler,Default_Handler
- .weak DMA1_CH1_IRQHandler
- .thumb_set DMA1_CH1_IRQHandler,Default_Handler
- .weak DMA1_CH2_3_IRQHandler
- .thumb_set DMA1_CH2_3_IRQHandler,Default_Handler
- .weak DMA1_CH4_5_IRQHandler
- .thumb_set DMA1_CH4_5_IRQHandler,Default_Handler
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
- .weak TMR1_BRK_UP_TRG_COM_IRQHandler
- .thumb_set TMR1_BRK_UP_TRG_COM_IRQHandler,Default_Handler
- .weak TMR1_CC_IRQHandler
- .thumb_set TMR1_CC_IRQHandler,Default_Handler
- .weak TMR3_IRQHandler
- .thumb_set TMR3_IRQHandler,Default_Handler
- .weak TMR6_IRQHandler
- .thumb_set TMR6_IRQHandler,Default_Handler
- .weak TMR14_IRQHandler
- .thumb_set TMR14_IRQHandler,Default_Handler
- .weak TMR15_IRQHandler
- .thumb_set TMR15_IRQHandler,Default_Handler
- .weak TMR16_IRQHandler
- .thumb_set TMR16_IRQHandler,Default_Handler
- .weak TMR17_IRQHandler
- .thumb_set TMR17_IRQHandler,Default_Handler
- .weak I2C1_IRQHandler
- .thumb_set I2C1_IRQHandler,Default_Handler
- .weak I2C2_IRQHandler
- .thumb_set I2C2_IRQHandler,Default_Handler
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
5 到此,基本代码和结构调试完整,在虚拟环境中输入scons进行工程构建,应该可以如下,形成二进制文件
最后,也就是第四步,进行调试器下载的配置。这个和keil一样需要选择安装包的配置,首先查看以下是否支持芯片
使用pyord pack list命令
可以看到,本次评测的APM32E030并不在支持的范围内。那么需要安装一下
pyocd pack install
这里显示是安装成功了,但是反复多次,发现并没有安装成功。对照官网的docs介绍,发现新的安装方法已经升级,本地安装不包括在本命令中。
但是可以在每次下载中,都用引用的方式,加载这个安装包,同样可以完成下载的任务。
这个使用的是
pyocd flash xxxx.bin文件的方式。
6 小结
这个过程花费了很长的时间,也在代码库中需要增加很多配置和调试的工作。而且,对应于rtthread的驱动代码,都需要有比较大的修订。因此,具体的步骤就不能容纳在这个帖子中了,但是经过上述4个步骤,可以完成bsp代码构建,为后续更多外部驱动的构建创造比较好的基础。