zoukankan      html  css  js  c++  java
  • 【STM32F429】第23章 ThreadX低功耗之tickless模式

    论坛原始地址(已完结):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514

    第23章       ThreadX低功耗之tickless模式

    本章节为大家讲解ThreadX本身支持的低功耗模式tickless实现方法,tickless低功耗机制是当前RTOS所采用的通用低功耗方法,。

    23.1 tickless低功耗模式介绍

    23.2 RTX实现tickless模式的框架

    23.3 tickless模式的API函数

    23.4 实验例程说明

    23.5 总结

    23.1 tickless低功耗模式介绍

    tickless低功耗机制是当前RTOS所采用的通用低功耗方法。

    ThreadX的低功耗也是采用的这种方式,那么tickless又是怎样一种模式呢,仅从字母上看tick是滴答时钟的意思,less是tick的后缀,表示较少的,这里的含义可以表示为无滴答时钟。整体看这个字母就是表示滴答时钟节拍停止运行的情况。

    反映在ThreadX上,tickless又是怎样一种情况呢?我们都知道,当用户任务都被挂起时,最低优先级的任务会得到执行,但ThreadX是没有空闲任务的,实际上是一种无任务执行的空闲状态。那么STM32支持的睡眠模式,停机模式就可以放在空闲状态里面实现。为了实现低功耗最优设计,我们还不能直接把睡眠或者停机模式直接放在空闲状态就可以了。进入空闲状态后,首先要计算可以执行低功耗的最大时间,也就是求出下一个要执行的高优先级任务还剩多少时间。然后就是把低功耗的唤醒时间设置为这个求出的时间,时间到后系统会从低功耗模式被唤醒,继续执行多任务。这个就是所谓的tickless模式。从上面的讲解中可以看出,实现tickless模式最麻烦是低功耗可以执行的时间如何获取。关于这个问题,ThreadX已经为我们做好了。

    23.2 ThreadX实现tickless模式的框架

    ThreadX实现低功耗tickless模式的代码框架如下:

    /* 通过函数tx_low_power_enter获取系统可以处于低功耗模式的时钟节拍个数 */
    #ifdef TX_LOW_POWER
        PUSH    {r0-r3}
        BL      tx_low_power_enter                      // Enter low power mode
        POP     {r0-r3}
    #endif
    
    /* 调用低功耗指令进入低功耗模式 */
    #ifdef TX_ENABLE_WFI
        DSB                                             // Ensure no outstanding memory transactions
        WFI                                             // Wait for interrupt
        ISB                                             // Ensure pipeline is flushed
    #endif
    
    /* 退出低功耗 */
    #ifdef TX_LOW_POWER
        PUSH    {r0-r3}
        BL      tx_low_power_exit                       // Exit low power mode
        POP     {r0-r3}
    #endif

    23.3 tickless模式宏定义

    tickless模式有如下几个宏定义需要了解:

    •   TX_LOW_POWER_TIMER_SETUP

    用户可以重定向低功耗时钟建立,由函数tx_low_power_enter调用。

    •   TX_LOW_POWER_TICKLESS

    使能tickless模式。

    •   TX_LOW_POWER_USER_ENTER

    用户可以重定向进入低功耗模式,由函数tx_low_power_enter调用。

    •   TX_LOW_POWER_USER_EXIT

    用户可以重定向退出低功耗模式,由函数tx_low_power_exit调用。

    •   TX_LOW_POWER_USER_TIMER_ADJUST

    用户可以重定向退出低功耗后的时钟调整,可以获取处于低功耗模式的时间,由函数tx_low_power_exit调用。

    23.4 tickless低功耗模式移植

    23.4.1        第1步,添加低功耗文件

    低功耗文件是从ThreadX内核版本V6.1.5开始提供的:

     

    23.4.2        第2步,添加头文件路径

    仅添加一个路径即可:

     

    23.4.3        第3步,在tx_port.h文件添加宏定义

    添加如下几个宏定义:

    /* Define the LowPower macros and flags */
    
    /* Define a macro that sets up a low power clock and keep track of time */
    /*#define TX_LOW_POWER_TIMER_SETUP */
    
    /* Define the TX_LOW_POWER_TICKLESS to disable the internal ticks */
    #define TX_LOW_POWER_TICKLESS
    
    /* A user defined macro to make the system enter low power mode */
    extern void App_ThreadX_LowPower_Enter(void);
    #define TX_LOW_POWER_USER_ENTER App_ThreadX_LowPower_Enter()
    
    /* A user defined macro to make the system exit low power mode */
    extern void App_ThreadX_LowPower_Exit(void);
    #define TX_LOW_POWER_USER_EXIT App_ThreadX_LowPower_Exit()
    
    /* User's low-power macro to obtain the amount of time (in ticks) the system has been in low power mode */
    /*#define TX_LOW_POWER_USER_TIMER_ADJUST */

    其中函数App_ThreadX_LowPower_Enter和App_ThreadX_LowPower_Exit放在了main.c里面实现:

    /*
    *********************************************************************************************************
    * 函 数 名: App_ThreadX_LowPower_Enter
    * 功能说明: 进入低功耗模式
    * 形    参:无
    * 返 回 值: 无
    *********************************************************************************************************
    */
    void App_ThreadX_LowPower_Enter(void)
    {
    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
    }
    
    /*
    *********************************************************************************************************
    * 函 数 名: App_ThreadX_LowPower_Exit
    * 功能说明: 退出低功耗模式
    * 形    参:无
    * 返 回 值: 无
    *********************************************************************************************************
    */
    void App_ThreadX_LowPower_Exit(void)
    {
    
    }

    23.4.4        第4步,使能预定义宏TX_LOW_POWER

    使能汇编文件的预定义宏TX_LOW_POWER:

     

    23.4.5        第5步,注意事项

    注意tx_thread_schedule.s文件中低功耗函数调用前后寄存器的入栈和出栈问题,早期几个版本此处没有做寄存器的入栈和出栈处理,最新的内核版本V6.1.8开始已经修正了这个问题。如果不做处理,移植后运行程序会进入硬件异常。

     

    至此就完成了ThreadX低功耗移植。

    23.5 实验例程

    配套例子:

    V6-3018_ThreadX Low Power

    实验目的:

    1. 学习ThreadX低功耗设计。

    实验内容:

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

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

             CPU利用率 =  0.89%

             任务执行时间 = 0.586484645s

             空闲执行时间 = 85.504470575s

             中断执行时间 = 0.173225395s

             系统总执行时间 = 86.264180615s              

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

            任务优先级 任务栈大小 当前使用栈  最大栈使用   任务名

              Prio     StackSize   CurStack    MaxStack   Taskname

              2         4092        303         459      App Task Start

              5         4092        167         167      App Msp Pro

              4         4092        167         167      App Task UserIF

               5         4092        167         167      App Task COM

               0         1020        191         191      System Timer Thread           

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

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

    App Task MspPro任务 :消息处理。

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

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

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

    2、K2按键按下演示内存块的申请和释放,K3按键按下演示内存池的申请和释放。

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

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

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

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

    #define Enable_RTTViewer  1

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

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

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

     

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

     

    程序执行框图:

    23.6 总结

    本章节主要为大家讲解了ThreadX低功耗tickless模式的实现,采用的睡眠模式,大家感兴趣可以试试停机模式。

     

    微信公众号:armfly_com 安富莱论坛:www.armbbs.cn 安富莱淘宝:https://armfly.taobao.com
  • 相关阅读:
    HDU 2899 Strange fuction
    HDU 2899 Strange fuction
    HDU 2199 Can you solve this equation?
    HDU 2199 Can you solve this equation?
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 699 掉落的方块(线段树?)
    Java实现 LeetCode 699 掉落的方块(线段树?)
    Java实现 LeetCode 699 掉落的方块(线段树?)
  • 原文地址:https://www.cnblogs.com/armfly/p/15210606.html
Copyright © 2011-2022 走看看