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