前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【STM32H7】第12章 ThreadX任务优先级修改及其分配方案

【STM32H7】第12章 ThreadX任务优先级修改及其分配方案

作者头像
Simon223
发布2021-06-24 14:56:01
4200
发布2021-06-24 14:56:01
举报
文章被收录于专栏:安富莱嵌入式技术分享

论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514

第12章 ThreadX任务优先级修改及其分配方案

本章节主要为大家讲解ThreadX任务优先级设置的注意事项、任务优先级的分配方案及其相关的一个例子,内容相对比较简单。

12.1 任务优先级说明

12.2 任务优先级分配方案

12.3 中断优先级和任务优先级的区别

12.4 任务优先级修改函数tx_thread_priority_change

12.5 任务优先级获取函数tx_thread_info_get

12.6 实验例程说明

12.7 总结

12.1 任务优先级说明

下面对ThreadX优先级相关的几个重要知识点进行下说明,这些知识点在以后的使用中务必要掌握牢固。

1、 ThreadX中任务的最大优先级数值是通过tx_port.h文件中的TX_MAX_PRIORITIES进行配置的,用户实际可以使用的优先级范围是0到configMAX_PRIORITIES – 1。比如我们配置此宏定义为32,那么用户可以使用的优先级号是0到31,不包含32,对于这一点,初学者要特别的注意。并且TX_MAX_PRIORITIES的宏定义设置的数值必须是32的整数倍:

#define TX_MAX_PRIORITIES 32

2、 用户配置任务的优先级数值越小,那么此任务的优先级越低(0是最高优先级任务),ThreadX没有空闲任务,如果大家创建空闲任务,需要将其设置为最低优先级。

3、 建议用户配置宏定义TX_MAX_PRIORITIES的最大值不要超过32,即用户任务可以使用的优先级范围是0到31。

  • 因为对于CM内核的移植文件,有专用的汇编指令CLZ(Count Leading Zeros),通过这些指令可以加速算法执行速度。
  • 比通用方式高效。
  • ThreadX查找最高优先级任务是通过定义的32bit数组,

ULONG _tx_thread_preempted_maps[TX_MAX_PRIORITIES/32];

如果TX_MAX_PRIORITIES设置为32,那么仅需一个32bit变量就可以方便记录32不同优先级任务,程序运行时查找最高优先级任务也方便。

4、 ThreadX中处于运行状态的任务永远是当前能够运行的最高优先级任务。下一章节讲解调度器,大家会对这个知识点有一个全面的认识。

12.2 任务优先级分配方案

对于初学者,有时候会纠结任务优先级设置为多少合适,因为任务优先级设置多少是没有标准的。对于这个问题,我们这里为大家推荐一个标准,任务优先级设置推荐方式如下图所示:

  • IRQ任务:IRQ任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先级最高的。
  • 高优先级后台任务:比如按键检测,触摸检测,USB消息处理,串口消息处理等,都可以归为这一类任务。
  • 低优先级的时间片调度任务:比如GUI的界面显示,LED数码管的显示等不需要实时执行的都可以归为这一类任务。实际应用中用户不必拘泥于将这些任务都设置为优先级1的同优先级任务,可以设置多个优先级,只需注意这类任务不需要高实时性。
  • 空闲任务:空闲任务是系统任务。
  • 特别注意:IRQ任务和高优先级任务必须设置为阻塞式(调用消息等待或者延迟等函数即可),只有这样,高优先级任务才会释放CPU的使用权,,从而低优先级任务才有机会得到执行。

这里的优先级分配方案是我们推荐的一种方式,实际项目也可以不采用这种方法。调试出适合项目需求的才是最好的。

12.3 中断优先级和任务优先级区别

部分初学者也容易在这两个概念上面出现问题。简单的说,这两个之间没有任何关系,不管中断的优先级是多少,中断的优先级永远高于任何任务的优先级,即任务在执行的过程中,中断来了就开始执行中断服务程序。

另外对于STM32来说,中断优先级的数值越小,优先级越高。同样,ThreadX的任务优先级也是任务优先级数值越小,任务优先级越高。

12.4 任务优先级修改函数tx_thread_priority_change

函数原型:

代码语言:javascript
复制
UINT tx_thread_priority_change(
    TX_THREAD *thread_ptr,
    UINT new_priority, 
    UINT *old_priority);

函数描述:

函数tx_thread_priority_change用于实现ThreadX任务优先级的修改。

  • 第1个参数thread_ptr是任务句柄,用于区分不同的任务。
  • 第2个参数new_priority是新任务优先级(0 至 (TX_MAX_PRIORITIES-1))。0表示最高优先级。
  • 第3个参数old_priority是任务之前的优先级。

注意事项:

  1. 允许在任务和定时器组里面调用。
  2. 指定任务的抢占阈值自动设置为新的优先级。如果需要新的阈值,则必须在此调用之后使用函数tx_thread_preemption_change。
  3. 第二个参数数值不可大于等于tx_port.h文件中的宏定义:#define TX_MAX_PRIORITIES 配置的数值。

使用举例:

代码语言:javascript
复制
TX_THREAD   AppTaskUserIFTCB;
UINT OldPriority;

/*优先级将其设置为6 */
tx_thread_priority_change(&AppTaskUserIFTCB, 6, &OldPriority);

12.5 任务优先级获取函数tx_thread_info_get

函数原型:

代码语言:javascript
复制
UINT tx_thread_info_get(
    TX_THREAD *thread_ptr, 
    CHAR **name,
    UINT *state, 
    ULONG *run_count,
    UINT *priority,
    UINT *preemption_threshold,
    ULONG *time_slice,
    TX_THREAD **next_thread,
    TX_THREAD **suspended_thread);

函数描述:

函数tx_thread_info_get不仅仅可用于获取ThreadX任务优先级。还可以获取其它相关信息。

1、 第1个参数thread_ptr是任务句柄,用于区分不同的任务。

2、 第2个参数name用于获取任务名。

3、 第3个参数state用于获取任务状态,可能的值如下所示。

  • TX_READY (0x00)
  • TX_COMPLETED (0x01)
  • TX_TERMINATED (0x02)
  • TX_SUSPENDED (0x03)
  • TX_SLEEP (0x04)
  • TX_QUEUE_SUSP (0x05)
  • TX_SEMAPHORE_SUSP (0x06)
  • TX_EVENT_FLAG (0x07)
  • TX_BLOCK_MEMORY (0x08)
  • TX_BYTE_MEMORY (0x09)
  • TX_MUTEX_SUSP (0x0D)

4、 第4个参数run_count用于获取任务运行计数。

5、 第5个参数priority用于获取任务优先级。

6、 第6个参数preemption_threshold用于获取抢占阀值。

7、 第7个参数time_slice用于获取时间片。

8、 第8个参数next_thread指向下一个创建的任务句柄。

9、 第9个参数suspended_thread指向挂起列表中下一个任务句柄。

10、 返回值

  • TX_SUCCESS:(0X00) 成功检索任务信息。
  • TX_THREAD_ERROR:(0x0E) 任务控制指针无效。

注意事项:

  • 可以在初始化阶段,任务,定时器组和中断服务程序里面调用。

使用举例:

代码语言:javascript
复制
TX_THREAD  AppTaskUserIFTCB;
CHAR *name;
UINT state;
ULONG run_count;
UINT priority;
UINT preemption_threshold;
UINT time_slice;
TX_THREAD *next_thread;
TX_THREAD *suspended_thread;
UINT status;

status = tx_thread_info_get(&AppTaskUserIFTCB, 
&name,
                            &state, 
&run_count,
                            &priority, 
&preemption_threshold,
                            &time_slice, 
&next_thread,
&suspended_thread);

12.6 实验例程

配套例子:

V7-3007_ThreadX Task Priority Change

实验目的:

  1. 学习ThreadX的开关中断使用BasePri寄存器方案,这样使用ThreadX可以仅开关受ThreadX管理的中断,从而可以让高优先级中断实现零中断延迟。

实验内容:

1、共创建了如下几个任务,通过按下按键K1可以通过串口或者RTT打印任务堆栈使用情况

===================================================

OS CPU Usage = 1.94%

===================================================

Prio StackSize CurStack MaxStack Taskname

2 4092 383 391 App Task Start

3 4092 543 659 App Msp Pro

4 4092 391 391 App Task UserIF

5 4092 543 659 App Task COM

30 1020 519 519 App Task STAT

31 1020 143 71 App Task IDLE

0 1020 391 391 System Timer Thread

串口软件可以使用SecureCRT或者H7-TOOL RTT查看打印信息。

App Task Start任务 :启动任务,这里用作BSP驱动包处理。

App Task MspPro任务 :消息处理,这里未使用。

App Task UserIF任务 :按键消息处理。

App Task COM任务 :这里用作LED闪烁。

App Task STAT任务 :统计任务

App Task IDLE任务 :空闲任务

System Timer Thread任务:系统定时器任务

2、 (1) 凡是用到printf函数的全部通过函数App_Printf实现。

(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

3、默认上电是通过串口打印信息,如果使用RTT打印信息

(1) MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

#define Enable_RTTViewer 1

(2) Embedded Studio继续使用此宏定义为0, 因为Embedded Studio仅制作了调试状态RTT方式查看。

实验操作:

  1. K1按键按下打印任务执行情况,按下K2和K3设置优先级后,可以按K1查看任务最新优先级是否设置成功。
  2. K2按键按下,设置任务App Task UserIF的优先级为6。
  3. K3按键按下,设置任务App Task UserIF的优先级为4。

串口打印信息方式(AC5,AC6和IAR):

波特率 115200,数据位 8,奇偶校验位无,停止位 1

RTT打印信息方式(AC5,AC6和IAR):

Embedded Studio仅支持调试状态RTT打印:

由于Embedded Studio不支持中文,所以中文部分显示乱码,不用管。

程序执行框图:

12.7 总结

本章节内容相对比较容易,重点是学习任务优先级分配方案,随着后面的学习,初学者需要慢慢积累这方面的经验。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第12章 ThreadX任务优先级修改及其分配方案
    • 12.1 任务优先级说明
      • 12.2 任务优先级分配方案
        • 12.3 中断优先级和任务优先级区别
          • 12.4 任务优先级修改函数tx_thread_priority_change
            • 12.5 任务优先级获取函数tx_thread_info_get
              • 12.6 实验例程
                • 12.7 总结
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档