usb1-使用usb

refer to and thanks
usb spec
国嵌usb视频linux2.6.32.2 uboot2009.11

首先了解linux de yousb编程层次
有颜色的部分是需要自己写代码的,但很多设备的驱动已经写好放在在driver目录下,但可能没配置。
而usb主机控制器驱动和udc驱动在linux内核已经实现,不必写代码。但可能没配置,所以必要时make menuconfig配置一下。


①开发板可以工作成主机,usb键盘鼠标可以接到上面,称为usb hid设备。要在开发板上编写hid驱动,以支持hid设备。当然在hid设备上,比如一个单片机做成的hid设备,也要写程序。
注:hid:human interface device 人机接口设备。比如鼠标键盘手柄等。不光是usb hid叫hid,ps/2的鼠标也叫hid,即ps/2 hid.
②开发板可以工作成设备,比如当成一个网卡,接到pc上面,此时开发板成为gadget设备。在开发板上要编写gadget驱动。

/****************************************************************板子作host,和usb设备相连**********************************************/
需要有主控制器驱动和相应设备驱动
/*板子作host,和usb设备相连*/
//配置内核以支持massstorage(以u盘为例)

//支持热插拔
general setup-->
	[*]configure standard kernel feature(for small systems)-->
		[*]support for hot-pluggable devices

//scsi设备驱动(u盘被当做scsi设备,就像鼠标被当做hid设备)
device driver-->
	scsi device support-->
		[*]scsi device support
		[*]scsi disk support
		[*]scsi generic support

//usb主控制器驱动(主要是support for host-side usb)和设备驱动(主要是usb mass storage support)
device driver-->
	[*]usb support-->
		<*>support for host-side usb
		[*]usb device filesystem
		<*>ohci hcd support
		<*>usb mass storage support
		[*]usb monitor

//支持u盘内部文件系统,如fat32
file systems-->
	dos/fat/nt filesystems-->
		<*>msdos fs support
		<*>vfat(windoww-95)fs support
		(936)default codepage for fat
		(cp936)default iocharset for fat
	partition types-->
		[*]pc bios(msdos partition table)support
	--*-- native language suport-->
		<*>simplified chinese charset(cp936,gb2312)
		<*>nls utf-8

/*板子作host*/
//配置内核以支持usb鼠标键盘

//usb主控制器驱动(③中已经选过了)
device driver-->
	[*]usb support-->
		<*>support for host-side usb
		<*>ohci hcd support
//hid驱动(usb设备驱动)
device driver-->
	hid device-->
		<*>usb human interface device(full hid)support
/************************************************************板子作device,和pc相连**********************************************/
需要有udc驱动和相应gadget设备驱动
/*板子作device,和pc相连*/
//将mini2440模拟成网卡(rndis,remote network device)

//udc驱动是usb peripheral controler(s3c2410 usb device controler)
//gadget驱动是ethenet gadget(with cdc ethenet support)
//(注:cdc communication device class,acm abstract control model)


device driver-->
	[*]usb support-->
		[*]usb gadget support-->
			[*]usb peripheral controler(s3c2410 usb device controler)
			[M]usb gatget drivers			
			[M]ethenet gadget(with cdc ethenet support)
			[*]rndis support
//(当然也可将其编译进内核)
//执行
make 
make modules
//考linux/driver/usb/gadget/g_ether.ko到板子
//启动板子(我的是uboot启动的linux2.6.32.2,先用mkimage将uImage转换一下,直接make uImage),在pc终端执行
insmod g_ether.ko
//连好线,会发现电脑有发现新硬件的提示,找到pc上的驱动信息linux.inf安装一下即可

//现在板子和pc上会各多出一个网卡,板子的是usb0,现在为新出现的这对网卡设置一下ip(不要和原来的ip在同一网段)
//在板子上执行ifconfig usb0 192.168.2.6
//在pc上执行,将新出现的网卡设置ip为192.168.1.7

//现在可以互相ping通

/*板子作device,和pc相连*/
//将mini2440模拟成串口

//udc驱动是usb peripheral controler(s3c2410 usb device controler)
//gadget驱动是Serial Gadget (with CDC ACM and CDC OBEX support) 

device driver-->
	[*]usb support-->
		[*]usb modem(cdc acm)support
		[*]usb gadget support
			[*]usb peripheral controler(s3c2410 usb device controler)
			[M]usb gatget drivers			
			[M]Serial Gadget (with CDC ACM and CDC OBEX support) 

//执行
make 
make modules	
//考linux/driver/usb/gadget/g_serial.ko到板子
//启动板子,在pc终端执行
insmod g_ether.ko
//连好线,会发现电脑有发现新硬件的提示,找到pc上的驱动信息gserial.inf安装一下即可

//现在板子和pc上会各多出一个串口,板子上的是/dev/ttyGS0
//在pc新开一个串口,监视一下新出现的串口
//在终端执行echo hello > /dev/ttyGS0 
//效果如下图


/*板子作device,和pc相连*/
//pc上读取mini2440的板载sdcard

//udc驱动是usb peripheral controler(s3c2410 usb device controler)
//gadget驱动是File-backed Storage Gadget  

device driver-->
	[*]usb support-->
		[*]usb modem(cdc acm)support
		[*]usb gadget support
			[*]usb peripheral controler(s3c2410 usb device controler)
			[M]usb gatget drivers			
			[M]File-backed Storage Gadget  
//执行
make modules	
//考linux/driver/usb/gadget/g_file_storage.ko 到板子
//启动板子,插上sdcard,在pc终端执行
insmod g_file_storage.ko file=/dev/sdcard stall=0 removable=1 

//此时终端会发出如下信息
g_file_storage gadget: File-backed Storage Gadget, version: 20 November 2008
g_file_storage gadget: Number of LUNs=1
g_file_storage gadget-lun0: ro=0, file: /dev/sdcard
//连好线,终端发出如下信息
g_file_storage gadget: full speed config #1
//片刻之后,电脑上会多出一个盘符,恩。就是sdcard了


/dev/sdcard是sd卡的设备文件,所以想在pc读写板载sdcard,首先应使sdcard在板子上工作正常。mini2440读写sdcard(fat32分区)已经正常。

//同时可以想到,如果用
insmod g_file_storage.ko file=/dev/mtdblock3 stall=0 removable=1 
//此时pc上的新盘符代表nandflash的第3个分区(默认yaffs所在分区)。所以,如果nand容量很大,如8G,则可以单独分出一个区开放给用户使用。


//在读写大点的文件时,出现"无法复制xxx:路径太深"的错误,解决如下:

//修改linux/drivers/usb/gadget/file_storage.c的一个函数,remove一行add一行,如下
static int fsg_setup(struct usb_gadget *gadget,
        const struct usb_ctrlrequest *ctrl)
{
    struct fsg_dev        *fsg = get_gadget_data(gadget);
    int            rc;
    int            w_length = le16_to_cpu(ctrl->wLength);

    ++fsg->ep0_req_tag;        // Record arrival of a new request
    fsg->ep0req->context = NULL;
    fsg->ep0req->length = 0;
    dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl));

    if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
        rc = class_setup_req(fsg, ctrl);
    else
        rc = standard_setup_req(fsg, ctrl);
    /* Respond with data/status or defer until later? */
    if (rc >= 0 && rc != DELAYED_STATUS) {
        rc = min(rc, w_length);
        fsg->ep0req->length = rc;
        //fsg->ep0req->zero = rc < w_length;/**********************remove*****************/
        fsg->ep0req->zero =rc < w_length&&(rc % gadget->ep0->maxpacket)==0;/******************add********************/
        fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
                "ep0-in" : "ep0-out");
        rc = ep0_queue(fsg);
    }
    /* Device either stalls (rc < 0) or reports success */
    return rc;
}


//修改linux/drivers/usb/gadget/s3c2410_udc.c 的一个函数,add 3行,如下
static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
{
    struct s3c2410_request    *req;
    int            is_in = ep->bEndpointAddress & USB_DIR_IN;
    u32            ep_csr1;
    u32            idx;
handle_ep_again:/********************add*********************************/ 
    if (likely (!list_empty(&ep->queue)))
        req = list_entry(ep->queue.next,
                struct s3c2410_request, queue);
    else
        req = NULL;

    idx = ep->bEndpointAddress & 0x7F;

    if (is_in) {
        udc_write(idx, S3C2410_UDC_INDEX_REG);
        ep_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
        dprintk(DEBUG_VERBOSE, "ep%01d write csr:%02x %d\n",
            idx, ep_csr1, req ? 1 : 0);

        if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
            dprintk(DEBUG_VERBOSE, "st\n");
            udc_write(idx, S3C2410_UDC_INDEX_REG);
            udc_write(ep_csr1 & ~S3C2410_UDC_ICSR1_SENTSTL,
                    S3C2410_UDC_IN_CSR1_REG);
            return;
        }
        if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req) {
            s3c2410_udc_write_fifo(ep,req);
        }
    } else {
        udc_write(idx, S3C2410_UDC_INDEX_REG);
        ep_csr1 = udc_read(S3C2410_UDC_OUT_CSR1_REG);
        dprintk(DEBUG_VERBOSE, "ep%01d rd csr:%02x\n", idx, ep_csr1);

        if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
            udc_write(idx, S3C2410_UDC_INDEX_REG);
            udc_write(ep_csr1 & ~S3C2410_UDC_OCSR1_SENTSTL,
                    S3C2410_UDC_OUT_CSR1_REG);
            return;
        }

        if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
            s3c2410_udc_read_fifo(ep,req);
            if(s3c2410_udc_fifo_count_out())/****************************add*************************/
            goto handle_ep_again;/**********************add****************************/ 
        }
    }
}

//重新
make
make modules
//重新烧写内核和模块




阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/songqqnew/article/details/6871063
上一篇换底板1
下一篇usb2-相关的input子系统及 写成input子系统
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭