USB Linux 实现 (一) 总览

初始化

Linux 5.11 usb ohci 结构体框架图(以usbmouse为例,带usbmouse)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

针对 hid 框架, mouse的话
	drivers/input/mousedev.c 的 mousedev_init 注册了 handler ,/dev 下创建了 /dev/input/mouse0
	这个handler 与
		 drivers/hid/hid-core.c "hid_device_probe -> hid_hw_start -> hid_connect -> hidinput_connect -> input_register_device" 
		创建的 device 
		匹配

[<c0105e34>] (unwind_backtrace) from [<c01047d0>] (show_stack+0x10/0x14)
[<c01047d0>] (show_stack) from [<c03ad510>] (input_register_device+0x10/0x448)
[<c03ad510>] (input_register_device) from [<c0422188>] (hidinput_connect+0x2064/0x4e8c)
[<c0422188>] (hidinput_connect) from [<c041e4e8>] (hid_connect+0x2bc/0x36c)
[<c041e4e8>] (hid_connect) from [<c041e6c8>] (hid_hw_start+0x3c/0x5c)
[<c041e6c8>] (hid_hw_start) from [<c041e920>] (hid_device_probe+0xdc/0x140)
[<c041e920>] (hid_device_probe) from [<c03630bc>] (really_probe+0x1f0/0x4cc)
[<c03630bc>] (really_probe) from [<c0363404>] (driver_probe_device+0x6c/0x1d0)
[<c0363404>] (driver_probe_device) from [<c0361878>] (bus_for_each_drv+0x54/0xb8)
[<c0361878>] (bus_for_each_drv) from [<c0363924>] (__device_attach+0xd8/0x178)
[<c0363924>] (__device_attach) from [<c0361a98>] (bus_probe_device+0x84/0x8c)
[<c0361a98>] (bus_probe_device) from [<c035fe7c>] (device_add+0x3d0/0x7c0)
[<c035fe7c>] (device_add) from [<c041eb0c>] (hid_add_device+0xec/0x2ac)
[<c041eb0c>] (hid_add_device) from [<c042a628>] (usbhid_probe+0x260/0x370)
[<c042a628>] (usbhid_probe) from [<c0395c1c>] (usb_probe_interface+0x134/0x2bc)
[<c0395c1c>] (usb_probe_interface) from [<c03630bc>] (really_probe+0x1f0/0x4cc)
[<c03630bc>] (really_probe) from [<c0363404>] (driver_probe_device+0x6c/0x1d0)
[<c0363404>] (driver_probe_device) from [<c0361878>] (bus_for_each_drv+0x54/0xb8)
[<c0361878>] (bus_for_each_drv) from [<c0363924>] (__device_attach+0xd8/0x178)
[<c0363924>] (__device_attach) from [<c0361a98>] (bus_probe_device+0x84/0x8c)
[<c0361a98>] (bus_probe_device) from [<c035fe7c>] (device_add+0x3d0/0x7c0)
[<c035fe7c>] (device_add) from [<c0393884>] (usb_set_configuration+0x484/0x868)
[<c0393884>] (usb_set_configuration) from [<c039f31c>] (usb_generic_driver_probe+0x2c/0x78)
[<c039f31c>] (usb_generic_driver_probe) from [<c0395a50>] (usb_probe_device+0x40/0xd8)
[<c0395a50>] (usb_probe_device) from [<c03630bc>] (really_probe+0x1f0/0x4cc)
[<c03630bc>] (really_probe) from [<c0363404>] (driver_probe_device+0x6c/0x1d0)
[<c0363404>] (driver_probe_device) from [<c0361878>] (bus_for_each_drv+0x54/0xb8)
[<c0361878>] (bus_for_each_drv) from [<c0363924>] (__device_attach+0xd8/0x178)
[<c0363924>] (__device_attach) from [<c0361a98>] (bus_probe_device+0x84/0x8c)
[<c0361a98>] (bus_probe_device) from [<c035fe7c>] (device_add+0x3d0/0x7c0)
[<c035fe7c>] (device_add) from [<c0387ba8>] (usb_new_device+0x1b4/0x3b0)
[<c0387ba8>] (usb_new_device) from [<c038ac7c>] (hub_event+0x780/0x16e4)
[<c038ac7c>] (hub_event) from [<c012785c>] (process_one_work+0x1d0/0x438)
[<c012785c>] (process_one_work) from [<c0127b04>] (worker_thread+0x40/0x580)
[<c0127b04>] (worker_thread) from [<c012c85c>] (kthread+0x10c/0x120)
[<c012c85c>] (kthread) from [<c0100170>] (ret_from_fork+0x14/0x24)
Linux 5.11 usb ohci 结构体框架图(以usb camera为例,带usbcamera)
Linux 5.11 usb ohci 结构体框架图(以usb disk为例,带usbdisk)
控制器初始化流程
包含 usb 设备驱动 接口驱动的 注册
包含 usb 控制器的 初始化
包含 root hub 设备device 的注册 
	及 "设备device 的与 设备driver的 匹配"
	及 root hub 接口device 的注册
	及 "接口device 的与 接口driver的 匹配"

usb_init
	bus_register(&usb_bus_type);
	usb_host_init();
	usb_hub_init();
		usb_register(&hub_driver);
		hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE, 0);
	usb_register_device_driver(&usb_generic_driver, THIS_MODULE);


ohci_hcd_s3c2410_probe
	hcd->rsrc_start = dev->resource[0].start;
	hcd->rsrc_len   = resource_size(&dev->resource[0]);
	usb_add_hcd
		request_irq(irqnum, &usb_hcd_irq, irqflags,
		register_root_hub
			usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
			usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
			usb_new_device // 这个是 hub 设备device
				usb_get_configuration
				device_add(hub 设备device)
					usb_generic_driver 的 generic_probe
						choose_configuration
						usb_set_configuration
							device_add(hub 接口device)
								hub_probe
									INIT_WORK(&hub->events, hub_event);
									hub_configure
										usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval);
											urb->complete = hub_irq;

hid_init
	usb_register(&hid_driver);

设备插入时

usbhid设备/storage设备/camera设备/非root hub的hub设备 插入时的 代码流程
包含 hid/hub/storage 设备device 的注册 
	及 "设备device 的与 设备driver的 匹配"
	及  对应class 接口device 的注册
	及 "接口device 的与 接口driver的 匹配"
// Linux-5.11 
usb_hcd_irq (对应一个硬件中断线) // linux-5.11
	hcd->driver->irq(hcd) // 即 ohci_irq
		usb_hcd_poll_rh_status
			usb_hcd_giveback_urb
				tasklet_schedule // tasklet_setup(&bh->bh, usb_giveback_urb_bh);
					usb_giveback_urb_bh
						__usb_hcd_giveback_urb
							urb->complete(urb); // 即 hub_irq
								kick_hub_wq(hub);
									queue_work(hub_wq, &hub->events)
										hub_event
											port_event
												hub_port_connect_change
													hub_port_connect
														udev = usb_alloc_dev
														usb_set_device_state(udev, USB_STATE_POWERED);
														choose_devnum(udev); // 原来是 choose_address
														status = hub_port_init(hub, udev, port1, i);
															hub_port_reset(hub, port1, udev, delay);
															hub_set_address
															usb_get_device_descriptor
														usb_new_device 	// 这个是设备
															usb_enumerate_device
																usb_get_configuration
															device_add(usb设备device)
																usb_generic_driver 的 usb_generic_driver_probe
																	usb_choose_configuration
																	usb_set_configuration
																		device_add(usb接口device)
																			usbhid_probe/storage_probe/hub_probe

运行时

运行时数据流程-以usb_mouse_driver为例
// 鼠标数据接收流程
usb_hcd_irq (对应一个硬件中断线) // linux-5.11
	hcd->driver->irq(hcd) // 即 ohci_irq
		usb_hcd_poll_rh_status
			usb_hcd_giveback_urb
				tasklet_schedule // tasklet_setup(&bh->bh, usb_giveback_urb_bh);
					usb_giveback_urb_bh
						__usb_hcd_giveback_urb
							urb->complete(urb); // 即 usb_fill_int_urb的第6个参数,hub_irq/usb_mouse_irq/hid_irq_in/hid_irq_out/usb_api_blocking_completion

// usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, (maxp > 8 ? 8 : maxp), usb_mouse_irq, mouse, endpoint->bInterval); 
// 填充 urb->complete = complete_fn ;
		
usb_mouse_driver 流程
	usb_mouse_irq
		input_report_rel(dev, REL_X,     data[1]);
		input_report_rel(dev, REL_Y,     data[2]);
		input_report_rel(dev, REL_WHEEL, data[3]);
		input_sync(dev);

往下是 input 框架 和 cdev 的 流程
请参考 input 系列博客 : https://blog.csdn.net/u011011827/article/details/87891596
运行时数据流程-以 usb camera为例
运行时数据流程-以 usb disk为例
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核中添加USB摄像头设备的实现可以通过以下步骤完成: 1. 确保你的摄像头设备已经正确地连接到计算机的USB端口,并且系统能够正确地检测到它。你可以通过运行`lsusb`命令来查看已连接的USB设备列表,确认摄像头设备已经被识别。 2. 在Linux内核源代码中,找到与USB子系统相关的配置文件。通常这个文件的路径是`/usr/src/linux/.config`。 3. 打开配置文件,启用USB摄像头设备的支持。在配置文件中搜索以下选项,并确保它们的值被设置为`y`或者`m`: ``` CONFIG_USB_VIDEO_CLASS=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_VIDEO_DEV=y ``` 这些选项使得内核支持USB视频类设备、媒体支持以及视频设备。 4. 保存配置文件并退出。 5. 编译并安装内核。可以使用`make`和`make install`命令来编译和安装内核。 6. 重新启动计算机,让新的内核生效。 7. 在启动后,系统应该能够自动检测和加载USB摄像头设备的驱动程序。你可以通过运行`ls /dev/video*`命令来查看是否存在`/dev/video0`或类似的设备节点。 8. 现在你可以使用各种摄像头相关的应用程序(如`cheese`)来测试并使用USB摄像头设备了。 请注意,以上步骤基于标准的Linux内核配置和设备,实际操作中可能会因为不同的Linux发行版和硬件配置而有所差异。因此,请确保参考你使用的Linux发行版和硬件设备的相关文档和指南,以获得更准确的指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值