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.

主站蜘蛛池模板: 日本在线亚洲| 亚洲αv毛片| 97成人在线视频| www精品久久| 成人国产免费| 一本视频精品中文字幕| 91在线播放免费不卡无毒| 尤物特级无码毛片免费| 专干老肥熟女视频网站| 伊人中文网| 亚洲国产天堂久久综合| 亚洲精品成人片在线观看| 欧美成人手机在线观看网址| 人妻免费无码不卡视频| 久久国产精品嫖妓| 99精品福利视频| 找国产毛片看| 国产99精品久久| 欧美人在线一区二区三区| 好久久免费视频高清| 国产 日韩 欧美 第二页| 欧美不卡视频一区发布| 四虎国产精品永久一区| 天天摸天天操免费播放小视频| 亚洲欧美另类日本| 自拍偷拍欧美| 亚洲精品图区| 亚洲男人天堂2020| 国产99视频精品免费观看9e| 无码国内精品人妻少妇蜜桃视频| 日本91在线| 尤物视频一区| 91免费片| 国产在线视频自拍| 国产精品视频999| 国产精品短篇二区| 亚洲成av人无码综合在线观看| 美女被操黄色视频网站| 国产人人乐人人爱| 亚洲中文字幕久久无码精品A| 毛片网站观看| 亚洲福利网址| 久夜色精品国产噜噜| 99热6这里只有精品| 在线一级毛片| 一区二区三区在线不卡免费| 91国内在线观看| 国产精品成人AⅤ在线一二三四| 国产福利在线免费观看| 亚洲精品手机在线| 亚洲国产中文在线二区三区免| 久久久久免费看成人影片 | 99尹人香蕉国产免费天天拍| 欧美午夜在线视频| 亚洲精品无码抽插日韩| 国产一二三区在线| 亚洲无线观看| 性视频久久| 超清无码熟妇人妻AV在线绿巨人| 热思思久久免费视频| 2020国产精品视频| 欧美日韩精品一区二区视频| 日韩麻豆小视频| 三级欧美在线| 一区二区三区精品视频在线观看| 天堂在线www网亚洲| 日韩天堂视频| 狠狠色香婷婷久久亚洲精品| 狂欢视频在线观看不卡| 少妇精品网站| 国产亚洲精久久久久久久91| 正在播放久久| 尤物亚洲最大AV无码网站| 日韩免费毛片| 一级全黄毛片| 成人在线欧美| 国产美女精品一区二区| 成年网址网站在线观看| 国产素人在线| 91网址在线播放| 国产美女一级毛片| 黄色网址手机国内免费在线观看|