Mini2440 USB gadget --使用与测试

发布者:RainbowMelody最新更新时间:2024-06-21 来源: elecfans关键字:Mini2440  USB  gadget 手机看文章 扫描二维码
随时随地手机看文章

USB Gadget驱动又称USB器件驱动。主要用于运行linux的嵌入式系统中,使得系统拥有普通USB设备的功能。mini2440具有USB1.1设备控制器,所以可以使用USB Gadget功能。但是linux2.6.32.2内核对于mini2440的支持不是很完全。开启USB Gadget功能之后,不能使得主机发现USB硬件。这个问题主要是USB接口上拉电阻的问题,mini2440使用GPC5来上拉USB,使得主机集线器发现有USB设备链接从而枚举设备。但是在linux2.6.32.2内核中,没有设置GPC5的代码。所以导致不能使用Gadget功能。解决办法网上也有一些,就是增加额外的模块置位GPC5,但是我认为这样不是最好的办法。认真分析s3c2410_udc.c以及g_zero.c的代码后,发现在注册Gadget功能驱动的时候会调用s3c2410_udc.c提供的usb_gadget_register_driver函数,而这个函数最后会调用s3c2410_udc_enable。这个函数就是使能UDC的。代码如下:

  1. static void s3c2410_udc_enable(struct s3c2410_udc *dev)  

  2. {  

  3.     int i;  

  4.   

  5.     dprintk(DEBUG_NORMAL, 's3c2410_udc_enable calledn');  

  6.   

  7.     /* dev->gadget.speed = USB_SPEED_UNKNOWN; */  

  8.     dev->gadget.speed = USB_SPEED_FULL;  

  9.   

  10.     /* Set MAXP for all endpoints */  

  11.     for (i = 0; i < S3C2410_ENDPOINTS; i++) {  

  12.         udc_write(i, S3C2410_UDC_INDEX_REG);  

  13.         udc_write((dev->ep[i].ep.maxpacket & 0x7ff) >> 3,  

  14.                 S3C2410_UDC_MAXP_REG);  

  15.     }  

  16.   

  17.     /* Set default power state */  

  18.     udc_write(DEFAULT_POWER_STATE, S3C2410_UDC_PWR_REG);  

  19.   

  20.     /* Enable reset and suspend interrupt interrupts */  

  21.     udc_write(S3C2410_UDC_USBINT_RESET | S3C2410_UDC_USBINT_SUSPEND,  

  22.             S3C2410_UDC_USB_INT_EN_REG);  

  23.   

  24.     /* Enable ep0 interrupt */  

  25.     udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_EN_REG);  

  26.   

  27.     /* time to say 'hello, world' */  

  28.   

  29.     if (udc_info && udc_info->udc_command) {  

  30.         udc_info->udc_command(S3C2410_UDC_P_ENABLE);  

  31.     }  

  32. }  

        我们发现这个函数除了前面使能中断的操作后,最后有个判断语句,判断udc_info以及udc_info->command是否有值。然后调用udc_command,这个函数的调用参数为S3C2410_UDC_P_ENABLE。很显然这个就是使能UDC的关键操作。我们看一下udc_info又是什么,在s3c2410_udc.c的最开始有这样的定义:


        static struct s3c2410_udc_mach_info *udc_info;

        说明这是一个指向s3c2410_udc_mach_info结构的指针。s3c2410_udc_mach_info结构在udc.h中定义:

  1. struct s3c2410_udc_mach_info {  

  2.     void    (*udc_command)(enum s3c2410_udc_cmd_e);  

  3.     void    (*vbus_draw)(unsigned int ma);  

  4.     unsigned int vbus_pin;  

  5.     unsigned char vbus_pin_inverted;  

  6. };  

        那么这个指针又是什么时候赋值的,是在s3c2410_udc_probe函数中。这就说明在注册s3c2410_udc驱动的时候,由platform总线找到相应的设备匹配后,调用的。如下:
udc_info = pdev->dev.platform_data;
        那么什么又是platfom_data呢,这个又是在什么时候赋值的呢。要理解这个还得需要平台驱动的只是,也就是platform driver的知识。s3c2410的udc驱动是一个platform驱动,所以USB设备控制器是platform device。那么这个platform_data又是在哪赋的值。一般而言platform device在系统板级初始化的时候初始化的。也就是板级初始化的时候赋值。但是用Kscope怎么也找不到给他赋值的语句。说明根本就没人给他赋值。所以在注册g_zero功能驱动的时候udc_info是空的,没有执行udc_info->udc_command()。我们要做的就是给usb gadget platform device的platform_data初始化。在mach-mini2440.c中增加如下代码:

  1. static void s3c2410_udc_pullup(enum s3c2410_udc_cmd_e cmd)  

  2. {  

  3.     switch (cmd) {  

  4.     case S3C2410_UDC_P_ENABLE :  

  5.         s3c2410_gpio_setpin(S3C2410_GPC(5), 1);  

  6.         break;  

  7.     case S3C2410_UDC_P_DISABLE :  

  8.         s3c2410_gpio_setpin(S3C2410_GPC(5), 0);  

  9.         break;  

  10.     case S3C2410_UDC_P_RESET :  

  11.         break;  

  12.     default:  

  13.         break;  

  14.     }  

  15. }  

        这个函数就是udc_info->udc_command()执行的函数,在这里使得GPC5为高电平,使能USB设备。

  1. static struct s3c2410_udc_mach_info s3c2410_udc_cfg __initdata = {  

  2.     .udc_command        = s3c2410_udc_pullup,  

  3. };  

        这个结构体定义了platform_data的初始值。


        修改mini2440_machine_init函数,增加s3c24xx_udc_set_platdata(&s3c2410_udc_cfg);如下

  1. static void __init mini2440_machine_init(void)  

  2. {  

  3. #if defined (LCD_WIDTH)   

  4.     s3c24xx_fb_set_platdata(&mini2440_fb_info);  

  5. #endif   

  6.     s3c_i2c0_set_platdata(NULL);  

  7.   

  8.     s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);  

  9.   

  10.     s3c_device_nand.dev.platform_data = &friendly_arm_nand_info;  

  11.     s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;  

  12.     s3c24xx_udc_set_platdata(&s3c2410_udc_cfg); //增加的代码   

  13.     platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));  

  14.     s3c_pm_init();  

  15. }  

        s3c24xx_udc_set_platdata()这个函数定义与devs.c,如下:

  1. void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)  

  2. {  

  3.     struct s3c2410_udc_mach_info *npd;  

  4.   

  5.     npd = kmalloc(sizeof(*npd), GFP_KERNEL);  

  6.     if (npd) {  

  7.         memcpy(npd, pd, sizeof(*npd));  

  8.         s3c_device_usbgadget.dev.platform_data = npd;  

  9.     } else {  

  10.         printk(KERN_ERR 'no memory for udc platform datan');  

  11.     }  

  12. }  

        最后还要在头文件中包含plat/udc.h。这样我们注册Gadget功能驱动的时候自动使能了USB设备功能。但是在卸载驱动的时候发生了问题,内核打印出一大堆调试信息。问题出在composite.c中的composite_unbind函数中。这个函数开头有一行代码WARN_ON(cdev->config);就是如果cdev-config不为0,那么内核就会打印出调试信息。上面还给了注释
/* composite_disconnect() must already have been called
* by the underlying peripheral controller driver!
* so there's no i/o concurrency that could affect the
* state protected by cdev->lock.
*/
        这个composite_unbind是在卸载udc功能驱动的时候调用的,调用关系如下:usb_composite_unregister 调用 usb_gadget_unregister_driver而usb_gadget_unregister_driver如下定义:

  1. int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)  

  2. {  

  3.     struct s3c2410_udc *udc = the_controller;  

  4.   

  5.     if (!udc)  

  6.         return -ENODEV;  

  7.   

  8.     if (!driver || driver != udc->driver || !driver->unbind)  

  9.         return -EINVAL;  

  10.   

  11.     dprintk(DEBUG_NORMAL,'usb_gadget_register_driver() '%s'n',  

  12.         driver->driver.name);  

  13.   

  14.     driver->disconnect(&udc->gadget);  

  15. //此处为新加语句,这条语句调用 composite_disconnect,然后使得cdev->config为NULL   

  16.     driver->unbind(&udc->gadget);  

  17. //这里就是composite_unbind   

  18.   

  19.   

  20.     device_del(&udc->gadget.dev);  

  21.     udc->driver = NULL;  

  22.   

  23.     /* Disable udc */  

  24.     s3c2410_udc_disable(udc);  

  25.   

  26.     return 0;  

  27. }  

        从注释上可以看出调用composite_unbind的前提是要首先保证composite_disconnect被调用。这样才不会出现警告的内核信息。在增加上面的代码后重新编译内核,将USB Gadget设置称为模块。然后make modules 在通过ftp将s3c2410_udc.ko与g_zero.ko传入开发板,先后加载这两个模块。在主机上lsusb会发现出现新设备
Bus 005 Device 023: ID 0525:a4a0 Netchip Technology, Inc. Linux-USB 'Gadget Zero'
        卸载g_zero.ko后,新设备就会消失。这样基本的USB Gadget驱动功能就开启了。类似的还可以测试其他的USB Gagget。


关键字:Mini2440  USB  gadget 引用地址:Mini2440 USB gadget --使用与测试

上一篇:Ubuntu 11.10 下移植 madplay 到 mini2440
下一篇:Mini2440 Linux 内存布局

推荐阅读最新更新时间:2024-11-12 09:10

TE Connectivity针对移动设备推出防水型Micro USB 2.0连接器
全新MIM外壳兼具更高的强度和更强的防水性,为更轻薄的设备提供保护。 中国上海 – 2014年10月15日- 全球连接领域的领导者TE Connectivity (TE) 今天推出IP68防水型Micro USB 2.0连接器,该款产品是IP57防溅型连接器的升级版,可为当今更轻薄的移动设备提供更有效的保护,彻底隔绝液体(例如水)和固体外物(例如灰尘)进入移动设备。 IP(进入防护)等级规定了对于固体外物或液体的防护程度。第一个数字代表防止固体外物侵入的等级,而第二个数字则代表防止液体侵入的密闭程度。数字越大,表示其防护等级越高。TE的IP68连接器可在水深1.5米处为移动设备提供防水保护,防水效果可持续至少
[手机便携]
TE Connectivity针对移动设备推出防水型Micro <font color='red'>USB</font> 2.0连接器
如何用示波器对USB解码?
考虑到协议信号应用的广泛性,ZDS2022示波器免费开放了21种协议触发与解码功能, 其中当然包括了USB协议,有些客户经常反应说USB不能有效解码,那么本期视频就让您的USB解码不再成为难题! 首先输入USB协议信号,按下【Decode】键,将解码类型设为USB,开启协议触发; 然后设置协议参数,检查D+与D-的通道设置是否正确,选择合适的USB模式,ZDS2022支持12种触发模式,我们选择起始包触发。 对于ZDS2022演示板上的USB信号,屏幕上波形已经有效解码。但是可能您测的自己的USB信号还没有有效解码,那是因为您的阈值设置不合适,您可在“解码设置”中,将自动阈值设为OFF,设为手动阈值,可将D+的阈值调到波形的下
[测试测量]
如何用示波器对<font color='red'>USB</font>解码?
技术文章—​USB供电让电路保护成了强制性配置
电路保护就像是保险,充其量可以看作是事后补救措施,即使是安装到位,也往往是不够的。虽然保险投资不足会威胁到企业的稳定运营,但电路保护不到位可能导致人员伤亡等更严重的后果。 我们以1998年9月2日从纽约肯尼迪国际机场起飞的瑞士航空111航班为例来看下电路保护的重要性。执飞此航班的是机龄已有7年的麦克唐纳·道格拉斯MD-11客机,在执飞此次航班前不久升级了飞行娱乐(IFE)系统。起飞52分钟后,驾驶舱突然冒出浓烟,机组人员随即作出反应宣布进入紧急状态,并试图备降到哈利法克斯机场,但由于驾驶舱天花板着火烧毁了电气控制电缆导致飞机失控,在距离新斯科舍省海岸8公里的海域坠毁,215名乘客和14名机组人员全部遇难。 事故调查
[网络通信]
技术文章—​<font color='red'>USB</font>供电让电路保护成了强制性配置
意法半导体发布USB Type-C™控制器
意法半导体推出两款新的USB Type-C™标准认证端口控制器芯片。新产品内置保护电路,有助于设计人员实现高成本效益的接口,支持USB功能整合需求,其中包括Power Negotiation(充电握手协商)、Managed Active Cables(主动线缆管理)和Guest Protocols(外接设备协议支持)。 USB Type-C标准规定线缆可以正反插,让各种设备的互连变得更简单。Type-C接口还支持USB的所有功能,包括480Mbps USB 2.0和10Gbps USB 3.1数据传输;5V/0.5A、最高20V/5.0A供电;延长连接距离的Managed Active Cables主动线缆管理;用同一
[嵌入式]
意法半导体发布<font color='red'>USB</font> Type-C™控制器
USB 3.0测试宝典(下)
USB 3.0接收机测试 USB 3.0接收机测试与其它高速串行总线接收机一致性测试类似,它一般分成三个阶段,第一个阶段是压力眼图校准,然后是抖动容限测试,最后是分析。让我们看一下这一过程的流程图(图4)。 压力眼图校准需要使用最坏情况信号,其通常在水平方向(通过增加抖动的方式)和垂直方向(通过把幅度设置成接收机能看到的最低幅度)加压。在任何测试夹具、线缆或仪器变化时,都必须执行压力眼图校准。 抖动容限测试使用校准后的压力眼图作为输入,在此基础上注入不同频率的正弦抖动(SJ)。应用的这个SJ考验的是接收机内部的时钟恢复电路,因此不仅测试了接收机对最坏信号情况的容忍能力,还测试了时钟恢复的能力
[测试测量]
<font color='red'>USB</font> 3.0测试宝典(下)
了解汽车应用USB充电器设计面临的挑战
汽车信息娱乐市场的最新进展需要高效率和低占用空间的供电(PD)解决方案。减少物料清单的倾向促使USB电源应用将更多功能和职责集成到单个IC中。电池供电的便携式设备的激增导致汽车中用于为设备电池充电的USB插座或端口的数量增加。本应用笔记描述了与汽车应用中USB充电器相关的设计和系统挑战。 介绍 通用串行总线 (USB) 是一种接口标准,用于在外围设备和现代计算设备之间提供电力和通信。它由一组公司于1991年开发,目前由USB互动论坛(USB-IF)监督。该接口标准使制造商和消费者更容易在计算机和外围设备之间共享数据和电源,包括但不限于键盘、鼠标、手机、平板电脑等。USB-IF不断更新USB标准以包含额外的功能,自推出以来,已经
[嵌入式]
了解汽车应用<font color='red'>USB</font>充电器设计面临的挑战
简单自检USB设备 解决接口无法使用的问题
1、通常很多朋友遇到的USB接口不能用,很多问题出在USB设备上   前段时间有一朋友买了个智能手机,但想到网上下载点音乐与手机桌面背景图片拷贝到手机SD卡中,结果将数据线与手机和电脑连接之后,手机屏幕上也显示在充电状态,但在电脑中的我的电脑里怎么也找不到可移动磁盘(SD卡)的存在,朋友一着急以为手机USB接口有问题,让小编看看。不过小编看了下手机,手机解锁之后发现手机上有提示是否需要打开USB设备,选择打开之后,一会我的电脑中就显示出了可移动磁盘了。通过这个例子小编想说,如果遇到USB接口没反应,最好想想设备是否有开关,USB线是否连接好,新设备最好看下使用说明书等等。最好的办法大家可以先换个USB口以及重新拔插几次,不行建议换个
[嵌入式]
基于PDIUSBD12的USB控制器的设计
USB是一种新型的通用串行总线,它具有即插即用、可热插拔和传输速率高的特点,在工业界已经获得了广泛的支持和应用。迄今为止,各种USB的外设已有上千种,除了象显卡这种需要极高数据量和实时性要求特别高的控制设备,几乎所有的PC外设都可以移植到USB上来。   一般的USB设备都使用一片微控制器作为其核心部件,通过微控制器强火的控制和运算功能,开发者可以很容易地实现USB设备的智能化。而嵌入式设备的实时、小巧等特性使得USB的协议栈和总线驱动的开发设计显得尤为重要,因为它的好坏会直接对USB主机产生影响,从而会对嵌入式系统性能和稳定产生较大影响。本文以PDIUSBD12为USB接口芯片,以AT89C52为控制器,给出了一种USB接口的设
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved