标题 | 基于Linux的USB集成下载工具的设计和实现 |
范文 | 聂涛 摘 ?要: 针对嵌入式软件开发采用交叉开发模型,需要频繁把程序从宿主机下载到目标机的要求,研究设计基于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. |
随便看 |
|
科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。