首页 > 其他分享 >u1

u1

时间:2022-12-14 20:55:41浏览次数:39  
标签:__ struct urb u1 static myusb usb

https://blog.csdn.net/baidu_19348579/article/details/126096687

设备树

这里就不需要设备树参与了,就像IIC一样,是挂载到现有的总线上,所以这里只需要注册usb设备就可以了。
代码框架(HID)

先来看一个通用的框架

#include <linux/init.h>
#include <linux/module.h>
#include <linux/usb.h>
 
 
//定义USB的IDTAB
static const struct usb_device_id my_usb_ids[] = 
{
    {USB_DEVICE(0x093a,0x2510)},
    {USB_DEVICE(0x0c45,0x760b)},
    {}
};
 
/*
MODULE_DEVICE_TABLE 有两个功能。
一是:将设备加入到外设队列中,
二是告诉程序阅读者该设备是热插拔设备或是说该设备支持热插拔功能。
该宏定义在<linux/module.h>下
这个宏有两个参数,第一个参数设备名,第二个参数该设备加入到模块中时对应产生的设备搜索符号,这个宏生成了一个名为__mod_pci_device_table
局部变量,这个变量指向第二个参数
*/
MODULE_DEVICE_TABLE (usb,my_usb_ids);
 
//USB设备信息与驱动端匹配成功的时候调用。
static int myusb_probe(struct usb_interface *intf,const struct usb_device_id *id)  //资源探索函数
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}
 
//USB断开的时候调用
static void myusb_disconnect(struct usb_interface *intf)
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
}
 
//定义USB驱动结构体 
static struct usb_driver myusb_driver = 
{
    .name = "myusb_drv",
    .id_table = my_usb_ids,
    .probe = myusb_probe,
    .disconnect = myusb_disconnect
};
 
static int __init myusb_init(void)
{
    //注册USB设备驱动
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    usb_register(&myusb_driver);
    return 0;
}
 
static void __exit myusb_exit(void)
{
     //注销USB设备驱动
     printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
     usb_deregister(&myusb_driver);
}
 
module_init(myusb_init);
module_exit(myusb_exit);
MODULE_AUTHOR("PGG");
MODULE_LICENSE("GPL");
注册中断

修改probe函数

static int size;
static unsigned char *buf =NULL;
static struct urb *myurb=NULL;
static dma_addr_t buf_phy;

static int myusb_probe(struct usb_interface *intf,const struct usb_device_id *id)  //资源探索函数
{
    struct usb_device *dev = NULL;
    struct usb_host_interface *interface = NULL;
    struct usb_endpoint_descriptor *endpoint = NULL;
    int pipe;

    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    printk("USB驱动匹配成功! ID: 0x%X,0x%X\n",id->idVendor,id->idProduct);
     
    /*通过接口获取设备信息*/
    dev = interface_to_usbdev(intf);
    /*获取当前接口设置*/
    interface=intf->cur_altsetting;
    /*获取端点描述符*/
    endpoint = &interface->endpoint[0].desc;

    
    /*中断传输:创建输入管道*/
    pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
    /*从端点描述符中获取传输的数据大小 */
    size = endpoint->wMaxPacketSize;
    printk("设备传输数据包大小:%d\n",size);
    /*分配数据传输缓冲区*/
    buf = usb_alloc_coherent(dev,size,GFP_ATOMIC,&buf_phy);

    
    /*分配新的urb,urb是usb设备驱动中用来描述与usb设备通信所用的基本载体和核心数据结构*/
    myurb = usb_alloc_urb(0,GFP_KERNEL);
    /*中断方式初始化urb*/
    usb_fill_int_urb(myurb,dev,pipe,buf,size,usb_complete,NULL,endpoint->bInterval);
    myurb->transfer_dma = buf_phy;
    myurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
    
    /*为端点提交异步传输请求*/
    usb_submit_urb(myurb, GFP_KERNEL);    
    
    return 0;
}
当中断设备有数据发送上来的时候,会触发中断,数据就在缓冲区中。
可以在回调中查看数据,按照缓存大小,输出一下数据看一下。

static void usb_irq_work(struct urb *urb)
{
    int i;
    for(i=0;i<size;i++)
    {
        printk("0x%x ",buf[i]);
    }
    printk("\n");
    /* 重新提交异步请求*/
    usb_submit_urb(myurb, GFP_KERNEL);
}

然后断开的时候会调用disconnect函数,需要释放资源

static void myusb_disconnect(struct usb_interface *intf)
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    
    struct usb_device *dev = interface_to_usbdev(intf);
    usb_kill_urb(myurb);
    usb_free_urb(myurb);
    usb_free_coherent(dev,size,buf, buf_phy);
    printk("USB 设备释放成功!\n"); 

}

然后测试一下模块驱动。
先装载驱动,再插上usb鼠标

root@raspberrypi:/home/pgg/work/driver# insmod myusbmouse.ko 
root@raspberrypi:/home/pgg/work/driver# dmesg 
[ 5684.233197] drivers/char/myusbmouse.c myusb_init 116
[ 5684.233391] usbcore: registered new interface driver myusb_drv
root@raspberrypi:/home/pgg/work/driver# dmesg 
[ 5684.233197] drivers/char/myusbmouse.c myusb_init 116
[ 5684.233391] usbcore: registered new interface driver myusb_drv
[ 5702.442546] usb 1-1.3: new low-speed USB device number 8 using dwc_otg
[ 5702.577376] usb 1-1.3: New USB device found, idVendor=093a, idProduct=2510, bcdDevice= 1.00
[ 5702.577413] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 5702.577433] usb 1-1.3: Product: USB Optical Mouse
[ 5702.577450] usb 1-1.3: Manufacturer: PixArt
[ 5702.578716] drivers/char/myusbmouse.c myusb_probe 56
[ 5702.578738] USB驱动匹配成功! ID: 0x93A,0x2510
[ 5702.578752] 设备传输数据包大小:4

可以看到驱动匹配成功,数据包大小为4。

移动一下鼠标看看。打印了很多数据。

[ 5771.634961] 0x0 
[ 5771.635024] 0xff 
[ 5771.635044] 0xff 
[ 5771.635061] 0x0 

[ 5771.683970] 0x0 
[ 5771.684017] 0xff 
[ 5771.684036] 0xff 
[ 5771.684053] 0x0 

[ 5772.644962] 0x0 
[ 5772.645013] 0xfe 
[ 5772.645033] 0x0 
[ 5772.645050] 0x0 

[ 5773.925960] 0x0 
[ 5773.926013] 0xff 
[ 5773.926033] 0x0 
[ 5773.926050] 0x0 

[ 5796.702962] 0x0 
[ 5796.703014] 0xff 
[ 5796.703035] 0xff 
[ 5796.703052] 0x0 

 

标签:__,struct,urb,u1,static,myusb,usb
From: https://www.cnblogs.com/cnchengv/p/16983512.html

相关文章

  • ubuntu16 redis5.0以后版本集群部署示例
    简言1.redis5.0版本以前的集群部署是使用ruby脚本完成的,略为复杂,具体示例见笔者的这篇博客,​​ubuntu16redis5.0以前版本集群部署示例_YZF_Kevin的博客2.本篇博客讲解red......
  • ubuntu16 redis5.0以前版本集群部署示例
    简言1.redis5.0版本以前集群的部署是使用ruby脚本完成的,ruby脚本的安装少略麻烦(主要原因是系统自动安装的版本太低,无法部署集群,必须手动安装)2.redis5.0版本以后把集群的部......
  • 基于Ubuntu18.04 tftp+apache2+grub+nfs搭建PXE系统(EFI模式,手动安装)
    基于Ubuntu18.04tftp+apache2+grub+nfs搭建PXE系统(EFI模式,手动安装)注:用于支持个性系统安装需求apt-getinstalltftpd-hpaapt-getinstallapache2apt-getinstallnfs......
  • ubuntu18 电脑重启后登录后无法进入桌面
    ubuntu18电脑重启后登录后无法进入桌面应该是ubuntu桌面管理器gdm3和nvidia驱动冲突导致的解决办法:首先卸载已有的nvidia驱动注意:在下载完驱动后,此时电脑没有驱动文件......
  • ubuntu16.04 安装gcc8 g++8
    下载:sudoadd-apt-repositoryppa:ubuntu-toolchain-r/testsudoapt-getupdatesudoapt-getinstallgcc-8sudoapt-getinstallg++-8 配置:将gcc8,g++8作为默认选......
  • 安装Ubuntu18.04并配置ssh服务
    安装Ubuntu18.04并配置ssh服务打开终端界面切换到root用户提示:输入密码是隐藏的,并不会显示,实际是输入了的运行以下代码切换到root:sudosu一.解决Ubuntu终端无法......
  • Ubuntu18.04 source.list更新国内源
    在更新源之前先作为备份sudovim/etc/apt/source.list 使用下列任意一个源即可:清华大学debhttp://mirrors.tuna.tsinghua.edu.cn/ubuntu/xenialmainrestri......
  • VMwarePro16安装Ubuntu16.04图文教程
    1.下载Ubuntu16.04的镜像文件2.下载和安装VMwarePro16主要是第三个链接的秘钥:3.VMware中创建Ubuntu16.04创建新的虚拟机自定义安装兼容性选择,这里直接下一步选择稍后安装......
  • Ubuntu18.04——基于X86和Arm安装并配置Realsense-ros环境
    文章目录​​基础安装​​​​1.安装ROS​​​​2.安装Realsense驱动以及依赖库​​​​(1)X86安装librealsense​​​​更新​​​​(2)Arm编译安装librealsense(或者Apt无法......
  • Ubuntu——双系统Ubuntu18.04系统安装和基础配置
    文章目录​​一、Ubuntu18.04双系统安装​​​​二、基础配置​​​​0.配置网络​​​​1.备份​​​​2.常用软件推荐​​​​3.安装NIVIDA驱动,CUDA,cudnn,TensorRT......