聶濤
摘 ?要: 針對嵌入式軟件開發采用交叉開發模型,需要頻繁把程序從宿主機下載到目標機的要求,研究設計基于Linux的USB集成下載工具。根據USB協議,開發Linux系統的USB驅動模塊,基于USB驅動模塊,設計出Linux文件下載程序。該工具運行于Linux系統,并利用TQ2440,OK6410,TQ210開發板進行測試。測試結果表明,該工具可以支持2440系列、6410系列、210系列的ARM開發板,并具有很好的擴展性和移植性。
關鍵詞: USB驅動; 下載工具; Linux; ARM
中圖分類號: TN915?34;TP311.1 ? ? ? ? ? ? ? 文獻標識碼: A ? ? ? ? ? ? ? ? ? ?文章編號: 1004?373X(2014)23?0087?04
Design and implementation of USB download tool based on Linux
NIE Tao
(School of Physical Electronics, University of Electronic Science and Technology of China, Chengdu 610054, China )
Abstract : The development of embedded system needs frequent software download and update, so the USB integrated download tool based on the Linux is designed. The USB driver module of Linux system was developed based on the USB protocol, and then the download process for Linux files was designed based on the USB driver module. The tool was tested on TQ2440, OK6410 and TQ210 embedded development platforms. The test results show that it can support the embedded development platforms of 2440 series, 6410 series and 210 series. It has perfect expansibility and portability.
Keywords: USB driver; download tool; Linux; ARM
0 ?引 ?言
隨著數字信息技術和網絡技術不斷的發展,嵌入式系統以體積小、功耗低、可靠性高、性能強以及基于面向具體行業應用等突出特點, 目前已經廣泛地滲透到國防、農業、消費電子、教育、信息家電、工業控制、網絡通信等各個領域,對于各行各業的產品升級、技術提升、生產效率提高等方面都起到了非常重要的推動作用[1]。目前,嵌入式處理器的類型主要有ARM、MIPS、SC?400、PowerPC等系列產品。其中,采用ARM核的嵌入式處理器已廣泛應用于消費類電子產品、工業控制、網絡通信系統以及無線系統的各個領域。ARM核嵌入式處理器約占嵌入式處理器75%以上的市場份額,對于ARM芯片的嵌入式系統開發一般采取交叉開發模型。所謂交叉開發模型就是在嵌入式開發過程中有宿主機和目標機的角色之分,宿主機是編寫、編譯、鏈接嵌入式軟件的計算機,目標機則是運行嵌入式軟件的硬件平臺。嵌入式系統開發過程中,需要頻繁的從宿主機上下載程序來更新目標機的程序,因此需要簡單、高效、方便的下載方式。這樣不僅能提高嵌入式系統的開發效率,而且還可以縮短嵌入式產品的上市時間。
當前嵌入式系統開發過程中下載程序的方式有很多不足和缺點,尤其下載軟件不能同時支持幾個系列ARM處理器的開發板,并且下載軟件十分不穩定,非常依賴于下載軟件的特定運行環境,嚴重影響了嵌入式系統的開發效率,因此需要開發一款新的下載軟件,來適應嵌入式系統開發的需要。本文在研究分析 USB 接口協議與 Linux系統驅動的基礎上,開發設計了一款基于USB接口的嵌入式集成下載工具。該工具可以穩定運行于Linux系統上,并且同時支持ARM9處理器2440系列開發板、ARM11處理器6410系列開發板、ARM Cortex?A8處理器210系列開發板,能夠勝任不同階段的下載任務,而且軟件具有很好的穩定性、可移植性和擴展性[2?5]。
1 ?USB驅動設計
Linux操作系統把設備看作成文件來處理,這類文件稱作設備文件,存放在Linux的dev目錄下, Linux系統通過對這些設備文件的操作來控制硬件設備[6]。同樣,USB驅動程序也會為USB設備創建設備文件。USB驅動程序是USB芯片和Linux系統內核之間的接口,為應用程序屏蔽了USB硬件設備的細節,應用程序可以通過USB設備文件的操作來實現對USB設備的控制與數據的讀/寫。USB驅動程序設計主要分為兩個模塊,分別為USB設備注冊和USB設備注銷。USB設備驅動程序在注冊和銷毀時侯需要用到一個結構體struct usb_driver。這個結構體需要在驅動程序中完成編寫,包括許多變量和回調函數,它向USB核心代碼描述了USB驅動程序的功能。
static struct usb_driver secbulk_driver= {
.name= "secbulk", ?//驅動程序的名字
.probe= secbulk_probe, //探測函數
.disconnect= secbulk_disconnect, ?//斷開函數
.id_table= secbulk_table, ?//驅動程序所支持的設備列表
.supports_autosuspend=0,
};
調用以struct usb_driver結構體指針作為參數的usb_register_driver函數,將struct usb_driver結構體指針注冊到 USB核心。USB驅動程序的注冊代碼如下:
static int __init secbulk_init(void)
{
int result;
printk(KERN_INFO "secbulk:secbulk loaded\n");
/*把該驅動程序注冊到USB子系統*/
result = usb_register(&;secbulk_driver);
if (result)
printk(KERN_ERR "secbulk:usb_register failed: %d",result);
return result;
}
USB驅動程序卸載時,調用usb_deregister_driver函數將struct usb_driver結構體從內核中注銷。執行該函數時,調用斷開函數把當前綁定到該USB驅動程序上的所有USB接口都斷開。USB驅動程序的注銷代碼如下:
static void __exit secbulk_exit(void)
{
/*把驅動程序從USB子系統注銷*/
usb_deregister(&;secbulk_driver);
printk(KERN_INFO"secbulk:secbulk unloaded\n");
}
1.1 ?驅動程序支持的設備列表
struct usb_device_id *id_table是指向struct usb_device_id表的結構體指針,該表包含了該USB設備驅動支持的所有不同類型的USB設備。增加對USB設備的支持,需要在該表中添加USB設備制造商ID和產品ID。因此在secbulk_table表中添加2440系列開發板、6410系列開發板、210系列開發板的USB設備制造商和產品的ID:
static struct usb_device_id secbulk_table[]=
{
{ USB_DEVICE(0x5345, 0x1234)}, //2440系列
{ USB_DEVICE(0x04e8, 0x1234)}, //6410系列
{ USB_DEVICE(0x18d1, 0x1234)}, //210系列
};
1.2 ?探測函數
int(*probe)(struct usb_interface * intf, const struct usb_device_id *id )是USB驅動程序中的探測函數的指針。當一個USB設備被安裝并且USB核心認定該USB驅動程序應該處理時,探測函數才會被調用。探測函數需要檢查傳遞給它的USB設備信息,然后確定驅動程序是否適合該設備[7]。當驅動程序確定適合設備時,探測函數會調用usb_register_dev函數來把USB設備注冊到USB核心。usb_register_dev函數有struct usb_interfac指針和struct usb_class_driver結構的指針兩個參數。struct usb_class_driver結構體包含描述設備的名稱、指派次設備號的開始值和設備相關操作的結構體的指針等成員變量。以下是probe函數下的探測部分代碼:
for(i=0; i <; iface_desc?>;desc.bNumEndpoints; i++)
{
endpoint=&;(iface_desc->;endpoint[i].desc);
if(!dev->;bulk_out_endpointAddr&;&;usb_endpoint_is_bulk_out(endpoint))
{
/*該驅動不支持此設備*/
printk(KERN_INFO"secbulk:bulkout endpoint found!\n");
dev->;bulk_out_endpointAddr=endpoint->;bEndpointAddress;
break;
}
}if(!(dev->;bulk_out_endpointAddr))
{
ret = -EBUSY; goto error;
}
/*注冊設備*/
ret=usb_register_dev(interface,&;secbulk_class);
if(ret)
{
/*某些情況造成我們不能注冊該驅動程序*/
printk(KERN_ERR"secbulk: usb_register_dev failed!\n");
return ret;
}
struct usb_class_driver結構體的初始化代碼如下:
static struct usb_class_driver secbulk_class = {
.name = "secbulk%d", ?//設備名字
.fops = &;secbulk_fops, ?//設備相關操作結構體指針
.minor_base= 100, ? //此設備號開始值
};
static struct file_operations結構體的初始化代碼如下:
static struct file_operations secbulk_fops = {.owner = THIS_MODULE,
.read = secbulk_read, ?//讀操作
.write = secbulk_write, ?//寫操作
.open = secbulk_open, ?//打開
.release= secbulk_release, ?//釋放
};
1.3 ?斷開函數
void(*disconnect)(struct usb_interface *intf)是USB驅動程序的斷開函數的函數指針。當struct usb_interface結構體從Linux系統中移除或者USB驅動程序從USB核心中卸載時,USB核心將會調用該函數做相關的清理工作[8]。secbulk_disconnect斷開函數代碼如下:
static void secbulk_disconnect(struct usb_interface *interface)
{
struct secbulk_dev *dev = NULL;
printk(KERN_INFO"secbulk:secbulk disconnected!\n");
/*防止競爭*/
dev = usb_get_intfdata(interface);
if( NULL != dev )
kfree(dev);
/*返回次設備號*/
usb_deregister_dev(interface, &;secbulk_class);
}
最后,將USB驅動程序編譯成驅動模塊,并加載到Linux系統中。
2 ?Linux下載程序設計
Linux系統成功加載USB驅動模塊后,會在Linux系統的dev目錄下生成USB的設備文件,通過操作USB的設備文件可以操作USB設備[9?10]。所以Linux系統和目標機ARM數據傳輸必須通過USB的設備文件進行,數據傳輸過程如下:首先打開USB設備文件,通過USB設備文件把數據寫入目標機ARM的內存中;目標機ARM接收數據后,會產生USB中斷,把數據從ARM的內存中讀入ARM的NAND FLASH中。根據Linux系統和目標機ARM數據傳輸過程設計Liunx下載程序。Linux下載程序流程圖如圖1所示。
Linux下載程序核心代碼如下:
printf("Start Sending data...\n");
size_tremain_size= file_stat.st_size+10;
size_t block_size = 512;
size_t written = 0;
/*從內存中寫入ARM內存中*/
while(remain_size >; 0) {
size_t to_write = remain_size >; block_size ? block_size:remain_size;
size_t real_write = write(fd_dev, file_buffer+written, to_write);
if( to_write != real_write) {
printf(" write ?/dev/secbulk0 failed! ?to_write = %u real_write = %u \n" , to_write ,real_write );
return 1;
}
remain_size -= to_write;
written += to_write;
printf("\rSent %lu%% \t %u bytes !", written*100/(file_stat.st_size+10), ?written);
fflush(stdout);
}
最后,利用GCC編譯器把Linux下載程序編譯成下載軟件。運行Linux下載軟件,傳遞文件名并指定下載內存地址的參數就可以把文件寫入ARM目標機的NAND FLASH中。
<;E:\2014年23期\2014年23期\Image\19t1.tif>;
圖1 Linux下載程序流程圖
3 ?測試結果
測試軟件的功能,需要利用硬件平臺。本文中Linux系統選用Redhat企業版6,嵌入式開發平臺為2440系列的TQ2440、6410系列的OK6410、210系列的TQ210分別進行測試。測試方法是將LED點燈程序通過Linux下載軟件下載到ARM開發板的NAND FLASH中,下載完成后,將ARM開發板撥到NAND FLASH啟動;如果ARM開發板中的LED點亮,說明USB驅動程序和Linux下載程序是可行的。
TQ2440測試結果如圖2所示;OK6410測試結果如圖3所示;TQ210測試結果如圖4所示。
<;E:\2014年23期\2014年23期\Image\19t2.tif>;
圖2 TQ2440測試結果
<;E:\2014年23期\2014年23期\Image\19t3.tif>;
圖3 OK6410測試結果
<;E:\2014年23期\2014年23期\Image\19t4.tif>;
圖4 TQ210測試結果
4 ?結 ?語
本文針對嵌入式系統交叉開發模型中,需要頻繁從linux宿主機中下載程序到目標機ARM更新程序的問題,開發和設計了一款基于USB的Liunx下載軟件。軟件解決了每個系列ARM開發板單獨需要一款下載軟件的問題,成功地實現了一款支持不同系列ARM開發板的USB的Linux下載軟件。軟件特點是穩定運行于各個版本Linux系統之上,并且支持ARM9處理器2440系列開發板、ARM11處理器6410系列開發板、ARM Cortex?A8處理器210系列開發板,實現下載功能。
參考文獻
[1] 王曉惠.基于ARM?Linux的交叉編譯環境的創建[J].電腦知識與技術,2007(15):55?58.
[2] 姚振國.基于嵌入式Linux的USB集成下載工具的設計與開發[D].成都:電子科技大學,2013.
[3] 王瓊.基于嵌入式Linux數據采集系統的軟件設計與實現[D].成都:電子科技大學,2013.
[4] 彭敏.基于ARM7的工業控制數據采集系統的研究[J].現代電子技術,2011,34(2):12?14.
[5] 李麗宏,郝志剛.嵌入式Linux的USB驅動設計[J].電子設計工程,2011(10):56?59.
[6] 寧玉玲,陳瓊,馬楊龍.Linux設備驅動模型框架的分類研究[J].現代電子技術,2013,36(4):5?8.
[7] 魏永明,耿岳,鐘書毅.Linux設備驅動程序[M].3版.北京:中國電力出版社,2006.
[8] 宋寶華.Linux設備驅動開發詳解[M].2版.北京:人民郵電出版社,2002.
[9] 韋東山.嵌入式Linux應用開發完全手冊[M].北京:人民郵電大學出版社,2008.
[10] 楊水清.ARM嵌入式Linux系統開發技術詳解[M].北京:電子工業出版社,2008.
TQ2440測試結果如圖2所示;OK6410測試結果如圖3所示;TQ210測試結果如圖4所示。
<;E:\2014年23期\2014年23期\Image\19t2.tif>;
圖2 TQ2440測試結果
<;E:\2014年23期\2014年23期\Image\19t3.tif>;
圖3 OK6410測試結果
<;E:\2014年23期\2014年23期\Image\19t4.tif>;
圖4 TQ210測試結果
4 ?結 ?語
本文針對嵌入式系統交叉開發模型中,需要頻繁從linux宿主機中下載程序到目標機ARM更新程序的問題,開發和設計了一款基于USB的Liunx下載軟件。軟件解決了每個系列ARM開發板單獨需要一款下載軟件的問題,成功地實現了一款支持不同系列ARM開發板的USB的Linux下載軟件。軟件特點是穩定運行于各個版本Linux系統之上,并且支持ARM9處理器2440系列開發板、ARM11處理器6410系列開發板、ARM Cortex?A8處理器210系列開發板,實現下載功能。
參考文獻
[1] 王曉惠.基于ARM?Linux的交叉編譯環境的創建[J].電腦知識與技術,2007(15):55?58.
[2] 姚振國.基于嵌入式Linux的USB集成下載工具的設計與開發[D].成都:電子科技大學,2013.
[3] 王瓊.基于嵌入式Linux數據采集系統的軟件設計與實現[D].成都:電子科技大學,2013.
[4] 彭敏.基于ARM7的工業控制數據采集系統的研究[J].現代電子技術,2011,34(2):12?14.
[5] 李麗宏,郝志剛.嵌入式Linux的USB驅動設計[J].電子設計工程,2011(10):56?59.
[6] 寧玉玲,陳瓊,馬楊龍.Linux設備驅動模型框架的分類研究[J].現代電子技術,2013,36(4):5?8.
[7] 魏永明,耿岳,鐘書毅.Linux設備驅動程序[M].3版.北京:中國電力出版社,2006.
[8] 宋寶華.Linux設備驅動開發詳解[M].2版.北京:人民郵電出版社,2002.
[9] 韋東山.嵌入式Linux應用開發完全手冊[M].北京:人民郵電大學出版社,2008.
[10] 楊水清.ARM嵌入式Linux系統開發技術詳解[M].北京:電子工業出版社,2008.
TQ2440測試結果如圖2所示;OK6410測試結果如圖3所示;TQ210測試結果如圖4所示。
<;E:\2014年23期\2014年23期\Image\19t2.tif>;
圖2 TQ2440測試結果
<;E:\2014年23期\2014年23期\Image\19t3.tif>;
圖3 OK6410測試結果
<;E:\2014年23期\2014年23期\Image\19t4.tif>;
圖4 TQ210測試結果
4 ?結 ?語
本文針對嵌入式系統交叉開發模型中,需要頻繁從linux宿主機中下載程序到目標機ARM更新程序的問題,開發和設計了一款基于USB的Liunx下載軟件。軟件解決了每個系列ARM開發板單獨需要一款下載軟件的問題,成功地實現了一款支持不同系列ARM開發板的USB的Linux下載軟件。軟件特點是穩定運行于各個版本Linux系統之上,并且支持ARM9處理器2440系列開發板、ARM11處理器6410系列開發板、ARM Cortex?A8處理器210系列開發板,實現下載功能。
參考文獻
[1] 王曉惠.基于ARM?Linux的交叉編譯環境的創建[J].電腦知識與技術,2007(15):55?58.
[2] 姚振國.基于嵌入式Linux的USB集成下載工具的設計與開發[D].成都:電子科技大學,2013.
[3] 王瓊.基于嵌入式Linux數據采集系統的軟件設計與實現[D].成都:電子科技大學,2013.
[4] 彭敏.基于ARM7的工業控制數據采集系統的研究[J].現代電子技術,2011,34(2):12?14.
[5] 李麗宏,郝志剛.嵌入式Linux的USB驅動設計[J].電子設計工程,2011(10):56?59.
[6] 寧玉玲,陳瓊,馬楊龍.Linux設備驅動模型框架的分類研究[J].現代電子技術,2013,36(4):5?8.
[7] 魏永明,耿岳,鐘書毅.Linux設備驅動程序[M].3版.北京:中國電力出版社,2006.
[8] 宋寶華.Linux設備驅動開發詳解[M].2版.北京:人民郵電出版社,2002.
[9] 韋東山.嵌入式Linux應用開發完全手冊[M].北京:人民郵電大學出版社,2008.
[10] 楊水清.ARM嵌入式Linux系統開發技術詳解[M].北京:電子工業出版社,2008.