以下转载自安富莱电子: http://forum./forum.php 本章节为大家讲解 FreeRTOS 本身支持的低功耗模式 tickless 实现方法,tickless 低功耗机制是当前 FreeRTOS 的低功耗模式介绍 默认定义的大小是 2 个系统时钟节拍,且用户自定义的话,不可以小于 2 个系统时钟节拍。 FreeRTOS 在线电子手册低功耗的说明 http://www./low-power-tickless-rtos.html。
显然用户自己配置要麻烦得多,好在FreeRTOS为M3,M4内核的做好了低功耗之睡眠模式,使得我们使用STM32 F1,F4系列的时候可以很简单,只需要在配置文件config.h中加上一个宏定义:#define configUSE_TICKLESS_IDLE 1 那我们要实现停机模式呢?那就只有自己动手了。 在介绍实现停机模式之前,有必要提醒一下:在低功耗的时候,要根据情况配置 回到正题,如何添加用户函数实现停机模式: * 说 明 : 本实验主要学习FreeRTOS的低功耗(tickless之停机模式) * 实验目的: * 1. 学习FreeRTOS的低功耗(tickless之停机模式) * 2. FreeRTOS自带的tickless 模式使用比较简单,只需用户使能宏配置: * #define configUSE_TICKLESS_IDLE 1 * 3. 为了打印系统信息,前面的所有试验中始化一个定时器中断,精度高于滴答定时器中断, * 每50us进一次,本例子关闭了任务执行情况打印功能,因为高频率的定时器中断影响低 * 功耗tickless模式效率。 * 4. 本实验在FreeRTOS自带的tickless睡眠模式的基础上实现停机模式,实现方法是重新 * 在文件FreeRTOSConfig.h定义如下函数两个函数 * #define configPRE_SLEEP_PROCESSING(x) OS_PreSleepProcessing(x) * #define configPOST_SLEEP_PROCESSING(x) OS_PostSleepProcessing(x) * 在文件port.c里面函数vPortSuppressTicksAndSleep调用了上面这两个函数: * --------------------------------------------------------------------- * configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); * if( xModifiableIdleTime > 0 ) * { * __dsb( portSY_FULL_READ_WRITE ); * __wfi(); * __isb( portSY_FULL_READ_WRITE ); * } * configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); * ----------------------------------------------------------------------- * 函数OS_PreSleepProcessing和OS_PostSleepProcessing是需要用户提供的,用户可以在 * 这两个函数里面实现进入停机模式和从停机模式恢复到正常的运行状态。另外,通过在函数 * OS_PreSleepProcessing里设置其形参变量vParameters为0就可以屏蔽原有的休眠模式。
/* ********************************************************************************************************* * 函 数 名: OS_PreSleepProcessing * 功能说明: 下面的函数在文件FreeRTOSConfig.h文件里面进行了宏定义: * #define configPRE_SLEEP_PROCESSING(x) OS_PreSleepProcessing(x) * #define configPOST_SLEEP_PROCESSING(x) OS_PostSleepProcessing(x) * 在文件port.c里面函数vPortSuppressTicksAndSleep调用了上面这两个函数: * --------------------------------------------------------------------- * configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); * if( xModifiableIdleTime > 0 ) * { * __dsb( portSY_FULL_READ_WRITE ); * __wfi(); * __isb( portSY_FULL_READ_WRITE ); * } * configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); * ----------------------------------------------------------------------- * 通过这两个函数可以实现在调用__WFI或者__WFE指令前后执行进一步的低功耗操作,主要有以下三种: * 1. 降低系统主频。 * 2. 关闭外设时钟。 * 3. IO引脚要做处理,防止拉电流和灌电流增加功耗。 * 如果此IO口带上拉,请设置为高电平输出或者高阻态输入; * 如果此IO口带下拉,请设置为低电平输出或者高阻态输入; * 下面的函数未做关闭外设时钟的处理。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void OS_PreSleepProcessing(uint32_t vParameters) { (void)vParameters; /* 用户可以考虑在此处加入关闭外设时钟来进一步降低功耗 */ vParameters = 0; PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE); } void OS_PostSleepProcessing(uint32_t vParameters) { /* 如果前面关闭了外设时钟,需要在这里恢复 */ /* 1、当一个中断或唤醒事件导致退出停止模式时,HSI RC振荡器被选为系统时钟。 2、退出低功耗的停机模式后,需要重新配置使用HSE。 */ RCC_HSEConfig(RCC_HSE_ON); while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET){} RCC_PLLCmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while (RCC_GetSYSCLKSource() != 0x08){} }
|
|
来自: astro蛋蛋 > 《FreeRTOS》