摘要
本文檔介紹TinyOS 如何管理微控制器的低功耗狀態(tài)。
簡介
微控制器通常有幾個電源狀態(tài),,它們具有不同的電源功率,、喚醒延遲和外圍支持。微
控制器在能滿足程序需求的前提下,,應當一直處于能耗盡量低的電源狀態(tài),。為了準確地決
斷處理器該處于哪個狀態(tài),需要有大量外圍子系統(tǒng)和外圍設(shè)備的電源狀態(tài)信息,。另外,,狀
態(tài)轉(zhuǎn)換是很常見的。每當微控制器處理一個中斷時,,它從低功耗狀態(tài)切換到激活狀態(tài),;當
TinyOS 調(diào)度器發(fā)現(xiàn)任務(wù)隊列為空時,它回到低功耗狀態(tài),。TinyOS 2.x 使用三種機制來決定
讓處理器處于哪種狀態(tài):狀態(tài)和控制寄存器,,臟位,,電源狀態(tài)覆蓋(override)。本文檔講
述了這些機制以及子系統(tǒng)電源管理的基本概念,。
背景
TinyOS 的調(diào)度器在任務(wù)隊列為空時讓處理器進入睡眠狀態(tài),。然而,處理器可能有多個
電源狀態(tài),。比如MSP430 有一個激活狀態(tài)(發(fā)射指令)和5 個低功耗狀態(tài),。低功耗狀態(tài)
有LPM0?LPM4。LPM0 只禁用CPU 和主系統(tǒng)時鐘,,LPM4 禁用CPU,、所有的時鐘和震蕩
器,只留下喚醒用的外部中斷源,。各種低功耗模式的差異可能有350 倍或更多(LPM0 為
75uA/3V,,LPM4 為0.2uA/3V)。正確地選擇微控制器的低功耗狀態(tài)可以大幅度地提高系統(tǒng)
的生存時間,。
TinyOS 1.x 用幾種不同的方法管理MCU 的功耗,,但是各種方法之間有共同之處。比如
在mica 平臺上有一個叫HPLPowerManagement 的組件,,它擁有啟用和禁用低功耗模式的
命令,,還有一個adjustPower() 命令用于根據(jù)各種控制寄存器和狀態(tài)寄存器計算低功耗狀態(tài),
并把結(jié)果存儲在Atmega128 的MCU 控制寄存器中,。當TinyOS 要求MCU 睡眠時,,它使用
控制寄存器決定轉(zhuǎn)移到哪個狀態(tài)?;贛SP430 的平臺如Telos 和eyes 在每次調(diào)度器要求
系統(tǒng)進入睡眠時計算低功耗狀態(tài),。
這兩種方法有各自的長處和缺點。1.x 中mica 使用的方法是效率較高的,,因為它只在被
要求計算的時候才計算低功耗狀態(tài),。然而這就把何時計算的時機讓于其它組件決定,這很
容易引入Bug,。由于1.x 硬件抽象架構(gòu)定義的不夠完善從而使這個問題更加嚴重,。MSP430
的方法更簡單,系統(tǒng)不需要外部的干涉可以自動進入正確的電源狀態(tài),。然而這種方法開銷
較大,,每個中斷都會引入了40-60 個周期用于喚醒系統(tǒng),這可能會是系統(tǒng)中斷處理速率的
瓶頸,。
兩種方法都假設(shè)TinyOS 可以通過檢查控制寄存器和狀態(tài)寄存器決定正確的低功耗狀
態(tài),。比如MSP430 默認運行在低功耗模式3,當它檢測到定時器A,、USART 或ADC 被激
活時,,它轉(zhuǎn)到低功耗模式1(LPM1),。外圍設(shè)備和子系統(tǒng)可能在MCU 睡眠時喚醒節(jié)點或
繼續(xù)工作,以這樣的觀點來看這是正確的行為,。但是電源模式轉(zhuǎn)換會引入喚醒延遲,,這可
能是高層組件所關(guān)心的因素。在功率非常低的MCU 中喚醒延遲并不是一個嚴重的問題,,
如Atmega128 和MSP430,,但在如Xscale(imote2 平臺的基礎(chǔ))等更強力的處理器上可能
會使喚醒延遲長達5ms。在一些應用領(lǐng)域中,,這樣的延遲是嚴重的問題,。高層的組件應當
根據(jù)需求向TinyOS 電源控制器提供適當?shù)男畔ⅲ糜谟嬎阏_的低功耗狀態(tài),。
微控制器電源管理
TinyOS 2.x 使用3 種基本機制管理和控制MCU 電源狀態(tài):一個臟位,,一個針對芯片的
低功耗狀態(tài)計算函數(shù)和電源狀態(tài)覆蓋函數(shù)。臟位告訴TinyOS 何時需要計算新的低功耗狀
態(tài),,由低功耗狀態(tài)計算函數(shù)作計算,,覆蓋函數(shù)允許高層組件根據(jù)需要引入額外的需求。
這三種機制都在TinyOS 核心調(diào)度循環(huán)中運作,,在TEP 106(調(diào)度器與任務(wù))中有介紹,。
該循環(huán)在啟動過程中調(diào)用,,這在TEP 107(啟動順序)中有講述,。當啟用MCU 休眠時,調(diào)
用的命令是Scheduler.taskLoop(),。
若在任務(wù)隊列為空時調(diào)用該命令,,則TinyOS 調(diào)度器會通過McuSleep 接口讓MCU 進入
睡眠狀態(tài):
interface McuSleep {
async command void sleep();
}
McuSleep.sleep() 使MCU 進入低功耗睡眠狀態(tài),可以由中斷喚醒,。該命令與TinyOS 1.x 中
的__nesc_atomic_sleep()不同,。注意,1.x 中的調(diào)用意味著讓MCU 睡眠必須具有某種原
子的屬性,。該命令應在atomic 區(qū)域中調(diào)用,,必須原子地重新啟用中斷再進入睡眠。問題是
系統(tǒng)中重新啟用中斷和進入睡眠這兩者之間的時間發(fā)生了中斷:該中斷可能會post 一個任
務(wù),,但是該任務(wù)必須在mcu 被喚醒后才能執(zhí)行,。
MCU 通常用硬件機制要解決這個問題。比如Atmega128 中的sei 指令在指令發(fā)射兩個
周期后才重新啟用中斷(因此指令序列sei sleep 會原子的執(zhí)行),。
McuSleepC 組件提供McuSleep 接口,,TinySchedulerC 必須原子地把它連接到調(diào)度器實
現(xiàn)上。McuSleepC 是芯片或平臺相關(guān)的組件,,它的頭部中必須包含以下接口:
component McuSleepC {
provides interface McuSleep;
provides interface PowerState;
uses interface PowerOverride;
}
interface McuPowerState {
async command void update();
}
interface McuPowerOverride {
async command mcu power t lowestState();
}
McuSleepC 還可以用其它的接口,。
臟位
每當硬件表示層(HPL,,見TEP 2:硬件抽象結(jié)構(gòu))組件改變了一部分硬件配置時,這
可能會改變MCU 可用的低功耗狀態(tài),,它必調(diào)用McuPowerState.update(),。這是電源管理
的第一種機制──臟位。如果McuPowerState.update() 被調(diào)用,,則McuSleepC 必須在調(diào)用
McuSleep.sleep() 進入睡眠之前重新計算低功耗狀態(tài),。
低功耗狀態(tài)計算
McuSleepC 負責計算最低的功率狀態(tài),同時保證TinyOS 各子系統(tǒng)能安全正確地工作,。
McuSleepC 應當使這種計算次數(shù)盡量少,,因為它是原子性的計算,如果計算過于頻繁會導
致相當大的開銷和抖動,。
MCU 電源狀態(tài)必須在標準芯片的頭文件中用enum 類型表示,。該文件必須定義
mcu power t 和一個結(jié)合函數(shù)將兩個電源狀態(tài)值合并為一個并返回,以提供它們功能
的結(jié)合,。
假設(shè)有一種MCU 具有3 個低功耗狀態(tài)(LPM0,,LPM1,LPM2)和兩種硬件資源如時
鐘(HR0,,HR1),。在LPM0 中,HR0 和HR1 都處于激活狀態(tài),。在LPM1 中,,HR0 是關(guān)閉
的而HR1 是激活的。在LPM2 中,,HR0 和HR1 是關(guān)閉的,。下面的表描述了合適的結(jié)合函
數(shù)(essentially a MAX):
| LPM0
| LPM1
| LPM2
|
LPM0
| LPM0
| LPM0
| LPM0
|
LPM1
| LPM0
| LPM1
| LPM1
|
LPM2
| LPM0
| LPM1
| LPM2
|
LPM2 中,HR0 是激活的而HR1 是關(guān)閉的,,結(jié)合函數(shù)如下:
| LPM0
| LPM1
| LPM2
|
LPM0
| LPM0
| LPM0
| LPM0
|
LPM1
| LPM0
| LPM1
| LPM0
|
LPM2
| LPM0
| LPM0
| LPM2
|
電源狀態(tài)覆蓋
當McuSleepC 計算最佳低功耗狀態(tài)時,,它必須調(diào)用PowerOverride.lowestState()。McuSleepC
應當有該命令的一種默認實現(xiàn),,返回MCU 可用的最低功耗狀態(tài),。該命令的返回值應
當是mcu_power_t 類型。McuSleepC 必須考慮該調(diào)用的返回值,,并恰當?shù)嘏c它計算出的低
功耗狀態(tài)相結(jié)合,。
PowerOverride 功能的存在是因為高層的組件可能有硬件狀態(tài)或配置寄存器不能捕獲的
信息,如可允許的最大喚醒延遲,。它可以覆蓋所有系統(tǒng)的保留機制,,因此要謹慎行事。由
于它是在核心調(diào)度器循環(huán)的atomic 區(qū)域中調(diào)用的,,PowerOverride.lowestState() 的實現(xiàn)應當
是一個高效的函數(shù),,不能長于20 ? 30個周期,。該實現(xiàn)應當是一個預存值的簡單返回。隨意
地連接到這個命令很容易引起TinyOS 出現(xiàn)不正常的行為,。mcu_power_t 具有一個結(jié)合函
數(shù)意味著這個命令可以有扇出調(diào)用,。
第5節(jié)描述了在Atmega128 的定時器棧中使用McuPowerOverride 的一個例子。
外圍設(shè)備和子系統(tǒng)
在HIL 層中,,TinyOS 子系統(tǒng)通常有一個簡單,、強制的電源管理接口。根據(jù)引入的延時,,
這些接口可以是StdControl,,SplitControl 或AsyncStdControl。這些接口保證如果有組件調(diào)
用另一個組件的stop 命令,,它能使該組件所代表的子系統(tǒng)進入非激活,、低功耗狀態(tài)。
從MCU 電源管理的角度來看,,這種轉(zhuǎn)換會引起狀態(tài)寄存器和控制寄存器的變化(比如
禁用某個時鐘),。根據(jù)3.1 小節(jié)所述,在有較大的變化發(fā)生時,,MCU 電源管理子系統(tǒng)會被
告知,,并在進入睡眠之前做適當?shù)膭幼鳌EP 115 描述了非虛擬化設(shè)備的電源管理,,TEP
108 描述了TinyOS 可以自動將電源管理放入共享非虛擬化設(shè)備中,。
實現(xiàn)
McuSleepC 的實現(xiàn)可以在tinyos-2.x/tos/chips/atm128,tinyos-2.x/tos/chips/msp430,,
tinyos-2.x/tos/chips/px27ax 中找到,。
使用McuPowerOverride 的一個例子可以在atmega128 定時器系統(tǒng)中找到,。由于一部分
低功耗狀態(tài)喚醒延遲比其它的要長,,定時器系統(tǒng)不允許在定時器即將觸發(fā)前有較長的的
延遲。該實現(xiàn)可以在tinyos-2.x/tos/chips/atm128/timer/HplAtm128Timer0AsyncP.nc
中找到,,tinyos-2.x/tos/chips/atm128/timer/HplAtm128Timer0AsyncC.nc 會自動連接
到McuSleepC,。
|