合MSP430F5438和FreeRTOS总结一下如何使用嵌入式操作系统实现低功耗工作

0.前言

    MCU实现低功耗本质而言便是停止MCU工作,通过中断的方式重新唤醒MCU,这些中断可以包括外部IO中断,UART接收中断,定时器中断等等。如果结合嵌入式操作系统,可以在空任务或者空任务钩子函数中进入低功耗模式,在系统滴答时钟中断服务函数中重新回到正常工作模式。利用操作系统进入和退出低功耗模式,需要熟悉嵌入式操作系统的空任务和系统滴答时钟中断,下面结合MSP430F5438和FreeRTOS总结一下如何使用嵌入式操作系统实现低功耗工作。
 

1.进入低功耗模式

    多数嵌入式操作系统都包含一个空任务,空任务优先级最低且一直保持就绪状态,空任务可以用于统计CPU使用率,或者让MCU进入低功耗状态。如果不想修改空任务,还可以通过空任务的钩子函数插入实现低功耗的代码。在FreeRTOS中,若需要打开空任务钩子函数,需要在FreeRTOSConfig.h中定义configUSE_IDLE_HOOK
#define configUSE_IDLE_HOOK 1
钩子函数中实现低功耗的代码如下
 
[cpp] view plain copy
 
  1. void vApplicationIdleHook( void )  
  2. {  
  3.     /* Called on each iteration of the idle task.  In this case the idle task 
  4.     just enters a low power mode. */  
  5.     __bis_SR_register( LPM3_bits + GIE );  
  6. }  
    在这里可打开全局中断,若全局中断关闭那么系统可能再也“活”不过来了。
 

2.退出低功耗模式

    在大多数嵌入式操作系统中可以在系统滴答中断函数中退出低功耗模式。由于MSP430的退出低功耗的指令只能在中断中使用,所以一旦进入系统滴答中断函数,可先退出低功耗模式。具体的代码实现如下:
[cpp] view plain copy
 
  1. #pragma vector=configTICK_VECTOR  
  2. __interrupt __raw void vTickISREntry( void )  
  3. {  
  4. extern void vPortTickISR( void );  
  5.   
  6.     __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );  
  7.     vPortTickISR();  
  8. }  
    该段代码位于port.c中,在MSP430F5438分支中,系统滴答定时器采用TIMER0_A0所以configTICK_VECTOR被定义为
    #define configTICK_VECTORTIMER0_A0_VECTOR
    其他相关的定义可以查看FreeRTOSConfig.h文件
 

3.实现过程

    例如某任务在t1时刻调用阻塞API,例如vTaskDelay,此时任务交出CPU使用权由OS进行任务调度。t2时刻,由于没有其他就绪任务,OS运行空任务,在空任务的最后进入空任务钩子函数,在空任务钩子函数中MCU进入低功耗模式,此时可进入LPM3模式。t3时刻MCU进入低功耗模式之后,MCU停止工作。t4时刻,由于系统滴答时钟中断服务函数中,MCU重新处于活跃状态,并且通过指令退出低功耗模式,此时OS任务调度器再次工作,若此时任务再次处于就绪状态便重新运行该任务。
    以上便是如何利用OS实现低功耗的基本方法,但是t3时刻和t4时刻是有反复的。例如,系统滴答时钟ISR发生之后,OS任务调度器中并没有就绪的任务,只能再次运行空任务,通过空任务再次进入低功耗模式,如此反复直到某任务就绪便执行任务代码。
    通过以上的分析,使用嵌入式操作系统和实现MCU低功耗并不矛盾,反而带来了诸多方便。

用户喜欢...

FreeRTOS任务调度研究

这篇文章不介绍FreeRTOS移植,只是最近针对多核ARM Cortex系列平台做了移植后的一篇总结研究文章。所以不涉及对FreeRTOS整体的介绍,而只是分析任务调度这一块的机制。对应的Demo参考自CORTE...


在FreeRTOS嵌入式操作系统中,如何设置STM32 Cortex M3和M4系列MCU的中断优先级

前言 本文将说明在FreeRTOS嵌入式操作系统中,如何设置STM32 Cortex M3和M4系列MCU的中断优先级。 总结 【1】STM32L1系列,STM32F1系列,STM32F4系列,设置NVIC时需要使用 NVIC_PriorityGroup_4 。 【2】抢占优...


我们为什么要学RTOS?为什么要选用FreeRTOS?

作为基于ARM7、Cortex-M3硬件开发的嵌入式工程师,本人一直反对使用RTOS。不仅因为不恰当的使用RTOS会给项目带来额外的稳定性风险,更重要的是个人认为绝大多数基于ARM7、Cortex-M3硬件的项目...


Zynq中使用FreeRTOS的空闲钩子函数时在SDK中的设置

本文介绍zynq中使用FreeRTOS的空闲钩子函数时在SDK中的设置和一些说明 初玩zynq发现,在zynq中可以运行FreeRTOS,果断试了下;测试了几个例子,一切正常,但是在使用空闲钩子函数时导致无法正...


FreeRTOS介绍与移植

最近在看一个实时嵌入式操作系统————FreeRTOS, 为什么看它呢?首先它是开源的,其次它的内核最小只需要三个文件 task.c、list.c、queue.c,加起来5000多行代码还有很多注释在里面。他的优...


FreeRTOS(V8.0.1)系统之xTaskGenericCreate()

BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, // 指向任务的入口函数. 任务必须执行并且永不返回 (即:无限循环).const char * const pcName, //描述任务的名字。主要便于调试。最大长度由configMAX_T...


FreeRTOS(V8.0.1)系统之vTaskSuspendAll()和xTaskResumeAll()

//如果一个临界区太长而不适合简单地关中断来实现,可以考虑采用挂起调度器的方式。但是唤醒(resuming, or un-suspending)调度器却是一个 //相对较长的操作。所以评估哪种是最佳方式需要结合实...


FreeRTOS代码剖析之5:链表管理list.c

链表是操作系统中常用的数据结构,其结构比较简单,因此在剖析FreeRTOS的内核时先从这里开始入手。 链表是由众多链表节点组成的,在FreeRTOS中,链表节点有两种定义,分别是xLIST_ITEM和xM...


FreeRTOS代码剖析之4:内存管理Heap_4.c

FreeRTOS8.0.1内存管理的最后一个堆模型Heap_4,貌似是在这一个版本才有的。所以找到的说明几乎没有。代码的开头注释也只是简单地说了一下实现了pvPortMalloc()和vPortFree()两个函数,并且能够对...


FreeRTOS代码剖析之3:内存管理Heap_3.c

FreeRTOS8.0.1的第三个模型Heap_3,可以说是最容易理解的一个内存堆管理模型。因为在这个模型里,FreeRTOS直接将标准C库中的malloc()和free()进行加工打包。(Implementation of pvPortMalloc() and vPortFree(...


FreeRTOS代码剖析之2:内存管理Heap_2.c

在FreeRTOS8.0.1这个版本中,一共有四个内存堆模型。这一次讲的就是第二个模型Heap_2.c。从一开始就可以看到注释中对Heap_2的模型解释:这是对pvPortMalloc()和vPortFree()的简单实现,除了可以分配...


FreeRTOS代码剖析之1:内存管理Heap_1.c

内存管理是一个操作系统的重要组成部分之一,所有应用程序都离不开操作系统的内存管理。因此,在剖析FreeRTOS的内核代码之前,前对FreeRTOS的内存管理进行研究。 现在以FreeRTOS8.0.1进行剖析...


自己定制的一个FreeRTOS 8.2.0 + LwIP 1.4.0 + FreeRTOS CLI的BSP,给Zynq用的:)

嗨,我在FreeRTOS的代码基础上,定制了一个FreeRTOS 8.2.0 + LwIP 1.4.0 + FreeRTOS CLI的bsp, 可以在上面运行FreeRTOS的CORTEX A9的demo,大家可以下载下来试一试:) https://github.com/liubenyuan/freertos_zynq_bsp...


FreeRTOS(V8.0.1)系统之vTaskDelete()

void vTaskDelete( TaskHandle_t xTaskToDelete ){TCB_t *pxTCB;taskENTER_CRITICAL();{//若传进来的值为NULL则用此函数的就是任务本身。pxTCB = prvGetTCBFromHandle( xTaskToDelete );//根据任务句柄获取对应任务的句柄或TCB//将...


FreeRTOS(V8.0.1)系统之vTaskDelay()和vTaskDelayUntil()

#if ( INCLUDE_vTaskDelay == 1 )//延时特定时间xTicksToDelay,这个时间需要转换为唤醒绝对时间xTimeToWake,//这样才能在与vTaskIncrementTick函数中操作的数值是一致的xTicksToDelay:延时的节拍数void vTaskDelay(...


FreeRTOS(V8.0.1)系统之Heap_2

#include #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "FreeRTOS.h" #include "task.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define configADJUSTED_HEAP_SIZE( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) // 在使用之前初始化堆结构...