zoukankan      html  css  js  c++  java
  • 【STM32H7】第12章 ThreadX任务优先级修改及其分配方案

    论坛原始地址(持续更新):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

    函数原型:

    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 配置的数值。

    使用举例:

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

    12.5 任务优先级获取函数tx_thread_info_get

    函数原型:

    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) 任务控制指针无效。

    注意事项:

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

    使用举例:

    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 总结

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

    微信公众号:armfly_com 安富莱论坛:www.armbbs.cn 安富莱淘宝:https://armfly.taobao.com
  • 相关阅读:
    java基础学习总结——GUI编程(二)
    003_Java笔记3:Eclipse添加jar包
    001_Eclipse编写第一个Java程序
    002_JavaSE笔记:单例模式
    001_IntelliJ IDEA详细安装步骤
    T4批量生成多文件
    T4模版引擎之基础入门
    T4模版引擎之生成数据库实体类
    localForage——轻松实现 Web 离线存储
    visual studio code插件精选
  • 原文地址:https://www.cnblogs.com/armfly/p/14919124.html
Copyright © 2011-2022 走看看