在线免费观看成年人视频-在线免费观看国产-在线免费观看国产精品-在线免费观看黄网站-在线免费观看精品

產品分類

當前位置: 首頁 > 新聞熱點

嵌入式系統低功耗設計的軟件策略

發布日期:2022-07-14 點擊率:57

的功耗問題已變得越來越重要。這一情況不僅限于手機、PDA和便攜媒體播放器等便攜式設備,對一些連接到交流電電源的設備而言,功耗也變得重要起來。條形碼掃描器、簽名識別設備、外部存儲設備和WiFi或無線鍵盤等通過USB供電的產品日漸增多,而這些低功耗的USB器件所允許的功耗預算只限于8mA到100mA之間。因此,每毫安的電流都彌足珍貴的。


數字邏輯電路中的功耗主要分為兩部分:漏電流和開關電流。CMOS邏輯中的漏電流是可以忽略的,當器件采用的是專用于低功耗8位和16位微控制器的更保守的工藝技術時尤其如此。造成功耗的關鍵是開關瞬態,每當一個數字輸出改變狀態時,都必須對與其本身相關的多個寄生電容和所有與其相連的電容進行充放電,不論這些電容位于芯片外部還是芯片內部。因此,一條信號線上的每次狀態轉換都會或多或少地消耗一定能量。因而,降低狀態轉換的速度(也即降低時鐘速度)可以降低功耗。但如果芯片因此而必須運行更長的時間才能得到同樣的結果的話,那降低速度就不一定意味著節能了。


因此,真正的挑戰是如何降低CPU要完成任務而必須執行的指令條數。這對程序設計提出了多條要求—首先是謹慎設計應用的軟件結構,編寫緊湊的代碼,以及選擇合適的開發工具(例如編譯器)。編譯器本身就可能對執行應用所需的指令條數有很大影響,從而對最后的功耗有很大影響。


微控制器的睡眠模式


大多數微控制器都可以進入某種睡眠或暫停狀態,以此降低芯片功耗。在這些狀態下,CPU將停止運行,芯片上的許多其它資源也會暫停或關閉。芯片所允許的睡眠狀態類型和應用的需要決定了應用中可以采用那些睡眠狀態。


軟件低功耗的設計目的就是充分利用應用所允許的最深睡眠狀態,并確保芯片盡可能長時間地保持在這一狀態下。編譯器對于微控制器可維持在睡眠模式下的時間長短有著微妙卻十分重要的影響。因為采用的編譯方法可能會在中斷程序上和在帶分塊存儲器(banked memory)的器件的存儲器地址定位上浪費很多CPU周期。


圖1:調用關系結構圖。
圖1:調用關系結構圖。


中斷程序


不論在何種應用中,保持中斷程序短小快速都是十分重要的,在速度和/或功耗十分關鍵的時候尤其如此,因為縮短中斷程序能夠幫助將中斷開銷降至最低。


編譯器對于中斷程序的貢獻在于它可以影響一個中斷出現時相應需保存的寄存器個數。為避免存儲器覆蓋,傳統的編譯器都會將一個中斷可能用到的所有寄存器都保存下來。而大多數編譯器都無法得知哪些寄存器可能會或不會被某個中斷使用,因此只有將所有寄存器全部保存。問題是一個中斷所用的CPU周期數直接是它所保存和恢復的寄存器個數的函數。而用于保存和恢復中斷時各種寄存器參數的CPU周期越多,消耗的功率也就越多。


例如,微星(Microchip)的PIC16所用的一款編譯器就不考慮哪些數據是必需的,而會為每個中斷均保存8字節數據。保存8字節數據總共需要42個指令周期(其中23個用于背景保存,19個用于恢復)。看起來好像并不多,但在一個大量包含中斷的應用中,CPU“蘇醒”時可能就需要多用幾千個指令周期,從而不必要地增大了功耗。



圖2:指針指向圖。
圖2:指針指向圖。


采用全面代碼生成(omniscient code generation, OCG)技術的新型編譯器則能選擇性地只保存每個特定的中斷所需的寄存器。這種全面代碼生成是通過在編譯代碼之前,從所有程序模塊中收集有關寄存器、堆棧、指針、對象和變量聲明的全面數據而實現的。OCG編譯器將所有程序模塊組合為一個大的程序,然后將其加載到一個調用關系結構圖中。根據這個調用圖,OCG代碼發生器創建一個指針參考圖,圖中顯示出一個變量地址每一次被訪問的實例,加上每次一個指針的值被賦給另一個指針的實例(不論是直接賦值、通過函數返回值賦值、函數參數傳遞賦值或通過其它指針間接賦值)。然后,編譯器會識別所有可能被每個指針指向過的對象,再利用這一信息來確定每個指針需要訪問的到底有多少內存空間。


OCG編譯器確切地知道哪些函數調用了其它函數,或被其它函數調用,哪些變量和寄存器是必需的,哪些指針指向的是哪些存儲器塊。這些信息就讓編譯器能夠確定程序中每個中斷會用到哪些寄存器,從而據此生成代碼,最小化代碼長度和保存與恢復中斷背景所需的指令周期數。


編譯器根據代碼在編譯時的狀態來動態確定每個中斷所需背景寄存器的多少。在OCG編譯器的編譯結果中,最少時,一個中斷可能只需要17個指令周期——其中10個用于保存背景信息,7個用于恢復。最多時也不過25個指令周期。與傳統編譯器相比,OCG編譯器將中斷相關的指令周期數減小了40%到60%。


根據應用的不同,通過編譯可節約的指令周期數可能非常大。例如,一個鼠標每秒鐘產生300次中斷,這些中斷會占用處理器所有工作周期的不到1%。而一個靠中斷驅動的波特率為480,600bps的串行通信端口每秒則會產生24,000個中斷。如果采用傳統的每個中斷需42條指令周期(即168個時鐘周期)來保存和恢復中斷背景的編譯器,那么每秒中斷會占用超過403萬零2千個CPU周期,或者說會占用一個20 MHz PIC16 20%的可用周期。而如果采用OCG編譯器,每個中斷平均只需21個指令周期(即84個時鐘周期),那么CPU周期的占用量會降低至201萬6千,在保存和恢復中斷背景信息上節約一半的時鐘周期,從而讓CPU得以將其工作周期的10%用于睡眠模式。假設CPU在工作模式下電流為10mA,睡眠模式下為1uA,那么OCG編譯器就能將MCU的功耗降低約1mA,也就是10%。


分塊式存儲器結構也會浪費指令周期


許多8位和16位微控制器中的存儲器都是分塊式的,不能同時訪問。在不同的存儲器塊之間切換需要執行至少兩條塊選擇指令。因此,若要將一個存儲器塊內的數據寫入另一塊,就必須執行塊選擇指令。顯然,將一個函數需要訪問的所有變量保存在同一個存儲器塊中就能減少塊選擇指令,從而減少應用所需的總指令周期數。但傳統編譯器無法識別哪些函數調用的是哪些變量,因此也就無法優化這些函數的內存分配。同時,這些編譯器也無法得知某個特定的存儲器塊是否會被代碼在任何地方選中。因此,不論一個存儲器塊是否已被選中,這些編譯器都會自動為每一次存儲器訪問生成塊選擇指令。


有些編譯器廠商已通過提供存儲塊限定子(bank qualifier)作為C代碼的擴展以識別變量地址,解決了這一問題。程序員可以通過使用這些非標準也不可移植的代碼,手動將變量分配給存儲器塊。采用塊限定詞允許編譯器將某個確切的存儲器塊看作其內部的一個對象,從而減少編譯后產生塊選擇指令的條數。然而,該方法卻并不能保證因變量(dependent variable)會被分配到同一個存儲器塊中。因此,每當需要將一個存儲器塊中的變量寫入另一個存儲器塊時,仍需執行塊選擇指令。此外,要想在多個代碼模塊間追蹤所有的內存地址并確保所有指針都擁有正確的地址,這是一個冗長耗時的過程,它本身就可能引發編程錯誤。


相比而言,由于OCG編譯器對所有程序模塊中的每個寄存器、堆棧、指針、對象和變量聲明都很清楚,所以它能優化所有變量和寄存器的分配,以及編譯后的堆棧中所保存的每個指針和對象的大小和范圍。OCG編譯器無需程序員的任何干涉,就能優化地分配存儲器,從而最小化甚至消除應用所需的塊選擇指令。


OCG編譯器在一個可用的非分塊式存儲器中為全局和靜態變量分配固定地址,因而無需任何塊選擇指令。如果應用中沒有非分塊式的存儲器,那么這些全局和靜態變量就會視其大小、相應的特殊限定詞和他們被訪問的次數而被分配到某個特殊的存儲器塊中。因變量則會在可能的時候被分配到同一個存儲器塊中。


函數參數和自變量(auto variable)則被分配給編譯堆棧。如果某些變量的函數不是同時被調用,那么鏈接器會自動允許這些變量共享同一個內存地址,從而將RAM的使用降低多達99%。


通過將常被訪問的變量存儲在非分塊式存儲器中,并將所有因變量存儲在同一個存儲器塊中, OCG編譯器從根本上減少了CPU需執行的指令周期數,從而也就降低了這些MCU結構中消耗在塊選擇指令上的功率。由于OCG編譯器在代碼的任何一點都很清楚被選中的是哪個存儲器塊,因此當該存儲器塊已被選中時,它還避免了執行不必要的塊選擇指令。減少指令條數就減少了CPU需要執行的周期數,從而允許CPU在睡眠模式下保持更長時間。


采用OCG編譯器所能節約的總周期數很大程度上取決于它所編譯的應用,因而很難量化。但清楚程序當前選擇的是哪個存儲器塊這一特點就有可能將應用所需的總周期數降低30%到50%,而周期數的降低與MCU功耗之間直接是呈線性關系的。


表1:睡眠模式的各種狀態。
表1:睡眠模式的各種狀態。


本文小結


要想盡可能降低功耗,選擇低功耗器件并盡可能讓MCU保持在睡眠模式是最重要的兩種方法。然而,編譯器管理中斷以及內存使用的方式也會對MCU能夠保持在睡眠模式下的時間長短有很大影響。采用全面代碼生成技術的新型編譯器在節約指令周期和節約功耗方面能夠做出相當大的貢獻。


作者:Clyde Stubbs

   CEO

   H-TECH 軟件公司






下一篇: 高性能MIPS32 24K處理

上一篇: MEMS傳感器使TPMS方案