999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

電力設備用MCU嵌入式程序分塊更新技術

2016-06-21 07:02:44江蘇林洋能源股份有限公司陳昊琦沈煜迪黃柳勝
電子世界 2016年11期

江蘇林洋能源股份有限公司 陳昊琦 沈煜迪 黃柳勝

電力設備用MCU嵌入式程序分塊更新技術

江蘇林洋能源股份有限公司 陳昊琦 沈煜迪 黃柳勝

【摘要】文章介紹電力設備MCU的嵌入式程序按功能或按函數級別對增加、修改、刪除代碼進行精確分塊更新的工作原理,指出采用分散加載機制方法,可對MCU劃分代碼區域,敘述使用偽指令、函數殼、void ★、void ★★、void ★★★方法保證因修改程序代碼或變量,需要更新的程序范圍不會擴大的設計方法。該技術已經在實際項目中使用,可以根據產品功能需求的變化精確、快速更新程序。

【關鍵詞】嵌入式程序分塊更新;分散加載機制;函數殼;空類型指針

一、引言

隨著智能電網建設的不斷推進,在電力設備中MCU的應用越來越廣泛,在很多情況下,如現場使用的設備需要增加新功能、現場應用運行后發現了BUG等等,都要求更新MCU內部的嵌入式程序;同時由于電力設備往往工作在無人值守的環境下,且數量眾多,一旦需要對數以萬計的終端進行現場更新,就會耗費大量現場服務的人力、物力和時間。

隨著通信技術的發展,電力設備使用GPRS/CDMA進行遠程通信成為現實;同時IAP在線應用編程技術的出現使得MCU不必增加專用編程接口,就可實現本地或遠程下載來實現程序的更新。

一些廠家采用了IAP + GPRS/CDMA通信方式實現遠程程序更新。該方案雖然解決了現場升級的繁重工作量。但由于目前廣泛使用的程序更新方式都是將MCU的嵌入式程序全部更新,即如果僅僅修改了一個函數的代碼或增加、刪除一個功能甚至只修改一行代碼都需要更新整個程序。

同時由于GPRS/CDMA的傳輸速度低、并根據流量收費,當程序代碼量大、需要頻繁升級時,仍會導致升級的時間長、流量大、收費高等問題的產生。

本文敘述的嵌入式程序分塊更新技術,可以按功能或按函數級別對修改的代碼進行精確的分塊更新,從根本上避免在任何情況下都必須更新全部程序的低效率工作方式,同時也有效解決通過GPRS/CDMA遠程更新設備程序所造成的升級時間長、流量大、收費高的問題。

二、嵌入式程序編譯、運行原理

目前,國內使用的MCU大部分屬于中低端設備,不具備運行Linux的條件,普遍采用前后臺系統或嵌入式實時操作系統如uCos運行程序。同時,為了提高開發效率,很多嵌入式程序采用C、C++語言編寫。

根據編譯原理如圖1所示,源代碼形成可執行文件需要經過預處理、編譯、匯編、鏈接四個階段。最終生成的目標程序包含了代碼段(Code)、只讀數據段(RO-data)、已初始化讀寫數據段(RW-data)、未初始化數據段(BSS)、堆棧段等信息。

圖1 生成目標程序流程

圖2 目標程序運行時布局

1、代碼段(Code)由程序中可執行的機器代碼組成。程序語句進行編譯后,形成機器代碼。在執行程序的過程中,CPU的程序計數器指向代碼段的每一條機器代碼,并由處理器依次運行。

2、只讀數據段(RO-data)是程序運行時不會被更改的數據,如常量。使用這些數據類似查表式操作,由于不需要更改,因此只需放置在只讀存儲器中。

3、已初始化讀寫數據段(RW-data)是在程序中聲明且具有初值的變量,如已初始化的全局變量、靜態變量。這些變量需要占用存儲器的空間,在程序執行時它們需要位于可讀寫的內存區域內,并具有初值,以供程序運行時讀寫。

4、未初始化數據段(BSS)也是在程序中聲明,但沒有初始化的變量,如未初始化的全局變量和靜態變量。這些變量在程序運行之前不需要占用存儲器的空間。

5、堆內存只在程序運行時出現,一般由程序員分配和釋放空間,如new、delete操作。

6、棧內存也只在運行時出現,程序臨時創建的局部變量、函數內部使用的變量、函數的參數以及返回值將使用??臻g,??臻g由編譯器自動分配。

Code、RO-data、RW-data、BSS屬于靜態存儲區域;堆和棧屬于動態區域。Code、RO-data和RW-data在鏈接之后生成,BSS在程序初始化時候開辟,而堆和棧在程序運行中分配和釋放。

目標程序運行時分為映像文件和運行兩種狀態,具體布局如圖2所示。通過工具將映像文件固化在MCU的ROM或Nor-Flash中,映像文件中包含了Code、RO-data以及RW-data;

程序運行的初始化階段,各段必須載入到內存RAM的恰當位置,其中RW-data復制到內存的Data區域中,各個BSS區域將在內存中開辟空間并清零,堆和??臻g一般是向前擴展,棧由編譯器管理,程序運行后堆大小分配由程序決定(見圖2)。

三、分塊更新要點和設計思路

通過上文對嵌入式程序的編譯和運行原理分析介紹,需要關注以下2點:

1、程序編譯后生成的目標代碼順序存放,緊密地靠在一起。若增刪程序后再編譯,生成的目標代碼將和原來大相徑庭。

2、目標程序使用的存儲空間見表1:

表1 目標程序使用存儲空間匯總

程序編譯后,由于RW-data段會保存在目標代碼中,并和其他段緊靠一起。若增刪RW-data中的變量,也會導致再編譯生成的目標代碼和原來區別非常大。

RO-data段存放在ROM中,由于程序運行時不會被修改,所以也可以看成Code段。

分塊更新的目標是“嵌入式程序可以按功能或按函數級別對增加、修改、刪除代碼進行精確分塊更新,減少更新的代碼量”,即只更新增加、修改、刪除的代碼,而且是按照功能模塊或函數級別更新。但本節提到的2個關注點已經指出,若直接修改代碼或RW-data段中的變量,會導致編譯生成的目標代碼改動非常大,給人一種“牽一發而動全身”的感覺,無法滿足分塊更新的要求。

為實現分塊更新的目標,需要滿足以下3點:

1、按功能模塊或函數級別對代碼劃分區域

源程序編譯后,目標代碼順序緊靠存放。修改源程序后必然導致目標代碼的大小變化,其后的代碼位置也隨之改動。按功能模塊或函數級別對目標代碼劃分開獨立的區域,區域的位置按更新的頻率設定,更新頻率低的區域放置在ROM低地址處,更新頻率高的區域放置在ROM高地址處;區域的大小根據實際情況預留一部分備用空間,在實際使用過程中若區域不夠時,可在ROM中劃出一塊還未使用的區域繼續。

源程序中函數一定是很多的,按函數級別劃分區域帶來的工作量相當大。在實際使用時,建議采用按功能模塊級別劃分區域。

使用偽指令劃分區域,根據編譯原理應在預處理階段實施。本文將在下一節介紹使用分散加載機制方法劃分代碼。

2、代碼精確更新,減少更新程序的范圍

如圖3所示,功能模塊之間、函數之間、模塊和函數之間需要相互調用。若僅僅對代碼劃分區域,一個區域內的代碼修改編譯后,與之相互調用函數的區域會改變,隨之又影響到其他有關聯的區域。

圖3 區域關聯

圖4 區域之間調用函數流程

這種情況導致更新一個區域時,與之有關聯的區域,甚至與關聯區域有關聯的區域都需要更新。

使用偽指令和函數殼既切斷區域之間連帶更新,又保證關聯區域正常工作。本文將在下一節闡述處理的方法。

3、RAM中變量改變時減少更新程序的范圍

由于模塊、函數之間相互調用,若函數的參數或模塊內的變量需要改變時,也會導致更新一個區域后,與之有關聯的其它區域都需要更新。

為了減少更新程序的范圍,使用1級、2級甚至3級空類型指針變量,使變量修改后再編譯減少對目標代碼的影響。

四、實施分塊更新的方法

上一節討論了需要滿足3要點以實現分塊更新的目標,這節詳細闡釋每個要點實施的方法。

(一)分散加載機制劃分代碼區域

在第2節中已經介紹了映像文件及其組成,要構建映像文件的存儲器映射,鏈接器必須有:描述如何分組成區的分組信息、描述映像區在存儲器映射中放置地址的放置信息。

分散加載機制允許為鏈接器指定映像文件的存儲器映射信息,可實現對映像組件分組和布局的全面控制,如固定函數的位置,即使周圍程序已經被修改并重新編譯。分散加載通常用于具有復雜存儲器映射的映像(盡管也可用于簡單映像),適合在加載和執行時映射中多個區域是分散的情況。

源程序在編譯前,利用開發平臺如Keil μVision自帶的分散加載機制功能,按程序設計的功能模塊劃分多個區域,并設置區域位置及大小。下面例子是相關代碼及注釋。

使用分散加載機制將所有程序文件按功能級別劃分ROM的地址空間。區域劃分后,功能模塊內部的函數相互調用、修改,不影響其他區域。

(二)偽指令和函數殼減少更新程序的范圍

功能模塊劃分完區域,區域之間會相互調用函數,為減少程序更新的范圍,需要在不影響正常運行的前提下切斷區域之間的連帶更新。對需要相互調用的函數建立相應函數殼,同時使用偽指令固定函數殼在區域內的位置。下面例子是相關代碼及注釋。

2個區域之間調用函數的流程如圖4所示。

函數殼起到“中間人”的角色,區域之間調用函數時都需要先通過函數殼。同時固定了函數殼的位置后,對應的函數修改代碼只會改變該函數所在的區域,不會影響到調用它的其他區域,從而切斷區域之間的連帶更新,達到了減少更新程序范圍的目的。

(三)使用空類型指針減少更新程序的范圍

4.2節的例子中函數沒有使用參數,實際情況下函數經常需要傳遞各種參數。同時功能模塊中還有各種變量需要使用或被其他模塊調用。本節對這2種情況的處理做詳細說明。

函數傳遞各種參數、或更新代碼后傳遞的參數改變了,如果直接使用函數殼加xxx參數,還是會造成關聯區域更新范圍擴大。使用1級(或2級)空類型指針傳遞實際參數,即使實際參數改變也不會擴大關聯區域的更新范圍。下面例子是相關代碼及注釋。

前文中對目標程序使用的存儲空間做了匯總,詳見表1。功能模塊中已初始化的全局變量、靜態變量(屬于RW-data段)需要占用ROM存儲空間,而且其他模塊也能調用這些變量。若修改變量也會造成關聯區域更新范圍擴大。使用2級(或3級)空類型指針代替變量,保證了即使實際變量改變也不會擴大關聯區域的更新范圍。下面例子是相關代碼及注釋。

void** pVariate;// 2級空指針變量

pVariate = new void *[RowCount]; // 動態申請變量數組

// 指針變量關聯實際變量

使用n級空類型指針可以避免編譯器為RW-data段分配ROM存儲空間。

五、結語

采用本文介紹的分塊更新技術,將電力設備用MCU的嵌入式程序按功能模塊或函數級別進行精確的分塊,產品投運后可以根據功能需求變化,只對更改了功能的模塊進行更新,從而避免了在任何情況下都必須更新全部程序的低效率工作方式,同時也有效解決了通過GPRS/CDMA遠程更新設備程序所造成的升級時間長、流量大、收費高的問題。

分塊更新技術已經在公司多個項目中實際應用,效果極佳。我們在II型集中器項目中以修改LED驅動為例做過統計,若沒有使用分塊更新技術編譯、鏈接后生成的Bin文件達到330k左右,通過GPRS網絡遠程更新時每2秒傳輸1024字節,需要11~15分鐘傳輸完畢。使用分塊更新技術后生成的LED驅動Bin文件只有3k左右,通過GPRS網絡僅需6~10秒傳輸完畢。分塊更新技術降低了產品投運后的維護成本,增強了產品的市場競爭力。

當然,分塊更新技術在實施過程中,需要注意到動態申請空類型指針變量會多占用一些內存,在內存不足的情況下需要及時釋放;而且,在編寫調試程序的時候也會有一定的難度。

參考文獻

[1]陳火旺.程序設計語言∶編譯原理(第3版)[M].國防工業出版社, 2014.

[2] Kenneth A.Reek. C和指針[M].人民郵電出版社,2008.

[3] Keil uVision4中文教程,2009.

主站蜘蛛池模板: 国产日韩欧美中文| 欧美一区精品| 午夜啪啪福利| 精品国产成人高清在线| 热思思久久免费视频| 亚洲国产日韩在线观看| 97人人做人人爽香蕉精品| 欧美不卡二区| 久久无码免费束人妻| 天天色天天综合| 97在线免费| 亚洲人在线| 91人人妻人人做人人爽男同| 色久综合在线| www亚洲天堂| 亚洲国产综合精品中文第一| 国产综合精品一区二区| 日韩精品高清自在线| 天天色综网| 欧美伦理一区| 精品亚洲国产成人AV| 91九色视频网| 国产精品一区二区久久精品无码| 亚洲高清在线天堂精品| 久久人妻系列无码一区| 97国产在线播放| 1024国产在线| 久久伊人操| 美美女高清毛片视频免费观看| 自慰网址在线观看| 99re热精品视频中文字幕不卡| a毛片在线播放| 亚洲嫩模喷白浆| 人妻无码中文字幕第一区| 青草视频网站在线观看| 国产精品永久不卡免费视频| 视频一本大道香蕉久在线播放| 99偷拍视频精品一区二区| 97在线观看视频免费| 国产在线八区| 久久久久人妻一区精品色奶水| 久久久久亚洲精品无码网站| 内射人妻无套中出无码| 91无码视频在线观看| 天天躁狠狠躁| 91最新精品视频发布页| 又粗又硬又大又爽免费视频播放| 国产精品密蕾丝视频| 国产h视频免费观看| 欧美成在线视频| 国产精品爽爽va在线无码观看 | 国产精品成人一区二区不卡| 成人字幕网视频在线观看| 青青操视频免费观看| 91在线日韩在线播放| 无码综合天天久久综合网| 亚洲天堂啪啪| 亚洲Av激情网五月天| 99在线观看国产| 午夜视频免费试看| a天堂视频| 成AV人片一区二区三区久久| 亚洲码在线中文在线观看| 久久a级片| 国产无码高清视频不卡| 国产av色站网站| 亚洲成年网站在线观看| 国产精品美女自慰喷水| 欧美精品亚洲精品日韩专区| 国产乱人免费视频| 亚洲无码精彩视频在线观看| 97se亚洲综合在线韩国专区福利| 精品少妇人妻av无码久久| 国产亚洲日韩av在线| 996免费视频国产在线播放| 日韩小视频在线观看| 巨熟乳波霸若妻中文观看免费| 波多野结衣在线一区二区| 久久99精品久久久久纯品| 亚洲一区二区成人| 色香蕉影院| 999国内精品视频免费|