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、棧內存也只在運行時出現,程序臨時創建的局部變量、函數內部使用的變量、函數的參數以及返回值將使用棧空間,棧空間由編譯器自動分配。

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區域將在內存中開辟空間并清零,堆和棧空間一般是向前擴展,棧由編譯器管理,程序運行后堆大小分配由程序決定(見圖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.

主站蜘蛛池模板: 99在线视频免费观看| 国产国语一级毛片在线视频| 国产三区二区| 国产精品无码作爱| 国产91丝袜| 伊人五月丁香综合AⅤ| 国产精品久久久久久搜索| 亚洲综合片| 亚洲欧美精品一中文字幕| 国产美女免费网站| 九九九久久国产精品| 亚洲国产精品不卡在线| 免费av一区二区三区在线| 高清精品美女在线播放| 欧美亚洲欧美区| 97精品久久久大香线焦| 深爱婷婷激情网| 色天天综合| 欧美激情伊人| 伊人成人在线| 亚洲成肉网| 国产91小视频在线观看| 亚洲成人网在线播放| 亚洲欧美日韩另类在线一| 国内黄色精品| 亚洲高清在线天堂精品| 国产亚洲精| 午夜毛片免费看| 亚洲动漫h| 青青草原国产av福利网站| 全部免费毛片免费播放| 青青操国产视频| 国产97色在线| 日韩欧美国产区| 99久久精品免费观看国产| 欧美一级99在线观看国产| 久久免费看片| 成年A级毛片| 国产69囗曝护士吞精在线视频| 亚洲日韩精品无码专区97| 国产菊爆视频在线观看| 国产伦片中文免费观看| 九色视频最新网址| jizz亚洲高清在线观看| 欲色天天综合网| 国内老司机精品视频在线播出| 亚洲一区二区精品无码久久久| 波多野结衣一二三| 亚洲国产中文综合专区在| 五月婷婷丁香综合| 久久中文电影| 午夜免费视频网站| 日日噜噜夜夜狠狠视频| 亚洲电影天堂在线国语对白| 91蝌蚪视频在线观看| 人妻一区二区三区无码精品一区| 国产一级小视频| 又污又黄又无遮挡网站| 免费黄色国产视频| 亚洲欧美一区二区三区图片| 亚洲最大看欧美片网站地址| 欧美日本视频在线观看| 亚洲欧美不卡视频| 国产欧美视频一区二区三区| 中文字幕亚洲乱码熟女1区2区| 丁香综合在线| 日韩在线播放欧美字幕| 欧美日本中文| 国产精品视频白浆免费视频| 天堂在线www网亚洲| 999在线免费视频| 精品丝袜美腿国产一区| 91人妻日韩人妻无码专区精品| 日韩精品毛片人妻AV不卡| 国产精品男人的天堂| 久久99国产乱子伦精品免| 欧美色图第一页| 女人18毛片水真多国产| 在线毛片免费| 国产成人精品免费av| 亚洲国产精品无码久久一线| 亚洲无线一二三四区男男|