楊超 胡旭
摘 要:在嵌入式設備研發過程中,程序的更新是不可避免的問題。如果嵌入式設備數量眾多或者已經封閉安裝,使用連線下載方式重新將全部設備更新程序,將是一項困難的工作。所以使用遠程方式進行程序的更新是嵌入式設備必不可少的一項功能。無操作系統嵌入式設備一般在用戶程序段之前加入一段IAP程序段,在開機之后先運行IAP程序,如果需要升級程序進入接收狀態,最后將接收到的程序覆蓋用戶程序段完成升級。而內嵌操作系統的嵌入式設備就更容易一些,只需要增加一個接收升級指令的線程,將更新后的程序替換原有文件就完成了升級。這兩種處理方式大多數都是通過以太網接收升級包,而文章討論的嵌入式設備底層不具備以太網接口,而是使用CAN總線完成整個升級過程。
關鍵詞:CAN總線;遠程更新;Linux系統
中國飛機強度研究所自主研發設計生產的數據采集系統,結構如圖1所示。
客戶端使用以太網與通訊控制器相連接,而每一個通訊控制底下連接了數個采集模塊,每一個采集模塊都內嵌Linux操作系統。通訊控制器負責接收客戶端發送的各種命令,將命令解析后,按需要將解析后的命令通過控制器局域網絡(Controller Area Network,CAN)總線發送給相應對的采集模塊,采集模塊在收到命令后完成相應的任務并通過CAN總線將數據結果返回通訊控制器。通訊控制器將數個采集模塊返回的數據包整合,按照一定的格式打包返回給客戶端,這樣就完成了整個命令下發和數據返回的過程。在實際使用中,如果每一次更新都需要把采集模塊從機箱中拆出,更新后在安裝,這樣的工作量是非常巨大的。所以在本系統中使用遠程更新是非常必需的。由于采集模塊與通訊控制器之間只有CAN總線連接,而沒有以太網接口,如果需要完成遠程升級的任務,就無法按照以往的以太網方式進行[1]。本文詳細介紹如何使用CAN總線來完成整個升級的過程。
1 軟件設計說明
采集模塊的程序遠程更新的過程涉及兩部分的軟件設計:通訊控制器與采集模塊。通訊控制器負責接收升級命令和升級數據包并下發,這部分的遠程升級使用IAP方式,由于此方式使用較為廣泛,例程較多,比較簡單不再過多闡述。采集模塊使用Freescale 的i.MX6Q處理器,內嵌Linux操作系統[2]。程序流程如圖2所示。
在采集模塊中,處理正常工作所需要的執行文件之外,增加了update可執行文件,負責完成升級工作。在程序主線程運行過程中,如果收到上層發來升級的命令,主線程首先關閉與AD轉換相關的副線程,關閉主線程,然后開啟軟件升級線程。在軟件升級線程中,主要工作有:判斷升級類型、建立備份升級文件、接收升級數據、寫入備份文件、校驗文件、替換原有執行文件。在完成了升級線程所有步驟之后,將升級結果發送主機,然后板卡自動重啟執行更新后的程序。
在整個升級過程中需要注意以下兩個地方:(1)在開始執行升級前需要關閉正在運行的線程,因為升級的程序有可能就是正在執行的程序,如果邊執行邊進行文件替換有可能造成文件寫入錯誤。(2)需要建立備份文件,將所有更新的程序寫入,最后進行更新數據的校驗,如果校驗通過則開始替換原文件。
由于是使用CAN總線進行數據接收,每一個CAN數據包可接收8字節數據,除去命令頭、控制字節、計數字節,每一個CAN數據包只能發送4個字節的升級數據。并且系統在正常的升級過程中一次性會同時升級多個機箱,所以本系統在升級過程中充分利用了雙層通訊結構,在同時升級多個機箱的情況下,首先將需要升級的可執行文件使用以太網分別下發給各個通訊控制器,通訊控制器將數據暫存在本地。接下來通訊控制器將升級數據分解成多個4字節的CAN數據包依次下發給每一個采集模塊。本系統中CAN總線速度設置為750 kb/s,在同時升級8個板卡并且合理協調時間間隔后,在升級文件為2 M左右大小時,實測整個升級過程需要幾分鐘[3]。
2 程序說明
在升級線程啟動之后,首先進行外部資源的初始化,關閉相關的線程,然后進入命令接受狀態,根據命令種類不同進入不同的處理流程,隨后進入升級開始函數,首先打開備份文件,將收到的升級數據寫入備份文件,進行數據校驗,并記錄數據總數:
Data_Update_Start()
{
unsigned char write_buff[4],i;
if(first_open == 0)
{
first_open = 1;
txt_fd = open(“test_copy”, O_RDWR); //打開升級備份文件
if (-1 == txt_fd)
{
printf(“open error\n”);
}
else
{
printf(“open success,txt_fd = %d\n”, txt_fd);
}
}
for(i=0;i<4;i++)
write_buff[i] = recievedata[i+4];
ret = write(txt_fd, write_buff, recievedata[1]);
if (ret < 0)
{
printf(“write error.\n”);
update_count = -1;
}
CRC_check(); //數據校驗 如未通過校驗,客戶端會重新發送這一段數據
update_count = update_count + recievedata[1]; //升級數據計數
}
Data_Update_Finish()
{
unsigned char i,size;
unsigned long long_size;
close(txt_fd);
first_open = 0;
for(i=0;i<8;i++)
frame.data[i] = 0;
frame.data[0] = 0xF2;
frame.data[1] = DAU_number;
long_size = update_count& 0x000000ff;
size = (char) long_size;
frame.data[7] = size;
long_size = update_count& 0x0000ff00;
long_size = long_size >> 8;
size = (char) long_size;
frame.data[6] = size;
long_size = update_count& 0x00ff0000;
long_size = long_size >> 16;
size = (char) long_size;
frame.data[5] = size;
long_size = update_count& 0xff000000;
long_size = long_size >> 24;
size = (char) long_size;
frame.data[4] = size;
frame.can_dlc = 8;
nbytes = sendto(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr));
}
最后的升級完成函數中首先判斷升級上位機發送的升級指令中,指明的需要升級的可執行文件。然后將已經更新完成的備份文件替換掉原可執行文件。最后向上位機發送升級成功報告并重新啟動采集板卡,完成整個升級過程。此部分軟件考慮到篇幅限制不在此列出。
3 結語
按照以上的遠程升級軟件設計,理論課可同時進行255臺采集機箱的升級工作。由于CAN總線通訊升級部分各個機箱是并行運行,多臺升級與單臺采集機箱升級消耗時間幾乎相同。實際測試同時升級8臺機箱,更新AD采樣計算部分程序時,該部分可執行文件大小為2.2 M,共用時5分28秒。雖然從文件傳輸角度考慮速度比較慢,但是考慮到系統升級對于時間要求不高且此方法的遠程升級大大減少了現場拆裝工作量,節省了數十倍的時間,本文討論的測量系統的遠程升級功能已經圓滿完成了任務。
[參考文獻]
[1]宋寶華. Linux設備驅動開發詳解[M].2版.北京:人民郵電出版社,2008.
[2]MATTHEW N,STON R.Linux程序設計[M].4版.北京:人民郵電出版社,2007.
[3]斯洛斯.ARM嵌入式系統開發:軟件設計與優化[M].北京:北京航空航天大學出版社,2005.