ThreadX 再介绍
一些此前的内容可见最全认证 RTOS——azure_threadX 移植教程 - 土星环的基地。
由于 threadX 捐赠给 eclipse 基金会,现在已经不叫 azure_threadX 改为 eclipse_threadX 。
最近我的新的 CMAKE 工程结构逐渐趋于稳定和完善,也是时候介绍一下相对现代的移植方式了。过去使用的 IDE(点名批评KEIL) 过于落后,通常只能手动指定所有的源码文件和 includPath,而 CMAKE 则可以提供更加自由更加自动化的方式。
在以前的博文里提到过,“大多数好的 c 语言库都会提供搜集了所有源码文件的 CMakeLists.txt”,而优秀的库会提供包括编译条件和按照编译条件选择源码文件的 CMakeLists.txt。所以在一个 CMAKE 项目中引入 threadX 软件包将非常方便。
前提条件
首先读者应该有基本的 CMAKE 认知以及简单的实践经验,移植前先构建一个能基础闪灯的工程并且烧录成功,保证闪灯的频率大致与预想相同。
- 对于 CMAKE 子目录和 project 的概念有基本的理解
- 完成过一个 CMAKE 项目的搭建和编译
没有这方面知识的可以先学习CMAKE 扫盲 - 土星环的基地。
大致思路
threadX 软件包已经提供了几乎最全面的支持。我们只要将整个代码库弄进工程,少量给出几个参数,随后以其为子目录,再自行添加链接库,就算是完成移植了。
将代码库弄进工程
对于初学者或者不想要使用 git 管理代码的工程师,只要将这个代码库完全地下载和复制到项目中即可。
例如我的这个项目,使用 6_Rtos 文件夹存放 RTOS 相关的源码,threadx-master 文件夹就是直接下载源码包并且解压得到的。当然如果读者熟悉 git 子模块或者 CMAKE 在线导入的方法,也是极好的,我这里只做尽可能简单的最小系统搭建。

image-20250526145554852
在顶层的 CMakeLists.txt 中使用这样的语句,即可引入 threadX。我这里的顶层 CMakeLists.txt 在上一层的 src 文件夹下,反正依据 CMAKE 项目结构,需要比解压的源码包更上层。
其中 THREADX_ARCH 指定了内核型号,THREADX_TOOLCHAIN 指定了编译器型号,这两个参数将由 threadx-master 中的 CMAKE 脚本自动选定 port 文件,详细可以自行研究 threadX 库的根 CMakeLists.txt 。
添加链接库
Note
再次提醒,读者必须完成过一个 CMAKE 项目的搭建和编译,否则以下的 CMAKE 基础脚本写法也不会懂的
由于我们在顶层 CMakeLists.txt 引入的子目录,所以需要在顶层项目中添加链接库。使用类似如下的语句
如果希望使用经典的 tx_user.h 配置文件。那么还需要在引入子目录前使用类似如下的语句。预先设置一个 TX_USER_FILE 参数用于导向我们自己创建的 tx_user.h 配置文件,而库内的 cmake 脚本会依据 TX_USER_FILE 参数是否被设置进行不同的操作,可以自行了解。
一个相对完整的顶层 CMakeLists.txt 如下
一些芯片级的支持
中断部分
首先 threadX 会接管 SysTick_Handler 和 PendSV_Handler 两个中断,所以需要将原工程中的这两个中断函数的定义给注释掉。
其次这些中断的实现,threadx 不会直接地在库中引入,而是需要自己实现。
推荐是创建一个 tx_initialize_low_level.S 文件在自己工程的其他文件夹,然后在 threadX 软件包中找一个合适的同名文件(不同架构都有示例),将这个文件复制出来到自己创建的里面。不要直接引入他的示例,会破坏源码包的独立性。
然后依据编译报错修改自己的文件,主要是链接符号的匹配问题,例如中断向量表的名字。
以下是一个简单的示例。其实讲道理是所有他给出的中断函数都应该进行替换屏蔽,但是要修改自己的中断函数名没必要,只屏蔽必要的两个中断函数由其接管就好,其他函数也没什么很大的意义。
注意修改其中的 SYSTEM_CLOCK、 SYSTICK_CYCLES 两个参数,与主频和期望的任务时间分辨力匹配。例如我这个文件中,主频是600M,tx_thread_sleep(1) 期望是 1ms。
GNU 部分
gcc 编译链与 AC 编译器的 MicroLib 不同,需要自己实现许多系统级接口。一个经典的 io 函数是 printf ,如果不实现接口,编译链是无法通过的。在项目中增加以下两个文件就好,当然我给出的源码并没有 printf 的接口支持。
printf 建议使用私有实现,比如以下的库。