当MCU的处理能力和内存组够用时,项目的实时安全性不是那么苛刻,任务又可能处于多个循环运行状态时,可以考虑为MCU移植一个RTOS系统,满足各个子任务雨露均霑的效果,让MCU化身时间管理大师。
常用的RTOS有著名的Free RTOS,国产的RT_Thread等,当然熟悉的任务调度的话可以自己手写一个任务调度器。我之前使用的是RT_Thread,开始基本上提出需求,芯片供应商负责移植。自从换了一家小公司之后就不再有压榨供应商这个说法,基本上都要自己来,在这里记录一下前段时间搞的基于stm32 的RT_Thread工程移植。
RT_Thread提供了调试和代码生成工具RT-Thread Studio,IDE风格类Eclipse,不过比其他的很多使用Eclipse框架的IDE好用很多,软件完成度很高。
首先配置工作空间,新建RT-Threa 项目,
选择工程位置、系统版本、芯片系列、调试工具就好。确定之后就生成了一个RT-Thread的工程,直接点击编译,不出意外编译通过,就可以连接开发板和调试器进行下载调试了。我选择的芯片的stm32F407VET6,下载的芯片SDK是0.2.3的,直接编译时串口驱动的函数报错,我的解决方案是吧报错的那一段switch代码屏蔽掉,好像正经的解决方法是使用0.2.2 的SDk或高版本的RT-Thread,总之问题不大。
Studio创建的初始工程所有的芯片外设都是默认的,实际项目中我们需要定制芯片资源,因此底层配置可能要自行修改,ST公司提供的芯片配置工具STM32CubeMx可以与RT-Thread Studio联合开发。
点击左侧文件树的CubeMX Settings,电脑提前安装了CubeMX的话就会弹出对应的CubeMX工程配置界面。
根据项目需求配置工程即可,在最后一部点击生成代码时要注意勾选生成独立的.c和.h文件。
生成代码之后返回Studio再次编译工程,此时回多出一个文件夹cubemx而且,此时应该会报错,因为cubemx中的代码文件没有更新到工程。在cubemx文件夹新建一个SConscript文件,键入配置信息(这里是从另外一片帖子复制的,具体是哪忘了哈哈):
import os
#引入os模块
from building import *
#导入building的所有模块
cwd = GetCurrentDir()
#获取获取当前路径,并保存至变量cwd
src = Glob('*.c')
#获取当前目录下的所有 C 文件,并保存至src变量
# add cubemx drivers
#由于RT-Thread工程中存在部分相同函数文件,所以对src重新赋值
#文件中的stm32g4xx_it.c 、 system_stm32g4xx.c不加入构建
#其余文件按相同格式填写到下述括号内
src = Split('''
Src/stm32g4xx_hal_msp.c
Src/main.c
Src/gpio.c
Src/usart.c
''')
#创建路径列表,并保存至path中
path = [cwd]
path += [cwd + '/Inc']
#这是 RT-Thread 基于 SCons 扩展的一个方法(函数)。
group = DefineGroup('cubemx', src, depend = [''], CPPPATH = path)
Return('group')
配置代码中需要注意的是在src项中把需要用到的文件名称加进去,漏掉的话依然会报错。
在新建的文件上右键->更新软件包,再次编译。错误少了很多,但是还有,因为有两个main函数,把cubemx里面那个weak掉或直接删掉就可以,删除之前记得把里面的代码拷贝出来到自己的main函数中。
完成上述配置之后再次编译工程应该不会报错了,但是还有一些配置工作:把cubemx里mian.c的void SystemClock_Config(void)函数体复制到drv_clk.c 的void system_clock_config(int target_freq_mhz)函数中覆盖之前的语句 ,至此RT-Thread移植完成,可以下载到开发板观察实验现象,终端信息会通过配置工程开始选择的串口打印出来。
在RTOS工程内部修改时钟源,在board.h修改clock config
/*-------------------------- CLOCK CONFIG BEGIN --------------------------*/
#define BSP_CLOCK_SOURCE ("HSE") //外部告诉时钟
#define BSP_CLOCK_SOURCE_FREQ_MHZ ((int32_t)8) //时钟频率
#define BSP_CLOCK_SYSTEM_FREQ_MHZ ((int32_t)72) //倍频后的频率