【STM32H7】第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 实验例程

配套例子:

V7-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模式的实现,采用的睡眠模式,大家感兴趣可以试试停机模式。

 

posted @ 2021-08-31 15:35  硬汉嵌入式  阅读(392)  评论(0编辑  收藏  举报