移植linux内核串口配置,[转载]Linux2.6内核usb gadget驱动移植

本文详细介绍了嵌入式系统中USB驱动的实现原理及调试技巧。从内核2.4到2.6版本的演进,特别是gadget接口的应用,并深入探讨了包括bulk驱动、CDC ACM驱动、U盘驱动等在内的多种驱动类型。同时,文中还提供了针对时序问题的解决方案。

在写之前恶补一点usb slave端的知识

在kernel 2.4版本中,嵌入式USB驱动是在kernel/arch/arm目录下的ep0.c ep**.c, 在调试USB驱动的时候比较难,主要是如果在中断了加太多的printk,

会影响USB的时序,导致枚举就失败或不停地USB reset。

在kernel

2.6版本中,USB的驱动改为了gadget接口,在/kernel/drivers/usb/gadget目录下,有一系列的文件,这些文件都是USB的驱动,其中serial.c是bulk驱动或CDC

ACM驱动, 运行make menuconfig配置好所有的USB功能后,make

modules,则在gadget目录下有一些g_serial.ko, g_enther.ko,

g_rnds.ko, g_file_storage.ko, g_gadget.ko.

其中g_serial.ko运行的时候有个参数是use_acm, 若为0则是普通的USB

bulk驱动,最好修改serial.c文件,改为不要和tty关联,这时候windows端用USB

bulk驱动,在DDK下有源代码,编译一下就可以了。如果不`想写windows端的驱动,可以把use_acm置为1,

host端用windows自带的usbser.sys驱动,即USB转串口驱动,有时候在

c:/windows/driver/dllcach目录下,可以用expand把它解出来,具体参考/kernel/document. 在windows端需写个inf文件, 在inf文件里可以把USB转为一个MODEM,

这样Windows就可以拿它来拨号上网了,当然在小机端要和GPRS模组通讯,模组的初始化AT命令可以写在INF文件里。在windows的资源管理中是看不见串口的,只能看到modem

(comX),

在超级终端中打不开这个串口,但是在secureCRT中是可以访问这个串口的。如果想虚拟出真正的串口,可以修改INF文件,把它虚拟出真正的串口,想添加MODEM的时候可以选择添加标准MODEM,模组的初始化AT命令可以写在MODEM的属性-->初始化命令中,比如ATD*99***1#

g_file_storage.ko是U盘的驱动,比如把SD卡当U盘,insmod g_file_storage.ko

file=/mnt/mmc luns=1,若有3个分区可以当U盘,则luns=3.

注意busybox中没有mkdosfs来格式化FAT文件系统,需要自己编译修改mkdosfs的源代码。

g_enter.ko是把USB虚拟出一个网卡,在windows端用usblan.sys就可以构成直接对接的网络了。

g_rnds.ko只在XP下有windows端的驱动,windows

2000下要字迹开发,可以到微软的网站上查RNDS.其中可以拿RNDS来调试程序

不论用USB转串口还是USB网卡来配合GDB调试程序,都比tty串口调试快多了

1、 配置选项

配置选项相关解释

a4c26d1e5885305701be709a3d33442f.png

选项配置模块g_file_storage.ko

File-backed Storage Gadget

配置选项,产生模块s3c2410_udc.ko文件

USB Peripheral Controller (S3C2410 USB Device

Controller) --->

(X) S3C2410 USB Device Controller

编译后生成对应的驱动

[root@vm-dev linux-2.6.24.4]# ls drivers/usb/gadget

static struct resource s3c_usbgadget_resource[] = {

[0] = {

.start = S3C24XX_PA_USBDEV,

.end = S3C24XX_PA_USBDEV +

S3C24XX_SZ_USBDEV - 1,

.flags = IORESOURCE_MEM,

},

[1] = {

.start = IRQ_USBD,

.end = IRQ_USBD,

.flags = IORESOURCE_IRQ,

}

};

#endif

struct platform_device s3c_device_usbgadget = {

.name = "s3c2410-usbgadget",

.id = -1,

.num_resources = ARRAY_SIZE(s3c_usbgadget_resource),

.resource = s3c_usbgadget_resource,

};

EXPORT_SYMBOL(s3c_device_usbgadget);

4、 时序问题

偶的驱动程序加载之后,没有出现任何的问题,在电脑端也可以看到对应的usb设备显示为U盘设备,但是内容是空的!这个让人很头痛。

后来在高人的指点下,使用抓包工具(原来只知道调试网络要用抓包工具,原来调试usb设备也要用这玩意儿)。发现在最开是的时候报头是完整的,但是后面的内容不再进行传输。正常的USB设备在挂载时,首先是传递整个USB的存盘信息,然后会有不断的一收一发的交互信息,这个在2410连接的时候也是没有的,也就是在连接显示了u盘之后,就不再有任何的交互信息。

在高人的启发下,在drivers/usb/gadget/file_storage.c文件中添加了无数的调试信息,终于定位到是usb传输的时序问题。在整个gadget的修改中只改了一行代码:

static void start_transfer(struct fsg_dev *fsg, struct usb_ep

*ep,

struct usb_request *req, int *pbusy,

enum fsg_buffer_state *state)

{

int rc;

// printk("start_transfern");

udelay(1000);

if (ep == fsg->bulk_in)

这是我打的一个补丁:usb_gadget.patch

---

linux-2.6.24.4/drivers/usb/gadget/file_storage.c 2008-03-25 02:49:18.000000000 +0800

+++

drivers/usb/gadget/file_storage.c 2016-11-25 15:35:23.000000000 +0800

@@ -1090,7 +1090,7 @@

static int ep0_queue(struct fsg_dev *fsg)

{ int rc;

-

+// printk("ep0_queue n");

rc = usb_ep_queue(fsg->ep0,

fsg->ep0req, GFP_ATOMIC);

if (rc != 0 && rc != -ESHUTDOWN)

{

@@ -1098,6 +1098,7 @@

WARN(fsg, "error in submission: %s --> %dn",

fsg->ep0->name, rc);

} +// printk("ep0_queue end n");

return

rc; } @@ -1452,7 +1453,7 @@

struct

fsg_dev *fsg = get_gadget_data(gadget);

int rc;

int w_length = le16_to_cpu(ctrl->wLength);

- +// printk("fsg_steup n");

++fsg->ep0_req_tag; // Record arrival of a new request

fsg->ep0req->context = NULL;

fsg->ep0req->length = 0;

@@ -1489,7 +1490,8 @@

enum fsg_buffer_state *state)

{

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值