0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于极海APM32F4的Azure RTOS ThreadX移植过程分享

Geehy极海半导体 来源:21ic论坛极海半导体专区 2026-04-02 11:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

《极海芯得》系列内容为用户使用极海系列产品的经验总结,均转载自21ic论坛极海半导体专区,全文未作任何修改,未经原文作者授权禁止转载。

前言

最近在玩APM32F407IG的板子,发现官方提供了两个RTOS的demo,FreeRTOSRT-thread。想着APM32F4这么丰富的资源,是不是也可以跑一下ThreadX RTOS看看。想着就动手,本文记录了APM32F4移植ThreadX RTOS的过程,供各位做个参考,权当抛砖引玉了。

1 ThreadX简介

说到RTOS,大家可能会想到FreeRTOS和我们国产的RT-Thread,这两者的知名度都非常高。因为它们商用免费,组件也十分丰富。那ThreadX RTOS可能就“鲜为人知”了,但是在一些行业内,它可是“如雷贯耳”,因为它上过天。O(∩_∩)O哈哈~,下面就简单介绍一些ThreadX。

ThreadX全名是Azure RTOS ThreadX(这里是它的官方网站:https://learn.microsoft.com/zh-cn/azure/rtos/threadx/)。它是专门为深度嵌入式实时 IoT 应用程序设计的。 Azure RTOS ThreadX 提供高级计划、通信、同步、计时器、内存管理和中断管理功能。 此外,Azure RTOS ThreadX 具有许多高级功能,包括 picokernel 体系结构、preemption-threshold 计划、event-chaining、执行分析、性能指标和系统事件跟踪。 Azure RTOS ThreadX 非常易于使用,适用于要求极其苛刻的嵌入式应用程序。 Azure RTOS ThreadX 在各种产品(包括消费者设备、医疗电子设备和工业控制设备)上的部署次数已达数十亿次。(节选自其官网)

为什么说它厉害呢?以上内容也仅是它的应用介绍,这个RTOS的真正厉害之处在于其通过了各项安全认证。以下便是其通过的安全认证:

1. 医疗- FDA510(k),IEC-62304 Class C,IEC-60601,ISO-14971

2. 工业- UL-1998,IEC-61508 SIL 4

3. 运输/铁路- EN50128 SIL 4,BS50128, 49CFR236,IEC-61508

4. 航空航天设备- DO-178B,ED-12B,DO-278

5. 汽车- IEC-61508 ASIL D

6. 核应用- IEC-61508

7. 家电- UL/IEC 60730/60335

其实它之前是收费闭源的,自被微软收购后就开源出来了,而且我们出于学习评估的目的,是不会被限制的。这个RTOS的厉害之处,大家可以查阅他们的官网,这里就不赘述了。

2 源码获取

移植前我们需要准备一些源码

1. APM32F407的工程模板,这个可以在他们官网获取:https://geehy.com/support/apm32?id=311

2. ThreadX源码,这个可以在他们的开源仓库获取:https://github.com/azure-rtos/threadx

需要注意的是,由于我们本次环境使用的是MDK环境,我们需要使用5.30以上的MDK。

3 文件移动与复制

准备好两个源码后,我们需要进行一些文件移动与复制工作以完成我们工程创建的前期准备。

1. 的把ThreadX源码复制至APM32F4xx_SDKMiddlewares文件夹中,准备后续工程文件的使用。

89ffcfb2-2ced-11f1-90a1-92fbcf53809c.png

2. 然后创建ExamplesSysTick的例程副本,重新命名为“ThreadX_Template”。用以作为我们的基础模板,我们将在该模板上建立APM32F4的ThreadX的demo。

3. 复制ThreadX源码中的“portscortex_m4ac5example_build x_initialize_low_level.s”文件至我们的例程源码目录“ThreadX_TemplateThreadX_TemplateSource”并改名为“tx_initialize_low_level_ac5.s”,因为我们后续要改动该文件。这里复制出一个副本出来用于后续修改。

8a58818e-2ced-11f1-90a1-92fbcf53809c.png

4 添加源码

这里我们选择我们刚刚复制的ThreadX_Template的MDK工程中添加相应的源文件。打开MDK工程,在现有目录下添加“ThreadX/ports”,“ThreadX/common”结构,我们添加相应的源码文件。

8ab0e6d0-2ced-11f1-90a1-92fbcf53809c.png

4.1 ThreadX/port结构

在该结构下,我们添加AC5编译器使用的.s文件。

1. 即“threadx-6.2.0_relportscortex_m4ac5src”下的所有 .s 文件。

2. 添加我们刚刚复制出来的tx_initialize_low_level_ac5.s文件。

最终添加文件如下:

8b09d1be-2ced-11f1-90a1-92fbcf53809c.png

4.2 ThreadX/common结构

在该结构下,我们添加ThreadX核心文件。即“threadx-6.2.0_relcommonsrc”下的.c文件。

4.3 Application结构

在原Application结构下添加我们一会要创建的线程文件:tx_application_entry.c。我们一会修改该文件内容。

8b6235fc-2ced-11f1-90a1-92fbcf53809c.png

5 选项卡设置

5.1 编译器设置

由于我们使用的是AC5的相关支持文件,我们这里选择使用AC5编译器,并勾选“Use MicroLIB”以使用printf。

8bbf0b56-2ced-11f1-90a1-92fbcf53809c.png

5.2 C/C++选项卡

在设置中的“C/C++”选项卡下的头文件设置中添加头文件路径。

1. “..........Middlewares hreadx-6.2.0_relportscortex_m4ac5inc”

2. “..........Middlewares hreadx-6.2.0_relcommoninc”

8c184734-2ced-11f1-90a1-92fbcf53809c.png

5.3 汇编头文件包含

在设置中的“Asm”选项卡需要完成以下设置:

1. 头文件设置出添加头文件路径:“..........Middlewares hreadx-6.2.0_relportscortex_m4ac5inc”。

2. 在Misc Controls栏中填写“--cpreproc”。以解决编译.s文件报错问题。

8c70880e-2ced-11f1-90a1-92fbcf53809c.png

6 修改源文件

由于ThreadX需要接管一些中断,并且使用ThreadX我们需要创建一些线程,这里我们要对我们的工程里面的源码进行编辑。

6.1 tx_initialize_low_level_ac5.s

该文件是ThreadX RTOS用于完成处理器的底层初始化,包括:

1. 设置中断向量表

2. 设置用于产生时钟节拍的定位器(Systick)

3. 保存系统栈顶指针给中断程序使用

4. 寻找RAM中首块可用地址传入tx_application_define函数供使用,也就是first_unused_memory指针的值

5. ThreadX在v6版本及以后,在这个文件中接管原有的处理器启动文件。

用于我这里还是想使用原有的处理器启动文件“startup_apm32f40x.s”,所以需要对“tx_initialize_low_level_ac5.s”文件进行一番修改。

1. 将没有用到的标号注释,手动添加_Vectors和__initial_sp标号,分别是APM32F4启动文件中导出的中断向量表和栈顶指针初始值:

8cc8e134-2ced-11f1-90a1-92fbcf53809c.png

2. 设置时钟频率(168Mhz)和时钟节拍(1ms),该值用来初始化Systick定时器

8d21b52a-2ced-11f1-90a1-92fbcf53809c.png

3. 将设置堆栈的代码全部注释(堆栈环境已经在APM32启动文件中设置了):

8d7baba2-2ced-11f1-90a1-92fbcf53809c.png

4. 将 ThreadX 定义的中断向量表全部注释(使用APM32F4启动文件中定义的向量表):

8dd667f4-2ced-11f1-90a1-92fbcf53809c.png

5. 注释ThreadX定义的复位处理程序(使用APM32F4启动文件中的复位程序):

8e2fc01a-2ced-11f1-90a1-92fbcf53809c.png

6. 修改ThreadX底层初始化函数:

8e88dc68-2ced-11f1-90a1-92fbcf53809c.png

7. 注释用不到的函数:

8ee06c08-2ced-11f1-90a1-92fbcf53809c.png

完成以上操作之后便是完成了对tx_initialize_low_level_ac5.s文件的修改。

6.2 apm32f4xx_int.c

由于ThreadX接管了部分中断,apm32f4xx_int.c里面的一些中断就必须进行屏蔽(或删除)处理,以免编译器报重复定义的错误。

即屏蔽PendSV_Handler和SysTick_Handler函数。

8f39aac0-2ced-11f1-90a1-92fbcf53809c.png

6.3 tx_application_entry.c

在该文件中我们创建两个线程并运行,需要使用到ThreadX的一些知识,这里就不赘述,直接上源码。

#include

#include"Board.h"

#include"tx_api.h"

#include"main.h"

#defineTX_APPLICATION1_PRIO 3

#defineTX_APPLICATION1_STACK_SIZE 1024

static TX_THREAD tx_application1;

uint8_t tx_application1_stack[TX_APPLICATION1_STACK_SIZE];

#defineTX_APPLICATION2_PRIO 2

#defineTX_APPLICATION2_STACK_SIZE 1024

static TX_THREAD tx_application2;

uint8_t tx_application2_stack[TX_APPLICATION2_STACK_SIZE];

void my_tx_application1_entry(ULONG thread_input)

{

/* Enter into a forever loop. */

while(1)

{

printf("ThreadX 1 application running... ");

APM_MINI_LEDToggle(LED2);

/* Sleep for 1500 tick. */

tx_thread_sleep(1500);

}

}

void my_tx_application2_entry(ULONG thread_input)

{

/* Enter into a forever loop. */

while(1)

{

printf("ThreadX 2 application running... ");

APM_MINI_LEDToggle(LED3);

/* Sleep for 1000 tick. */

tx_thread_sleep(1000);

}

}

void tx_application_define(void *first_unused_memory)

{

/* Create thread */

tx_thread_create(&tx_application1, "thread 1", my_tx_application1_entry, 0, &tx_application1_stack[0], TX_APPLICATION1_STACK_SIZE, TX_APPLICATION1_PRIO, TX_APPLICATION1_PRIO, TX_NO_TIME_SLICE, TX_AUTO_START);

tx_thread_create(&tx_application2, "thread 2", my_tx_application2_entry, 0, &tx_application2_stack[0], TX_APPLICATION2_STACK_SIZE, TX_APPLICATION2_PRIO, TX_APPLICATION2_PRIO, TX_NO_TIME_SLICE, TX_AUTO_START);

}

6.4 main.c

我们需要在main函数中初始化相应的外设(LED、USART)后启动ThreadX。由于在tx_application_entry.c中使用了printf,我们还需要对printf进行重定向。并删除之前SysTick工程中一些操作,这里也闲话少叙,直接上源码。

/* Includes */

#include"main.h"

#include"Board.h"

#include

#include"tx_api.h"

/** @addtogroup Examples

@{

*/

/** @addtogroup SysTick_TimeBase

@{

*/

/** @addtogroup SysTick_TimeBase_Macros Macros

@{

*/

/** printf using USART1 */

#defineDEBUG_USART USART1

/**@} end of group SysTick_TimeBase_Macros*/

/** @defgroup SysTick_TimeBase_Functions Functions

@{

*/

/*!

* [url=home.php?mod=space&uid=247401]@brief[/url] Main program

*

* @param None

*

* @retval None

*/

int main(void)

{

USART_Config_T usartConfigStruct;

usartConfigStruct.baudRate = 115200;

usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;

usartConfigStruct.mode = USART_MODE_TX;

usartConfigStruct.parity = USART_PARITY_NONE;

usartConfigStruct.stopBits = USART_STOP_BIT_1;

usartConfigStruct.wordLength = USART_WORD_LEN_8B;

APM_MINI_COMInit(COM1, &usartConfigStruct);

APM_MINI_LEDInit(LED2);

APM_MINI_LEDInit(LED3);

printf("ThreadX RTOS on APM32F407 IG MINI Board ");

tx_kernel_enter();

while (1)

{

}

}

/*!

* [url=home.php?mod=space&uid=247401]@brief[/url] Redirect C Library function printf to serial port.

* After Redirection, you can use printf function.

*

* @param ch: The characters that need to be send.

*

* @param *f: pointer to a FILE that can recording all information

* needed to control a stream

*

* @retval The characters that need to be send.

*/

int fputc(int ch, FILE *f)

{

/** send a byte of data to the serial port */

USART_TxData(DEBUG_USART,(uint8_t)ch);

/** wait for the data to be send */

while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);

return (ch);

}

7 编译与下载

最后我们编译工程,编译结果如下。

8f9128ea-2ced-11f1-90a1-92fbcf53809c.png

然后我们下载程序进板子后,LED2和LED3闪烁,若连接串口可以查看到如下信息:

8fe772b8-2ced-11f1-90a1-92fbcf53809c.png

注:文章作者在原帖中提供了代码文件,有需要请至原文21ic论坛

原文地址:https://bbs.21ic.com/icview-3271244-1-1.html?_dsign=d8e4a5a2

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5209

    文章

    20622

    浏览量

    336753
  • threadx
    +关注

    关注

    0

    文章

    19

    浏览量

    14491
  • 移植
    +关注

    关注

    1

    文章

    417

    浏览量

    29523
  • RTOS
    +关注

    关注

    25

    文章

    868

    浏览量

    123204

原文标题:极海芯得 EP.78 | 基于APM32F4的Azure RTOS ThreadX 移植过程分享(基于AC5)

文章出处:【微信号:geehysemi,微信公众号:Geehy极海半导体】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Azure RTOS ThreadX的抢占任务应用实现与调试

    Azure RTOS ThreadX 是 Microsoft 提供的高级工业级实时操作系统 (RTOS)。它是专门为深度嵌入式实时 IoT 应用程序设计的。
    发表于 07-12 11:17 3142次阅读

    使用MM32F3270基于Azure RTOS定时器组的应用

    Azure RTOS ThreadX 是 Microsoft 提供的高级工业级实时操作系统 (RTOS)。它是专门为深度嵌入式实时 IoT 应用程序设计的。
    的头像 发表于 12-29 17:26 2857次阅读

    如何在Eclipse ThreadX RTOS中集成SystemView

    SEGGER实时软件分析工具SystemView已经在ThreadX v6.4.2上进行了测试。SystemView从v3.60c版本支持Eclipse ThreadXAzure RTOS
    的头像 发表于 05-06 17:11 1593次阅读

    基于MM32 MCU的OS移植与应用——ThreadX开篇

    /MM32F013x_Lib_Samples_V1.03.zip移植Azure RTOS ThreadX01功能验证在eMiniBoard
    发表于 11-09 10:30

    IDE在尝试运行或调试sample_threadx示例时,显示程序文件不存在怎么解决?

    sample_threadx 示例时遇到此问题。程序文件不存在/Users/venkat/work/pp/azure_rtos/stm32f746g-disco/stm32cubeide
    发表于 01-11 07:23

    使用MM32F3270基于Azure RTOS定时器组的应用

    各种产品(包括消费者设备、医疗电子设备和工业控制设备)上的部署次数已达数十亿次。在前文描述移植基本内核的基础上,该应用手册描述了MM32F3270系列MCU结合Azure RTOS
    发表于 02-07 14:18

    RT-Thread已经全面支持APM32F1系列MCU

    近日,RT-Thread 和其高级会员合作伙伴半导体宣布:正式完成APM32F4系列MCU的RT-Thread 物联网操作系统适配及RT-Thread Studio IDE的支持。
    发表于 08-30 09:45 1767次阅读

    适用于Arduino 101的Azure RTOS ThreadX线程

    电子发烧友网站提供《适用于Arduino 101的Azure RTOS ThreadX线程.zip》资料免费下载
    发表于 10-18 09:46 0次下载
    适用于Arduino 101的<b class='flag-5'>Azure</b> <b class='flag-5'>RTOS</b> <b class='flag-5'>ThreadX</b>线程

    AN1088_APM32F4xx系列ETH移植LWIP

    AN1088_APM32F4xx系列ETH移植LWIP
    发表于 11-09 21:03 0次下载
    AN1088_<b class='flag-5'>APM32F4</b>xx系列ETH<b class='flag-5'>移植</b>LWIP

    AN1089_APM32F407_RTOS例程

    AN1089_APM32F407_RTOS例程
    发表于 11-09 21:03 2次下载
    AN1089_<b class='flag-5'>APM32F407_RTOS</b>例程

    DB4560_STM32F4 系列用于 STM32Cube 的 Azure® RTOS 软件扩展

    DB4560_STM32F4 系列用于 STM32Cube 的 Azure® RTOS 软件扩展
    发表于 11-23 08:30 0次下载
    DB4560_STM32<b class='flag-5'>F4</b> 系列用于 STM32Cube 的 <b class='flag-5'>Azure</b>® <b class='flag-5'>RTOS</b> 软件扩展

    使用MM32F3270基于Azure RTOS信号量的应用

    Azure RTOS ThreadX 是 Microsoft 提供的高级工业级实时操作系统 (RTOS)。它是专门为深度嵌入式实时 IoT 应用程序设计的。
    的头像 发表于 12-16 09:23 2162次阅读

    使用MM32F3270基于Azure RTOS动态内存管理的应用

    Azure RTOS ThreadX 是 Microsoft 提供的高级工业级实时操作系统 (RTOS)。它是专门为深度嵌入式实时 IoT 应用程序设计的。
    的头像 发表于 12-23 11:01 2074次阅读

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植
    的头像 发表于 10-27 10:15 1679次阅读
    使用MM32<b class='flag-5'>F</b>3270基于<b class='flag-5'>Azure</b> <b class='flag-5'>RTOS</b> (<b class='flag-5'>ThreadX</b>) 的<b class='flag-5'>移植</b>

    微软开源Azure RTOS,并更名为Eclipse ThreadX

    Azure RTOS 是一个带有 ThreadX 实时操作系统(RTOS)的嵌入式开发套件。ThreadX 是一个普及性很高的小型
    的头像 发表于 12-01 16:17 1595次阅读
    微软开源<b class='flag-5'>Azure</b> <b class='flag-5'>RTOS</b>,并更名为Eclipse <b class='flag-5'>ThreadX</b>