1.新建stm32工程
用mx图形界面配置好将要用的串口,内部外部时钟,本例使用了外部高速时钟(HSE)以及外部低速时钟(LSE)。打开调试(SYS中的Debug选项选Serial Wire), 配置好时钟树,再点保存生成代码(不要配置project中的选项)。
2.rtthread源码拷贝
将rtthread源码放在一个文件夹(名字随意,本例取名rtthread)后添加到当前工程主目录下。
删除除了bsp、components、include、libcpu、src这5个文件夹外其他所有文件及文件夹。 (非必须,但如此做就得在工程里做配置,麻烦,所以直接删除方便点,以下同理)
删除libcpu文件夹下除了arm的所有文件及文件夹。
将bsp/stm32/libraries/HAL_Drivers文件夹; 以及bsp/stm32/libraries/templates/stm32f4xx文件夹下(根据芯片选择,f0,f10,f2,f4.....)的applications、board文件夹以及rtconfig.h文件拷贝到bsp目录下并删除其余内容。之后再将board文件下的CubeMX_Config文件夹删除。
3.cubeIDE工程配置
回到cubeIDE,右键当前工程选择Refresh(刷新),就可以看到刚刚添加的rtthread目录了。
右键当前工程,选择Properties,左侧选择C/C++General->Paths and Symbols,在右侧includes中把以头文件下路径添加进去:
rtthread/bsp
rtthread/bsp/HAL_Drivers
rtthread/bsp/HAL_Drivers/drv_flash
rtthread/bsp/HAL_Drivers/config
rtthread/bsp/HAL_Drivers/config/f4
rtthread/bsp/board
rtthread/components/drivers/include
rtthread/components/drivers/include/ipc
rtthread/components/drivers/include/drivers
rtthread/components/libc/compilers/minilibc
rtthread/components/finsh
rtthread/include
rtthread/libcpu/arm/common
rtthread/libcpu/arm/cortex-m4
头文件路径添加完毕后继续选择当前菜单下右边的Source Location(与includes同级的菜单选项),将我们的rtthread文件夹添加(Add Folder)进去。
点击右下角Apply,应用设置。
回到左侧窗口,选择C/C++Build->Settings,再在右侧窗口选择Tool Settings,在MCU Settings选项中将Runtime library改为Standard C,另外如果想要串口printf(需要另外编写_write函数)打印出浮点数,则需要将下面的Use float with printf from newlib-nano(-u _printf_float)勾上,scanf同理
MCU Post build outputs 中设置编译产生的文件(bin,hex.....)
MCU GCC Assembler->Miscellaneous(杂项)中添加-Wa,-mimplicit-it=thumb(gcc编译参数,不加会报thumb conditional instruction should be in IT block......错误)
MCU GCC Linker->General中把Linker Script(链接脚本)改成rtthread/bsp/board/linker_scripts/link.lds文件(默认是cubeMX自动生成的STM32Fxxxxx_FLASH.ld)。这里必须在弹出的窗口中右下角将后缀名选择“ld”,改为“.”(所有文件),否则将看不到link.lds文件。
最后点击右下角Apply and Close保存设置。
4源文件配置
将rtthread/libcpu/arm目录下的除了common跟cortex-m4(根据芯片选择,m0,m3,m4.....)文件夹的 其他全部文件夹右键选择Resource Configurations->Exclude from build...弹出窗口中选择Select All,点击ok(此时这些选中的文件夹上会出现一个斜杠并且变成灰色,这样这些文件夹就不会被编译了,c文件也可以这样操作,以此来屏蔽一些当前用不到的文件但又不想删除)。
按照此操作再将以下文件夹及部分c文件屏蔽
文件夹:
rtthread/components/cplusplus
rtthread/components/dfs
rtthread/components/lwp
rtthread/components/net
rtthread/components/utilities
rtthread/components/vbus
rtthread/components/vmm
rtthread/components/libc/aio
rtthread/components/libc/libdl
rtthread/components/libc/mmap
rtthread/components/libc/pthreads
rtthread/components/libc/signal
rtthread/components/libc/termios
rtthread/components/libc/time
rtthread/components/libc/compilers/armlibc
rtthread/components/libc/compilers/common
rtthread/components/libc/compilers/dlib
rtthread/components/libc/compilers/newlib
rtthread/components/drivers/audio
rtthread/components/drivers/can
rtthread/components/drivers/cputime
rtthread/components/drivers/hwcrypto
rtthread/components/drivers/hwtimer
rtthread/components/drivers/i2c
rtthread/components/drivers/mtd
rtthread/components/drivers/pm
rtthread/components/drivers/rtc
rtthread/components/drivers/sdio
rtthread/components/drivers/sensors
rtthread/components/drivers/spi
rtthread/components/drivers/touch
rtthread/components/drivers/usb
rtthread/components/drivers/watchdog
rtthread/components/drivers/wlan
需要屏蔽的c文件:
rtthread/bsp/HAL_Drivers文件夹下的:drv_adc.c、drv_can.c、drv_crypto.c、drv_eth.c、drv_hwtimer.c、drv_lcd_mipi.c、drv_lcd.c、drv_lptim.c、drv_pm.c、drv_pulse_encoder.c、drv_qspi.c、drv_rtc.c、drv_sdram.c、drv_soft_i2c、drv_spi.c、drv_usbd.c、drv_usbh.c、drv_wdt.c
rtthread/bsp/HAL_Drivers/drv_flash文件夹下的:drv_flash_f0.c、drv_flash_f1.c、drv_flash_f2.c、drv_flash_f7.c、drv_flash_l4.c
rtthread/components/drivers/misc文件夹下的:adc.c、pulse_encoder.c、rt_drv_pwm.c、rt_inputcapture.c
rtthread/components/finsh文件夹下的:finsh_compiler.c、finsh_error.c、finsh_heap.c、finsh_init.c、finsh_node.c、finsh_ops.c、finsh_parser.c、finsh_token.c、finsh_var.c、finsh_vm.c、msh_file.c、symbol.c
其他文件
rtthread/libcpu/arm/common文件夹下的:divsi3.S(其他编译环境所需的启动文件)
rtthread/libcpu/arm/cortex-m4文件夹下的:context_iar.S、context_rvds.S(其他编译环境所需的启动文件)
此外还需屏蔽当前工程目录下的Core/Src文件夹下的:main.c、syscalls.c、sysmem.c、stm32f4xx_it.c(这个文件可以不屏蔽,但是如此的话其中的HardFault_Handler(void)、PendSV_Handler(void)、SysTick_Handler(void)这三个中断函数必须注释掉,因为rtthread中已经实现,为了避免每次MX生成一次代码就要注释一次的麻烦,可以直接屏蔽此文件, 有需要再添加)
5.修改源文件
Core/startup/startup_stm32f429igtx.s(stm32启动文件,cubeMX自动生成的,不同芯片名称不同):
其中的有段代码(如下):
将其中的 bl __libc_init_array 注释掉,并将bl main 改为bl entry。如下:
当然也可以选择用rtthread官方给出的启动文件而不用这个启动文件,官方文件位置在:源码包(rtthread)/bsp/stm32/libraries/STM32F4xx_HAL/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc文件夹下。
将cubeMX生成的Core/src/main.c文件中的void SystemClock_Config(void)函数拷贝替换掉 rtthread/bsp/board/board.c中的同名函数。
rtthread/bsp/board/board.h中的STM32_FLASH_SIZE 改为自己芯片的flash大小,以及STM32_SRAM_SIZE 改为自己芯片RAM的大小(单位kB),例如本例是stm32f429igt6(flash:1024kB RAM:192kB),更改为如下:
rtthread/bsp/board/linker_scripts/link.lds链接脚本中的芯片容量也做对应修改,本例更改为如下:
rtthread/bsp/rtconfig.h (rtthread的配置文件),将其中的:
#define RT_CONSOLE_DEVICE_NAME "uart1"(控制台所用的串口号)改为自己所用的串口,本例为USART3,改为如下:
#define RT_CONSOLE_DEVICE_NAME "uart3"
#define SOC_SERIES_STM32F4 (芯片系列)改为自己芯片的系列(F0,F1......),本列采用F429,故不更改
#define SOC_STM32F407ZG(芯片型号)改为自己芯片型号,本例采用STM32F429IGT6,故改为:
#define SOC_STM32F429IG
#define BSP_USING_UART1 (所用串口)改为自己所用的串口,本例采用的USART3,故改为:
#define BSP_USING_UART3
更改rtthread/bsp/applications/main.c:将其中的LED引脚更改为自己板子上的引脚,本例采用的PC5,应做如下更改:
#define LED0_PIN GET_PIN(B, 1) 改为:
#define LED0_PIN GET_PIN(C, 5)
以上移植工作(只启用了最简单的控制台finsh和GPIO)已做完,点击菜单栏小锤子(编译)即可。
6.调试
点击菜单栏小虫子(debug)右侧的下拉箭头,选择debug configurations,在弹出的窗口中,双击左侧的STM32 Cortex-M C/C++ Application选项(新建configuration),再将右侧Startup下的Set breakpoint at : main改为Set breakpoint at : entry (程序debug开始的时候停在何处,为了弄清rtthread运行过程,否则可以不更改),
至此就可以烧录调试了。
温馨提示:rtthread官方给的CMSIS文件夹下比cubeMX自动生成的多一个RTOS文件夹,其中有一个文件cmsis.h,此文件在当前例程中没有用,所以没有添加,但不清楚在启用更多设备(LCD,SDRAM,SPI.....)情况下是否有用。