完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
转rtx操作系统
低功耗是MCU的一项非常重要的指标,比如某些可穿戴的设备,其携带的电量有限,如果整个电路消耗的电量特别大的话,就会经常出现电量不足的情况,影响用户体验。 本章节为大家讲解STM32F103和STM32F407的低功耗方式之睡眠模式在RTX操作系统上面的实现方法(RTX本身支持的tickless低功耗模式在第24章节讲解) 本章教程配套的例子含Cortex-M3内核的STM32F103和Cortex-M4内核的STM32F407。 21.1 STM32F103睡眠模式介绍 21.2 STM32F407睡眠模式介绍 21.3 低功耗模式的调试支持 21.4 如何有效降低休眠模式下的功耗 21.5 实验例程说明 21.6 总结 21.1 STM32F103睡眠模式介绍 说明:在RTX系统上面实现睡眠方式仅需了解这里讲解的知识基本就够用了,更多睡眠方式的知识请看STM32F103参考手册和Cortex-M3权威指南。 在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。 STM32F103有三种低功耗模式: u 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统滴答定时器Systick等仍在运行)。 u 停止模式(所有的时钟都已停止)。 u 待机模式(1.8V电源关闭)。 本章节我们主要讲解睡眠模式,而在实际的睡眠模式编程时我需要清楚那些问题呢?请继续往下看。 |
|
相关推荐
|
|
21.1.1 如何进入睡眠模式
通过执行 WFI(等待中断)或WFE(等待事件)指令进入睡眠状态。根据Cortex™-M3系统控制寄存器中的SLEEPONEXIT位的值,有两种选项可用于选择睡眠模式进入机制: u SLEEP-NOW:如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微控制器立即进入睡眠模式。 u SLEEP-ON-EXIT:如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。 小结:本章节配套的睡眠例子我们采用WFI指令进入睡眠模式,睡眠模式的进入机制是采用的SLEEP-NOW。因为系统复位上电后SLEEPONEXIT位是被清除的,所有这个位也不需要专门的去设置。另外在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。 在RTX系统上,我们可以将WFI指令放到空闲任务里面实现。 21.1.2 如何退出睡眠模式 由于我们是采用指令WFI进入睡眠模式,那么任意一个被嵌套向量中断控制器NVIC响应的外设中断都能将系统从睡眠模式唤醒。并且该模式唤醒所需的时间最短,因为没有时间损失在中断的进入或退出上。 在RTX系统上,主要是周期性执行的系统滴答定时器中断会将系统从睡眠态唤醒,当然,其它的任意中断也可以将其从休眠态唤醒。 |
|
|
|
|
|
21.2 STM32F407睡眠模式介绍
说明:在RTX系统上面实现睡眠方式仅需了解这里讲解的知识基本就够用了,更多睡眠方式的知识请看STM32F407参考手册和Cortex-M4权威指南。 默认情况下,系统复位或上电复位后,微控制器进入运行模式。在运行模式下,CPU通过HCLK 提供时钟,并执行程序代码。系统提供了多个低功耗模式,可在CPU不需要运行时(例如等待外部事件时)节省功耗。由用户根据应用选择具体的低功耗模式,以在低功耗、短启动时间和可用唤醒源之间寻求最佳平衡。STM32F407有三个低功耗模式: u 睡眠模式(Cortex™-M4F 内核停止,外设保持运行) u 停止模式(所有时钟都停止) u 待机模式(1.2 V 域断电) 本章节我们主要讲解睡眠模式,而在实际的休眠模式编程时我需要清楚那些问题呢?请继续往下看。 21.2.1 如何进入睡眠模式 执行 WFI(等待中断)或WFE(等待事件)指令即可进入睡眠模式。根据 Cortex™-M4F 系统控制寄存器中SLEEPONEXIT 位的设置,可以通过两种方案选择睡眠模式进入机制: u 立即休眠:如果SLEEPONEXIT 位清零, MCU将在执行WFI或WFE指令时立即进入睡眠模式。 u 退出时休眠:如果SLEEPONEXIT位置1,MCU将在退出优先级最低的ISR时立即进入睡眠模式。 小结:本章节配套的休眠例子我们采用WFI指令进入睡眠模式,睡眠模式的进入机制是采用的立即休眠。因为系统复位上电后SLEEPONEXIT位是被清除的,所有这个位也不需要专门的去设置。另外在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。 在RTX系统上,我们可以将WFI指令放到空闲任务里面实现。 21.2.2 如何退出睡眠模式 由于我们是采用指令WFI进入睡眠模式,那么任意一个被嵌套向量中断控制器NVIC响应的外设中断都能将系统从睡眠模式唤醒。并且该模式唤醒所需的时间最短,因为没有时间损失在中断的进入或退出上。 在RTX系统上,主要是周期性执行的系统滴答定时器中断会将系统从睡眠态唤醒,当然,其它的任意中断也可以将其从休眠态唤醒。 |
|
|
|
|
|
21.3 低功耗模式的调试支持
使用WFI和WFE可以进入低功耗模式。 MCU支持多种低功耗模式,分别可以关闭CPU时钟,或降低CPU的能耗。内核不允许在调试期间关闭FCLK或HCLK。这些时钟对于调试操作是必要的,因此在调试期间,它们必须工作。MCU使用一种特殊的方式,允许用户在低功耗模式下调试代码。为实现这一功能,调试器必须先设置一些配置寄存器来改变低功耗模式的特性。 u 在睡眠模式下,调试器必须先置位DBGMCU_CR寄存器的DBG_SLEEP位。这将为HCLK提供与FCLK(由代码配置的系统时钟)相同的时钟。 调用库函数:DBGMCU_Config(DBGMCU_SLEEP, ENABLE);即可 u 在停止模式下,调试器必须先置位DBG_STOP位。这将激活内部RC振荡器,在停止模式下为FCLK和HCLK。 调用库函数:DBGMCU_Config(DBGMCU_STOP, ENABLE);即可 21.4 如何有效降低休眠模式下的功耗 设计低功耗主要从以下几方面着手: u 关闭可以关闭的外设时钟。 u 降低系统主频。 u 注意I/O的状态,因为休眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。 l 如果此I/O口带上拉,请设置为高电平输出或者高阻态输入。 l 如果此I/O口带下拉,请设置为低电平输出或者高阻态输入。 u 注意I/O和外设IC的连接。 u 测试低功耗的时候,一定不要连接调试器,更不能边调试边测电流。 |
|
|
|
|
|
21.5 实验例程说明
21.5.1 STM32F103开发板实验 配套例子: V4-421_RTX实验_低功耗(睡眠模式) 实验目的: 1. 学习RTX实验低功耗(睡眠模式)。 2. 通过函数DBGMCU_Config(DBGMCU_SLEEP,ENABLE);保证睡眠模式下调试器正常连接使用。 实验内容: 1.K1按键按下,串口打印。 2.K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro。 任务AppTaskMsgPro接收到消息后进行消息处理。 3.各个任务实现的功能如下: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的信号量同步信号。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。 4.关于低功耗的说明: (1) STM32F10x有三种低功耗模式: a.睡眠模式(Cortex-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行) b.停止模式(所有的时钟都已停止) c.待机模式(1.8V电源关闭) (2) 通过指令__WFI进入休眠模式,可以通过任意中断唤醒。 (3) 降低系统主频或者关闭外设时钟也可有效降低系统功耗。 (4) 进入低功耗状态前,设置使用的I/O引脚不产生拉电流和灌电流也可有效降低功耗。 5. 本例程的低功耗实现方法是在空闲任务中调用__WFI指令来进入低功耗模式。未做关闭外设时钟和设置I/O引脚处理。在文件RTX_Conf_CM.C文件中的函数os_idle_demon里面调用函数__WFI。 6.实际项目中推荐采用官方的tickless模式。 |
|
|
|
|
|
RTX配置:
RTX配置向导详情如下: u Task Configuration l Number of concurrent running tasks 允许创建4个任务,实际创建了如下四个任务: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的消息邮箱数据。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。 l Number of tasks with user-provided stack 创建的4个任务都是采用自定义堆栈方式。 |
|
|
|
|
|
程序设计:
u 任务栈大小分配: staticuint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskLEDStk[256/8]; /* 任务栈*/ staticuint64_t AppTaskMsgProStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskStartStk[512/8]; /* 任务栈 */ 将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数,浮点运算和uint64_t类型数据运算会出问题。 u 系统栈大小分配: |
|
|
|
|
|
外设初始化:
注意新加的函数初始化函数DBGMCU_Config(DBGMCU_SLEEP, ENABLE);保证睡眠模式下调试器正常连接使用。 复制代码 /* /* ********************************************************************************************************* * 函 数 名: bsp_Init * 功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。 * 全局变量。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_Init(void) { /* 保证睡眠模式下调试器继续可以连接使用 */ DBGMCU_Config(DBGMCU_SLEEP, ENABLE); /* 优先级分组设置为4, 优先配置好NVIC */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); bsp_InitUart(); /* 初始化串口 */ bsp_InitLed(); /* 初始LED指示灯端口 */ bsp_InitKey(); /* 初始化按键 */ } |
|
|
|
|
|
RTX初始化:
复制代码 /* ********************************************************************************************************* * 函 数 名: main * 功能说明: 标准c程序入口。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int main (void) { /* 初始化外设 */ bsp_Init(); /* 创建启动任务 */ os_sys_init_user (AppTaskStart, /* 任务函数 */ 4, /* 任务优先级 */ &AppTaskStartStk, /* 任务栈 */ sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */ while(1); } |
|
|
|
|
|
RTX任务创建:
复制代码 /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */ 1, /* 任务优先级 */ &AppTaskUserIFStk, /* 任务栈 */ sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */ HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */ 2, /* 任务优先级 */ &AppTaskLEDStk, /* 任务栈 */ sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */ HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */ 3, /* 任务优先级 */ &AppTaskMsgProStk, /* 任务栈 */ sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */ } |
|
|
|
|
|
睡眠模式在空闲任务实现,即配置向导文件RTX_Conf_CM.c文件中
复制代码 /*--------------------------- os_idle_demon ---------------------------------*/ #include "stm32f10x.h" __task void os_idle_demon (void) { /* The idle demon is a system task, running when no other task is ready */ /* to run. The 'os_xxx' function calls are not allowed from this task. */ for (;;) { /* HERE: include optional user code to be executed when no task runs.*/ __WFI(); } } |
|
|
|
|
|
信号量的创建:
复制代码 static OS_SEM semaphore; /* ********************************************************************************************************* * 函 数 名: AppObjCreate * 功能说明: 创建任务通信机制 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppObjCreate (void) { /* 创建信号量计数值是0, 用于任务同步 */ os_sem_init (&semaphore, 0); } |
|
|
|
|
|
21.5.2 STM32F407开发板实验
配套例子: V5-421_RTX实验_低功耗(睡眠模式) 实验目的: 1. 学习RTX实验低功耗(睡眠模式)。 2. 通过函数DBGMCU_Config(DBGMCU_SLEEP,ENABLE);保证睡眠模式下调试器正常连接使用。 实验内容: 1.K1按键按下,串口打印。 2.K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro。 任务AppTaskMsgPro接收到消息后进行消息处理。 3.各个任务实现的功能如下: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的信号量同步信号。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。 4.关于低功耗的说明: (1) STM32F407有三种低功耗模式: a.睡眠模式(Cortex-M4F内核停止,所有外设包括Cortex-M4F核心的外设,如NVIC、系统时钟(SysTick)等仍在运行)。 b.停止模式(所有的时钟都已停止)。 c.待机模式(1.2V电源关闭)。 (2) 通过指令__WFI进入休眠模式,可以通过任意中断唤醒。 (3) 降低系统主频或者关闭外设时钟也可有效降低系统功耗。 (4) 进入低功耗状态前,设置使用的I/O引脚不产生拉电流和灌电流也可有效降低功耗。 5.本例程的低功耗实现方法是在空闲任务中调用__WFI指令来进入低功耗模式。未做关闭外设时钟和设置I/O引脚处理。在文件RTX_Conf_CM.C文件中的函数os_idle_demon里面调用函数__WFI。 6.实际项目中推荐采用官方的tickless模式。 |
|
|
|
|
|
设计低功耗主要从以下几个方面着手:
1. 用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式可以使用的低功耗方式有休眠模式,待机模式,停机模式。 2. 选择了低功耗方式后就是关闭可以关闭的外设时钟。 3. 降低系统主频。 4. 注意I/O的状态。 如果此I/O口带上拉,请设置为高电平输出或者高阻态输入; 如果此I/O口带下拉,请设置为低电平输出或者高阻态输入; a.在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。 b.在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。 c.在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚: ● 复位引脚(仍可用)。 ● RTC_AF1引脚 (PC13)(如果针对入侵、时间戳、RTC闹钟输出或RTC时钟校准输出进行了配置)。 ● WKUP引脚 (PA0)(如果使能)。 5.注意I/O和外设IC的连接。 6.测低功耗的时候,一定不要连接调试器,更不能边调试边测电流。 |
|
|
|
|
|
RTX配置:
RTX配置向导详情如下: u Task Configuration l Number of concurrent running tasks 允许创建4个任务,实际创建了如下四个任务: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的消息邮箱数据。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。 l Number of tasks with user-provided stack 创建的4个任务都是采用自定义堆栈方式。 l Run in privileged mode 设置任务运行在非特权级模式 |
|
|
|
|
|
imx6ull裸机编程,使用宏定义无法驱动,使用指针就可以驱动
434 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第三十二章 音频FFT实验
297 浏览 0 评论
飞凌嵌入式ElfBoard EL 1板卡-i2c与从设备通讯编程示例之i2c-tools工具使用
1266 浏览 0 评论
stc15f2k60s2利用串口传输字模存储到eeprom并进行点阵显示
1603 浏览 1 评论
1589 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11614 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-5 16:15 , Processed in 0.973543 second(s), Total 73, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号