1.背景
我曾经写了一个PX5 RTOS移植到stm32用stm32cubeMX的保姆级教程,链接如下
https://blog.csdn.net/dqsh06/article/details/150612971?spm=1001.2014.3001.5501
这个PX5 RTOS是个很好的RTOS,但是,它有两个问题,暂时不好克服。哪两个问题呢?
-
代码不开源,尤其是关键代码没有开源,大家不能完整的研究和放心的使用
-
不是免费的license,商用的话,估计要交license费。虽然可以移植成功,并且可以大量使用,但是万一被告的话,搞不好要花很多钱。
所以,要找另外好用的免费的RTOS。
刚刚好,PX5 RTOS的老板和作者,先写了threadX, 据说全球有120亿的设备使用了这个threadX, 而且,在太空车上都是用的这个,那么它的性能和安全性是毫无疑问的。而且,这个threadX还被微软收购了,微软收购了后,就将其改造成azureRTOS, 并且开源了。不仅开源了,而且微软将这个RTOS捐赠给了eclipse基金会,license也变成了MIT license, 大家可以随便使用,随便更改,随便发布,只要保留文件头就行。
所以呢,在我实际开发的项目中,我是用的这个threadX RTOS。
下面是介绍。
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/threadx/overview-threadx.md
既然我实际是用的threadX RTOS, 那么为了振兴中华,我就来写一个threadX RTOS移植到stm32用stm32cubeMX的保姆级教程。
2. threadX RTOS移植到stm32的方法
2.1用stm32cubeMX来生成项目的框架
因为我是用的stm32g474vet6的芯片,所以,我就用这颗芯片来做例子,来配置一个很简单的项目框架。
我这项目是这样的。

实际上要演示这个threadX的移植,配一个IO和一个串口就行了。我这里配置了8个IO口,1个串口,1个RS485口和4个PWM口。外加系统要用的外部晶振接口和SWD调试接口。
一般的配置就不多说了,大家都会,就来专门演示一下,怎么配threadX。
2.2 用stm32cubeMX来配threadX
本身,在cubeMX的中间件和软件包里,应该有【X-CUBE-AZRTOS-G4】这个选项,如果有的话呢,按照这样勾中就行了。

那,如果没有【X-CUBE-AZRTOS-G4】或者【X-CUBE-AZRTOS-G4】是灰的,那么应该怎么办呢?这时需要到【Software Packs】里面去下载。

在这里选择【x-CUBE-AZRTOS-G4】来install.

install完成之后呢,点开这个【x-CUBE-AZRTOS-G4】,在里面勾选【ThreadX->Core】, 我里面是安装的6.2.0的版本,那么就选择这个版本。

这里选好之后,那么在cubeMX的中间件和软件包里,应该有【X-CUBE-AZRTOS-G4】这个选项,那么勾选好【RTOS ThreadX】就行。
接下来是配ThreadX的选项。一般来说,按照我这样来选就OK了。



这里配完了之后,在SYS里面,配【Timebase Source】,不能选SysTick, 要用其他的定时器,用TIM6的很多,但是,我这里是选的TIM7.

到这里,跟threadX相关的配置就完成了,其他的组件,各自可以自己配一下。
在【Project Manager】这里,【Linker Settings】可以改一下,Size稍微改大一点。

好了,可以点【GENERATE CODE】生成代码了。
2.3 相关任务/线程的编写
生成代码之后,就导入到VSCode, 导入之后的目录结构是这样的。

可以看到一些跟threadX相关的目录和文件。
为了方便管理,我将自己生成的线程/任务都放到了my_app.h和my_app.c文件里了。
my_app.h的内容如下:

这里只设计了2个线程,一个叫thread1,一个叫thread_IDLE。堆栈的大小都是1KB, 调度的优先级,一个是28,一个是31。thread_IDLE是IDLE任务,优先级最低,所以给的31。
my_app.c的内容如下:


因为是演示用的,这2个线程写得很简单,thread1就是翻转绿灯,打印Thread1 running. 等50ms。 thread_IDLE就是将电机正转20s, 停5s, 反转20s, 停5s, 打印一个软件版本,等3s。
这2个线程写完了之后呢,要将线程登记到RTOS里面去,登记线程的动作,在文件app_threadx.c里。**同时,还要将堆栈错误的回调函数登记进去,**内容如下:

这些都写完了之后,将相关的文件都加入进CMakeLists.txt,就可以进行编译了。
我的文件编译的结果如下。

反正,线程很少,并且线程里的任务也很轻,所以,所以编译出来很小,只有50kB。
3. 运行结果检验
下载到板子里看看运行的结果怎么样。可以看到板子上的绿灯在闪,串口也确实在打印。用调试器在IDLE线程的3s等待处打个断点,可以看到线程运行的情况和堆栈使用的情况。如下。

可以运行成功了。