基于STM32F4XX+RTOS的多线程程序开发及线程性能分析与状态查看

前言

STM32F4xx系列是ST公司高性价比产品,由于可以很方便的移植RTX-RTOS系统,在多线程程序开发上有很多的优势,但是在多线程并发情况下,如何合理的进行线程切换与调度,充分发挥芯片性能,解决线程间冲突,是迫切需要解决的问题。MDK5.25版本以后提供了新的System analyzer,可以方便的跟踪和统计线程的工作情况,由于网上资料较少,花了一天时间终于弄明白了System analyzer的使用,共享给大家,个人的经验,高手请绕路。

实现

下面是基于HAL库的多线程工程建立以及多线程程序实现过程,每一步基本上都有截图和说明。
工程使用STM32CubeMx生成,没有STM32CubeMx软件的上官网下载,STM32CubeMx的优点太多了,将繁琐的芯片配置过程图形化了,强烈推荐。
新建CUBEMX工程

  1. 打开软件,建立工程,选择一款芯片,本例选择STM32F405ZGTx,引脚配置如下图,首先配置调试端口为SWD,并切换系统时钟基准为任意一个TIM,这是由于RTOS要特殊使用SysTick时钟,此处选择了TIM14;
    在这里插入图片描述
  2. 配置RCC为外部时钟,虽然芯片内部时钟也能工作,但是误差可能有些大,还是外部时钟比较保险,可以看到配置完后,右边芯片图上时钟引脚和调试口引脚已经是绿色的了;在这里插入图片描述
  3. 本例使用了两个LED作为输出显示,这两个LED连接在PF9和PF10两个IO上,因此配置这量IO为输出,具体配置方法为在芯片图中的具体IO管脚上点鼠标左键,选择GPIO_Outpu即可,为了方便使用,在IO管脚上点鼠标右键,设置UserLabel为LED1和LED2;
    在这里插入图片描述
    在这里插入图片描述
  4. 配置完后可以在左边列表中看到这两个IO,可以进一步设置上拉下拉,输出模式什么的,本例不用上下拉,是推挽输出;
    在这里插入图片描述
  5. 切换到芯片的Clock Configuration配置系统时钟,由于使用了外部晶振,可以将芯片调整到最快工作频率,注意不要有红色的错误即可;

在这里插入图片描述
6. 切换到ProjectManager页配置工程属性,这里有两个需要注意的地方,一个是Project下面的Toolchain/IDE和版本,要按照安装的IDE设置,由于本例使用了MDK-ARM5.27,故如图设置即可,另一个是Code Generator页的Generated files下面的第一个选项决定了是否单独产生.c/.h文件,选上有各种设备都单独生成.c/.h,而不是生成在一起;
在这里插入图片描述
在这里插入图片描述
7. 保存工程后,点击最后的GENERATE CODE生成工程代码,主要工程位置在ProjectManager中指定了。生成代码后会提示是否打开工程,当然要打开了;
在这里插入图片描述
8. 打开工程如下图所示,可以展开各个文件夹看一下文件组织结构,并编译工程,工程很干净,初始化已经完成了,LED引脚定义在main.h中;在这里插入图片描述

  1. 接下来添加RTOS支持,点击工具栏中的RTE按钮,如果找不到看下图中倒数第二个;
    在这里插入图片描述
  2. RTE是运行环境管理,可以很方便的加入各种组件,但是和STM32CubeMx有一些冲突,这也是为什么在STM32CubeMx中配置时没有选择Middleware中的FreeRTOS的缘故,FreeRTOS和CMSIS-RTOS还是有很大区别的,选择如下图中的组件,注意KeilRTX5一定要改成Source,就是加入源代码而不是直接使用库文件。主要是要选择Compiler下面的EventRecorder和KeilRTX5,如果有警告信息,可以点击左下角的Resolve按钮自动添加缺少的子组件;在这里插入图片描述
  3. 选择完成,点击OK后工程目录如下图所示,有三个绿色的运行环境,此时编译会出一大堆错误,是重复引用导致的;

在这里插入图片描述
12. 下面的工作是去除重复引用,在Device上点右键,选择Options for Component Class或者按Alt+F7,去掉Include in target build前的勾,在编译时不编译即可;在这里插入图片描述

在这里插入图片描述
不再包括Device的启动代码的工程视图如下所示,Device部分变成灰色了,而且文件名上有一个红色的禁止编译符号;
在这里插入图片描述
13. 然后再注释掉stm32f4xx_it.c文件中的三个中断处理函数SVC_Handler,PendSV_Handler和SysTick_Handler,如下面三个图所示,再编译就没有错误了;在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
14. 在main.h中加入头文件,增加对RTOS2的引用,注意头文件位置,要写到USER CODE中,以便以后用STM32CubeMx更新代码时不破坏自己的代码;
#include “RTE_Components.h” // Component selection
#include “cmsis_os2.h” // ::CMSIS:RTOS2

在这里插入图片描述
15. 在main.c中增加两个线程句柄,用于线程操作,定义两个函数void thrLED1(void *argument)和void thrLED2(void *argument),这两个函数的具体实现放在USER CODE BEGIN 4后面,声明放在USER CODE BEGIN PFP后面,这两个线程就是我们需要使用的工作线程了;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
另外再声明一个函数void app_main(void *argument)作为主线程,也将声明和实现分别放在USER CODE BEGIN PFP和USER CODE BEGIN 4部分;
在这里插入图片描述在这里插入图片描述
16. 在USER CODE BEGIN 2部分调用OS的初始化和创建主线程的代码如下:
在这里插入图片描述
17. 为了让线程监视起作用,还需要设置RTX_Config.h文件,在工程中CMSIS下找到RTX_Config.h,点击编辑窗口的左下角Configuartion Wizard视图,切换到配置向导,这个配置向导就是将文件中的定义用图形的方式显示出来,方便使用;
在这里插入图片描述

在这里插入图片描述
18. 需要配置的参数主要是Event Recorder Configuration下面的Global Initialization,一定要勾选上,如下图所示即可;
19. 再勾选上所有的RTOS事件;
在这里插入图片描述

  1. 最后设置仿真器为SW模式,一定要以最高速度运行,否则会很卡;

在这里插入图片描述

  1. 编译下载程序,全速运行;

在这里插入图片描述

  1. 打开System Analyzer窗口;

在这里插入图片描述

  1. 可以看到线程的工作情况了;

在这里插入图片描述
最上面是事件记录器,TRX5展开有下面的线程运行情况,可以查看什么时候线程切换了,点击线程名字的右键还有统计信息,标明了每个线程的CPU占用率;

在这里插入图片描述
24. 运行效果:两个LED分别以不同的闪烁频率闪烁,两个led线程分别是thrLED1运行1次,thrLED2运行5次。

结束语

有了这个分析器,可以极大的方便我们调试线程,了解RTOS的工作过程,多线程程序工作也非常方便的减少了并发程序开发的工作量,比跑裸机程序方便多了,以上一点个人使用经验,仅供借鉴参考。

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值