linux内核usb驱动框架,基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析
基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析
发布时间:2014-07-18 16:47:31来源:红联作者:linux08071151
driver/usb/host/ohci-s3c2410.c
static struct platform_driver ohci_hcd_s3c2410_driver
注册usb_device_driver
static int __init usb_init(void)
usb_register_device_driver(&usb_generic_driver, THIS_MODULE)/*注册usb_device_driver 到内核中*/
当找到usb总线上有匹配的usb_device就会调用generic_probe
generic_probe
usb_set_configuration
ret = device_add (&intf->dev);/*将每个USB接口注册到内核*/
struct usb_device_driver usb_generic_driver
driver/usb/host/ohci-hcd.c
注册USB平台驱动
ohci_hcd_mod_init
#define PLATFORM_DRIVER ohci_hcd_s3c2410_driver
platform_driver_register(&PLATFORM_DRIVER);
usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev)
hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx")
usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED)
hcd_buffer_create(hcd)
usb_register_bus(&hcd->self)
usb_alloc_dev(NULL, &hcd->self, 0)
register_root_hub(hcd)
usb_new_device (usb_dev)
device_add(&udev->dev)/*将usb_device添加到usb总线的klist_devices链表上,以便于usb_register_device_driver注册usb_device_driver的时候匹配该设备*/
S3C2410 HUB初始化
usb_hub_init
usb_register(&hub_driver)/*该过程匹配USB总线上的USB HUB接口设备,通过usb_probe_interface进行匹配,若匹配则调用hub_probe*/
hub_probe
hub_configure
usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval);/*填充urb->complete = hub_irq*/
hub_activate(hub);
usb_submit_urb
khubd_task = kthread_run(hub_thread, NULL, "khubd");/*建立内核线程*/
list_empty(&hub_event_list)/*若hub_event_list链表为空,则该线程休眠,知道urb_irq检测到hub接口状态发生变化,将该事件添加到hub_event_list链表,然后唤醒该线程*/
创建HCD
usb_create_hcd
init_timer(&hcd->rh_timer);
hcd->rh_timer.function = rh_timer_func;
hcd->rh_timer.data = (unsigned long) hcd;
static void rh_timer_func (unsigned long _hcd)
usb_hcd_poll_rh_status
mod_timer (&hcd->rh_timer, jiffies + msecs_to_jiffies(250));
usb_submit_urb(struct urb *urb, gfp_t mem_flags)
status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
finish_urb (struct ohci_hcd *ohci, struct urb *urb)
usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb);
urb->complete (urb);/*调用注册的HUB_IRQ*/
1.中断类型的端口用于监控 root hub上是否有设备插入,root hub通过两种方式来监控是否有设备插入:
1.一种是通过中断方式,使能相应中断,当状态发生变化时产生中断,然后运行中断服务程序获取取状态寄存器信息;
2.一种是定时轮询方式,当定时时间到了运行定时器程时指定的定时器rh_timer的function函数rh_timer_func。
问:为什么要两种方式?
答:个人认为如果只使用中断方式的话,当插入USB的设备的时候,只会发生一次中断,若此次的中断丢失的话那么系统永远无法感知有USB设备的接入,但是定时器的可以定时的轮训该USB设备接入状态,可以避免这种情况的发生
一、中断方式:
usb_hcd_s3c2410_probe
usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
request_irq(irqnum, &usb_hcd_irq, irqflags,hcd->irq_descr, hcd))/*usb_hcd_irq会调用hcd->driver->irq (hcd) = ohci_irq*/
ohci_irq
usb_hcd_poll_rh_status(hcd);
二、定时器方式:
usb_hcd_s3c2410_probe
usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED)
hcd->driver->start(hcd)/*调用ohci_s3c2410_hc_driver中的ohci_s3c2410_start,该函数*/
ohci_s3c2410_start (struct usb_hcd *hcd)
ohci_run (ohci)
hcd->poll_rh = 1;
hcd->uses_new_polling = 1;
if (hcd->uses_new_polling && hcd->poll_rh)
usb_hcd_poll_rh_status(hcd);/*进行一次USB HUB接口状态的检查,该函数中启动定时器链表rh_timer,当定时器超时的时候,调用超时函数rh_timer_func*/
static void rh_timer_func (unsigned long _hcd)
{
usb_hcd_poll_rh_status((struct usb_hcd *) _hcd);
} /*usb_hcd_poll_rh_status函数中会再次修改rh_timer,添加到内核定时器链表,定时器的周期为250ms*/
不管是通过中断方式还是通过定时轮询方式 ,最终都是通过调用usb_hcd_poll_rh_status来实现的root hub状态查
接下来分析usb_hcd_poll_rh_status函数
usb_hcd_poll_rh_status
length = hcd->driver->hub_status_data(hcd, buffer)
if (length > 0)
usb_hcd_giveback_urb (hcd, urb)
urb->complete (urb)/*该函数即为usb_fill_int_urb填充的hub_irq*/
kick_khubd(hub);/*当urb->status=0是说明urb传输完成,此时需要唤醒内核线程hub_thread*/
list_add_tail(&hub->event_list, &hub_event_list)
wake_up(&khubd_wait)
接着分析线程hub_thread
for (i = 1; i <= hub->descriptor->bNbrPorts; i++)
hub_port_status/*获取HUB接口状态*/
connect_change = 1/*当接口状态发生改变时,connect_change设为1*/
if(connect_change)
hub_port_connect_change(hub, i, portstatus, portchange)
udev = usb_alloc_dev(hdev, hdev->bus, port1)
dev->dev.bus = &usb_bus_type;
dev->dev.type = &usb_device_type;
struct usb_device *udev/*创建一个usb_device设备*/
choose_address(udev)/*给USB分配地址,最大为127*/
hub_port_init(hub, udev, port1, i)
hub_set_address
retval = usb_get_device_descriptor(udev, 8)/*因为不确定USB设备的能够支持的最大传输大小,先读取8字节,第8个字节为bMaxPacketSize0*/
i = udev->descriptor.bMaxPacketSize0 == 0xff?512 : udev->descriptor.bMaxPacketSize0;
udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);/*设置UDEV的描述符wMaxPacketSize = bMaxPacketSize0*/
retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE)/*将USB设备中的设备描述、配置描述符、接口描述符、端点描述符一次性全部读出来进行分析*/
usb_new_device(udev)
device_add(&udev->dev)/*将该设备添加到usb_bus_type类型的总线上,匹配成功的话,将调用需要我们写的usb_driver->probe*/
举例usb_driver:
驱动编写者需要添加自己usb_driver,如usbmouse_as_key.c
static struct usb_driver usbmouse_as_key_driver
usb_register(&usbmouse_as_key_driver)/*若匹配的过程是设备接口,则调用usbmouse_as_key_driver的probe函数*/
usbmouse_as_key_probe
input_register_device(uk_dev);
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval)
usb_submit_urb
linux内核usb驱动框架,基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析相关推荐
- Intel平台计算机升级到22.60.0.6蓝牙驱动导致蓝牙不稳定,请卸载!
由于蓝牙驱动更新导致华为蓝牙鼠标链接不稳定.这里设置驱动不自动更新.Intel平台计算机升级到22.60.0.6蓝牙驱动导致蓝牙不稳定,请卸载!
- s3c2440a如何保证嵌入式linux对于虚拟内存的支持?,基于S3C2440的嵌入式LINUX操作系统内核研究【资料学习】.doc...
学校代码: 11059 学 号:0805070285 Hefei University 毕业论文(设计) BACHELOR DISSERTATION 论文题目: 基于S3C2440的嵌入式 LINUX ...
- 基于u盘的linux桌面系统3 -基于windows平台的系统介绍
基于U盘的移动操作系统,不仅有linux下开源的,也有基于windows平台的.使用起来也非常方便. 我自己试用过的有Prayaya V3,关于它的介绍可以到其官网查看.官方网址:http://www ...
- Linux四大安全实验二-基于实验楼平台的学习
ShellShock攻击实验 前言 何为ShellShock 搭建环境 bash自定义函数 进行复现 深究源码 总结 前言 要理解这个实验可能需要一些set-uid程序的基础,详见我的上一篇博客 何为 ...
- Go微服务框架及基础平台选择
Go微服务框架及基础平台选择 1 考虑因素 2 现有Go微服务框架 2.1 istio 2.1.1 Istio 特点 2.2 Go-kit 2.2.1 暂未找到 2.3 Kratos(奎托斯) 2.3 ...
- linux达芬奇安装教程,在Linux系统中能安装和运行达芬奇DaVinci Resolve 17版本
如果你想在Linux系统中安装达芬奇DaVinci Resolve 17版本和运行它,请按以下说明操作,以下以Deepin 20.2为例,也适用在Ubuntu 20.04.UOS.Debian发行版中 ...
- linux移植wifi板载驱,基于arm\Linux平台USB无线网卡的wifi驱动移植
arm平台是三星2440,Linux内核是2.6.24,威盛VNT6656的USB无线网卡:开发平台是Fedora10,内核是2.6.27.遭遇的问题主要有如下几个: 一.驱动程序的版本不对 开始在网 ...
- linux mic阵列通道丢数据,基于XMOS平台的USB麦克风阵列多声道采集装置
技术领域 本实用新型涉及麦克风阵列多声道声音采集领域,尤其涉及基于XMOS平台的USB麦克风阵列多声道采集装置. 背景技术 麦克风阵列(Array Microphone),是由2个以上数量的声学数字或 ...
- 移植根文件系统到linux内核 s3c2440,u-boot-2011.06在基于s3c2440开发板的移植之引导内核与加载根文件系统...
三.根文件系统的制作 我们利用busybox来制作根文件系统 1.在下列网站下载busybox-1.15.0.tar.bz2 在当前目录下解压busybox tar -jxvf busybox-1.1 ...
最新文章
- 阿里云高级总监谈超大规模超高性能分布式快存储系统
- JMS(Java消息服务)入门教程
- 最近面试一些厂的面经整理(阿里,腾讯,字节等)
- Node.JS 学习路线图
- C语言数组、字符与字符串笔记
- LeetCode 963. 最小面积矩形 II
- Linux采用服务器网址,Linux实现https方式访问站点
- H3C telnet 配置
- php动态生成页面结构,PHP 动态生成静态HTML页面示例代码
- javascript中的cookie
- STC8G七彩数字时钟、GPIO设置、DS1302使用、热敏电阻测温、SM5166P和MBI5024控制数码管显示
- TF-IDF算法原理和公式
- 微信小程序通过公众号(服务号)推送通知或提醒步骤及代码(一,获取推送前所需信息)
- c语言程序转换成单片机语言,STC12C2052AD单片机AD转换C语言程序(成功)
- python开源报表工具_12个最好的开源报表工具
- 国外十大在线支付服务网站
- mysql三表联合查询(员工表,部门表,工资表)
- 苹果怎么登录服务器未响应,王者荣耀登陆游戏服务器未响应该怎么解决 王者荣耀无法登陆解决办法...
- 大厂技术实现 | 爱奇艺文娱知识图谱的构建与应用实践 @自然语言处理系列
- [VOT10](2022CVPR)TCTrack: Temporal Contexts for Aerial Tracking
热门文章
- 计算机毕业设计JavaWEB儿童运动馆业务信息系统(源码+系统+mysql数据库+lw文档)
- 情人节礼物:抖音表白程序Python版 之无法拒绝的爱附完整源代码
- 软件测试————测试级别
- c++string 加引号_一文带你了解Java字符串处理(String,StringBuffer,StringBuild)
- WEB开发零基础到入门之HTML+CSS(学习记录)
- 安装、文件-Windows 8 完美越狱教程 -by小雨
- Matlab的输入输出函数,input()fprintf()disp()语法介绍,fprintf()disp()的区别
- YolactEdge: Real-time Instance Segmentation on the Edge (Jetson AGX Xavier: 30 FPS, RTX 2080 Ti: 170
- 微信小程序の再体验 - - 常用组件
- HTTP Status 400 - Required String parameter '/q' is not present