usb message 处理
来源:互联网 发布:今日金十数据官网新闻 编辑:程序博客网 时间:2024/06/06 20:37
分类: LINUX
谨以此文纪念过往的岁月
一. 前言
在前文中看过urb的实现的机制,在该文中咱们来看msg的实现。
二. msg
在ldd中说msg是一种轻量级的usb数据传输,个人以为不然,其本质还是采用了urb来实现的,那我们来看其具体的实现,除了iso的没有msg其余的三种usb传输都有。那一一来看其实现。
在该函数的说明中就说明该函数不能使用在中断上下文中。因为该函数会睡眠等待。那先来看其具体的参数:
dev:usb设备
pipe: 管道 包括一些传输的信息
request :usb请求的命令,该值在usb协议中定义
requesttype :请求类型
value :usb信息值
index :usb信息索引值
data :指向需要发送的数据指针
size:数据大小
timeout:等待时间
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data,
__u16 size, int timeout)
{
struct usb_ctrlrequest *dr;
int ret;
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
if (!dr)
return -ENOMEM;
dr->bRequestType = requesttype;
dr->bRequest = request;
dr->wValue = cpu_to_le16(value);
dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(size);
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}
static int usb_internal_control_msg(struct usb_device *usb_dev,
unsigned int pipe,struct usb_ctrlrequest *cmd,
void *data, int len, int timeout)
{
struct urb *urb;
int retv;
int length;
urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
len, usb_api_blocking_completion, NULL);
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;
}
从上面的源码可以看出,其实所谓的message就是一个马甲,其就是自己私自创建一个urb用于传输。那我们来看其中还具有一点隐私的函数usb_start_wait_urb,咱们不看其具体的实现来猜猜其的作用。嘿嘿,其中一点调用了usb_submit_urb来提交urb不过还应该有一个类似于信号量的东东用来等待urb完成,而在填充urb中complet域的函数usb_api_blocking_completion中一定会唤醒或完成的东东来唤醒在usb_start_wait_urb中等待的东东。咱们还是来看源码。
static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
{
struct api_context ctx;
unsigned long expire;
int retval;
init_completion(&ctx.done); --新建和初始化一个完成量
urb->context = &ctx; --存储,要不然怎么完成
urb->actual_length = 0;
retval = usb_submit_urb(urb, GFP_NOIO); --提交urb
if (unlikely(retval))
goto out;
expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
if (!wait_for_completion_timeout(&ctx.done, expire)) { --如果等待没有结果就…
usb_kill_urb(urb);
retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
} else
retval = ctx.status;
out:
if (actual_length)
*actual_length = urb->actual_length;
usb_free_urb(urb);
return retval;
}
其实上面的等待将在下面的函数中唤醒。
static void usb_api_blocking_completion(struct urb *urb)
{
struct api_context *ctx = urb->context;
ctx->status = urb->status;
complete(&ctx->done);
}
这里理解了为什么msg不能在中断上下文中了吧,呵呵。
而int和bulk的msg传输与上面类似咱就不看了,不过函数定义还是来看一下。
int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
这儿说到了请求,那这儿就来看看usb请求的具体的格式以及具体的请求有什么。
下面结构体定义控制类型传输的格式
struct usb_ctrlrequest {
__u8 bRequestType;
__u8 bRequest;
__le16 wValue;
__le16 wIndex;
__le16 wLength;
} __attribute__ ((packed));
bRequestType:
bit7 :数据传输方向 0 主机->设备 1 设备->主机
bit6~bit5 :类型 0 标准 1 类 2 私有 3 保留
bit4~bit0 :接受者 0 usb设备 1 usb接口 2 usb端点 其余保留
如何理解请求的类型,这个很好理解就是0表示是所有usb设备都必须支持的标准请求命令,1表示一类设备所支持的请求命令而2就是该usb设备所特定的请求命令。Bit4~bit0则表明了数据所对应的目的地。其实在这几个参数中wIndex这个比较难理解。也许下面的表格比较好理解一点。
当bRequestType中bit4~bit0值为2时即目的地是端点wIndex则代表:
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
保留(0)
Direction
保留(0)
Endpoint number
当bRequestType中bit4~bit0值为1时即目的地是接口wIndex则代表:
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
保留(0)
Interface number
上面的表格够清晰了吧!呵呵。
在usb协议中有几种标准的usb请求如下:
#define USB_REQ_GET_STATUS 0x00 -- 获取状态
#define USB_REQ_CLEAR_FEATURE 0x01 --清除或禁止某一特定功能
#define USB_REQ_SET_FEATURE 0x03 --设定或使能某一特定功能
#define USB_REQ_SET_ADDRESS 0x05 --设定地址
#define USB_REQ_GET_DESCRIPTOR 0x06 --获取描述符
#define USB_REQ_SET_DESCRIPTOR 0x07 --设定描述符
#define USB_REQ_GET_CONFIGURATION 0x08 --获取配置
#define USB_REQ_SET_CONFIGURATION 0x09 --设定配置
#define USB_REQ_GET_INTERFACE 0x0A --获取接口
#define USB_REQ_SET_INTERFACE 0x0B --设定接口
#define USB_REQ_SYNCH_FRAME 0x0C --同步帧
关于上述的请求命令其实在看hub的时候都涉及到了,只不过在这里单独来看了。
三. 总结
本文主要是看usb中message的实现以及其具体的参数说明。
上一篇:linux urb结束处理
下一篇:usb hub请求
- usb message 处理
- C# Message处理
- Message 消息处理详解
- 消息处理(Message Handling)
- android:Message处理机制
- usb_control_msg(drivers/usb/core/message.c)
- usb状态相关处理
- USB host处理过程
- USB中断处理
- Message以及report的处理
- android Message 消息处理机制
- Oslo.Messaging 中的 Message 处理
- Protocol Buffer处理嵌套message
- Oslo.Messaging 中的 Message 处理
- Android消息处理机制--Message,Message Queue,Handler,Looper
- Message消息重载、自定义消息处理过程
- Android消息处理Handler,Message,Looper
- android消息处理机制(Looper,Handler,Message)
- mysql5.0安装或登录提示 error number 1045 access denied for user ''@'localhost'
- HDU 1108 最小公倍数
- 评价等级使用的五星选择,包含半星的选择
- 数学之美系列四:怎样度量信息?
- 希尔排序Shell Sort
- usb message 处理
- wpf cpu曲线图
- JavaScript,只有你想不到
- LINUX下USB1.1设备学习小记(4)_uhci(7)
- OBJC中声明字符串常量的一个常见错误
- Java5泛型的用法,T.class的获取和为擦拭法站台
- 将Flash 嵌入WPF 程序
- 黑马程序员----C#中的不同数据类型之间的转换
- 控件上显示气泡数字