LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: luoyong

我想翻译USB编程指南,谁有意合作?

[复制链接]
 楼主| 发表于 2004-2-27 23:51:34 | 显示全部楼层
Reference和以后还没人翻译,你看是不是......;)

后面的那些词组有点烦人,太散,得挨个查
发表于 2004-2-27 23:54:14 | 显示全部楼层

你们任务重,后面的那些就我来吧。:)

呵呵,你们辛苦啦。
发表于 2004-2-28 00:01:36 | 显示全部楼层
最初由 luoyong 发表
Reference和以后还没人翻译,你看是不是......;)

后面的那些词组有点烦人,太散,得挨个查

呵呵,我来试试,正好有个师姐做过这个的。可以请教一下。
发表于 2004-2-28 01:12:48 | 显示全部楼层

各们加油,兄弟们给你们打气。

 楼主| 发表于 2004-2-29 12:53:17 | 显示全部楼层
Linux的USB子系统
    Linux有一个叫做“USB Core”的子系统,这个子系统包括了许多API来支持USB设备。
    USB Core包含了许多访问USB设备的方法和函数,这些函数分为高层API和低层API,比如USB闪盘属于USB设备,它的驱动程序是高层API,但主板上USB控制器的驱动程序是低层API。由于Linux内核中USB控制器的驱动编写已经完成,详情请参见Linux内核的相关文档,我们在下面主要讲解的是USB设备的驱动程序。
    这节我们将讲述USB设备的主要结构和相关API函数的使用方法,我们在这里只给出了USB驱动程序的编写指南,如果你对Linux驱动程序的编写不太了解的话请参看有关Linux驱动程序主体结构的相关文档。

USB驱动程序的主体结构
//这里有一部分没有翻译
主要结构变量(struct)
    所有的关于USB的函数和结构变量都以“usb_”开头,下面这段结构定义就是向USB子系统加入USB设备支持时需要的结构变量:
struct usb_driver
{
    const char *name;
    void *(*probe)(struct usb_device *,unsighed int,const struct usb_device_id *id_table);
    void (*disconnect)(struct usb_device *,void *);

    struct list_head driver_list;

    struct file_operations *fops;
    int minor;
    struct semaphore serialize;
    int (*ioctl)(struct usb_device *dev,unsighed int code,void *buf);
    const struct usb_device_id *id_table;
};
部分变量说明
name:模块名称
probe:probe函数的地址
disconnect:断开连接时所需要的函数的地址
driver_list:为子系统调用准备的函数,初始为{NULL,NULL}
fops:驱动程序默认的文件操作权限,被预先初始化为默认值。
monir:设备的相关minor值(规定必须是16的倍数)
serialize:
ioctl:
id_table:

//最近有事,没能翻译,今天就先翻译这么些,晚上我再翻一部分帖出来
 楼主| 发表于 2004-2-29 12:53:38 | 显示全部楼层
程序入口函数
    USB驱动程序框架增加了两个入口函数:
void *probe(struct usb_device *dev,unsighed int interface,const struct usb_device_id *id_table);当你开始使用USB接口上的设备时你需要使用这个函数,然后系统就会为这个设备创建位置。
dev指出了相关的设备,interface标识出接口的序号,如果一个USB驱动程序需要某个硬件接口联系起来的话就需要返回一个与某个设备相关的结构变量。

    设备辨认阶段一般在检测厂商标识和设备相关信息后结束,然后将检测到的信息和驱动程序提供的标识相比较,然后驱动程序将进一步收集设备的信息。
    下面是一个普通的设备检测程序:
    void *probe(struct usb_device *dev,unsighed int interface,const struct usb_device_id *id_table)
    {
        struct driver_context *context;
        if (dev->descriptor.idVendor==0x0547  &&  dev->descriptor.idProduct==0x2131 && interface==1){
            MOD_INC_USE_COUNT;
            //开始分配资源
            context=allocate_driver_resources();
            //返回相关信息
            return context;
    }


//待续
 楼主| 发表于 2004-2-29 12:54:38 | 显示全部楼层
此文删除
发表于 2004-3-2 08:51:28 | 显示全部楼层

通用串型总线

通用串型总线
在1994年的时候,由四家工业合作伙伴(康柏、英特尔、微软、NEC)结成的联盟开始着手通用串型总线(USB)的计划。这个总线最初的设计目的是:
1.从PC连入电话;
2.简单使用;
3.扩展端口。
最初的1.0的标准公布于1996年的一月,然后最近一个官方版本1.1于1998年9月发布。这份文档仍在发展因为在1999年2.0版本也公布了。更多的信息和所有的标准资料都能在这里(http://wwwbode.cs.tum.edu/Par/ar ... ode33.html#usbspecs)找到。USB结构严谨并且能被一个主机控制。主机使用一种主从协议来与附加的USB设备通信。这就意味着每一种通信都是主机初始化建立起来而这些设备不能对其他设备进行直接的通信。这看起来是与其他总线结构的缺点但是这并不是因为它是开销和性能并举的设计。主从协议解决了不兼容的问题比如防止设备的冲突或者分布式总线的判断。(arbitration我不知道如何翻译比较好)。当前的USB实现允许127个设备同时连结,并且通信带宽限制在12M/s。
发表于 2004-3-2 08:54:18 | 显示全部楼层
主机控制芯片
现在USB的主机控制芯片一般都集成在主板芯片上。没有这种控制芯片的老板子可以通过带这种芯片的PCI卡进行升级。所有这些控制芯片都可以与任何开放式主机控制芯片界面(即由康柏、微软和国家半导体共同制定的OHCI)或者通用主机控制芯片界面(由英特尔制定的UHCI)标准兼容。同样两种类型的界面拥有相同的功能,并且USB设备不必关心主机控制芯片。基本上,UHCI标准的硬件更加低级(simpler我觉得这里应该理解为低等、低级),因此它需要更加复杂的设备驱动,当然这会稍稍增加CPU的负担。

USB设备和传输特性
因为不同的用途设计出了很多不同类型的USB设备。首先,一个设备能自加电、总线加电或者两者兼备。USB一般能提供500毫安的电流给设备。如果总线上仅有总线加电的设备,那么最大电源分配可能会超出因此自加电的设备存在。它们需要的是自我电源的供应。两者兼备的设备能够在外加电源供应时转换成自加电模式。
对于不同的USB设备,它们的传输速率也能不同。USB标准分明了低速率和高速率的设备。低速率的设备(诸如鼠标、键盘、游戏杆等)传输率在1.5MBit/s并且限制了功能。高速率设备(诸如视频、音频系统)能使用12MBit/s的90%大约是前面协议提到的10MBit/s。

集线器
物理上讲在计算机的尾部面板上有一定数量的USB接口。这些接口能用来接入设备或者一个集线器。集线器是一种USB设备,用来扩展接口数量(比如2-8个)来连结其他的USB设备。能接入设备的最大数目通过总线上的集线器的数量而减少。集线器是自加电或总线供电的高速设备。
通常一个主控制芯片的接口是由一个虚拟的根集线器处理的。这个由主控制器设备驱动模拟出来的集线器,可以确立总线拓扑结构。因此每一个接口通过USB子系统的集线器驱动进行相同的处理。(见图1)

数据流类型
在USB上的通信在两个方向上完成,使用了3种不同的传输方式。从主机直接来的数据到设备上去被称为下游(译者注:downstream更加精确应该是下流的,担心读者误解,特在此处注明)或者外传输。其它方向被称为上游或者内传输。根据设备类型的传输不同得到下列用途:
·传输控制被用来请求并发送可靠的短小的数据包。这被用来设立设备,每一个都要求支持最小化系列的控制命令。这里是一个列表:
GET_STATUS
CLEAR_FEATURE
SET_FEATURE
SET_ADDRESS
GET_DESCRIPTOR
SET_DESCRIPTOR
GET_CONFIGURATION
SET_CONFIGURATION
GET_INTERFACE
SET_INTERFACE
SYNCH_FRAME
更多的控制命令能被用来传输矢量化的数据。
·大量传输能被用来请求或者发送可靠的数据包直至占据整个总线带宽。像扫描仪或者scsi适配卡设备使用这种传输类型。
·中断传输和大量传输一样都是定时轮询。一旦一个中断传输提交到主控制芯片将自动按照一个明确的间隔(1~255毫秒)重复这个请求。
·同步传输实时保证总线带宽但不可靠地发送或者接受数据流。通常,这种传输方式被用在音频和视频设备上。

枚举和设备描述符
无论什么时候USB设备接入总线,它总能被USB子系统列举出来。比如一个唯一的设备号(1-127)将确定并且设备的描述符将变为可读。这样的一个描述符是一种数据结构,包括了关于设备和其属性的一些信息。USB标准定义了一种描述符的结构体系(见图2)。

标准描述符
·一个设备描述符描述了这个USB设备的通用信息。它包括了这个设备的总体应用和所有这个设备配置文件的信息。一个USB设备只有一个设备描述符。
·配置描述符提供了关于明确的一台设备的配置信息。一个USB设备能有一个或者多个配置描述符。每一个配置又有一个或多个接口,每个接口有0或更多的终点。一个终点不会在一个单一配置中共享接口除非终端被相同设置的接口用来替换。终点可以共享部分不同但不会产生上述限制的接口。配置可以通过标准控制传输set_configuration字段专门被激活。不同的配置能被用来改变设备的全局设置诸如电源的消耗值。
·一个接口描述符用一个配置文件描述一个接口。一个配置文件提供了一个或者更多的接口,每一个有0或者更多的终点描述符用配置描述一组终点。一个接口可以包括预选设置允许终点和/或它们的特点在设备已经配置好了以后还能变化。默认的接口设置总是预制为0。预选设置可以专门通过标准控制传输set_interface被选中。举个例子,一个多功能的设备诸如带内置麦克风的摄像机可以有3个预选设置来适应总线上的带宽分配。
1.摄像机激活
2.麦克风激活
3.摄像机和麦克风激活
·一个终点描述符包含了主机决定每一个终点带宽需求所需要的信息。一个终点表示了一种逻辑数据源或者一个USB设备池。终点0被所有标准控制传输使用并且这个终点绝没有描述符。USB标准也使用管道这个术语来表示终点。
·字符串描述符是可选的,用人们可读的Unicode格式提供附加信息。它们用来表示零售商、设备名称或者序列号。

设备分类
标准设备和接口描述符包括了关于分类的信息:类、子类和协议。这些表格可以被一个主系统使用来联系一个设备或者一个驱动器的接口,这个要看它们如何被类的标准划分。这些设备和接口描述符的类域有效值在USB设备工作组里定义了(见表1)。
Table 1: USB Device Classes Device Class Example Device
         Display                         Monitor
         Communication                   Modem
         Audio                           Speakers
         Mass storage                    Hard drive
         Human interface                 Data glove

分组设备或者群组接口到类中,然后定义在一个类标准里的特性允许那些管理多种基于这个类上实现的主机软件的发展。这样的主机软件将它的操作适合到一个特定的设备或者使用由这个设备表示的描述性信息的接口。一个类的标准作为一个框架定义了所有设备的最小化的操作或者表明它们作为类中成员的接口。

人性化界面设备(HID)
HID类包括了人们用来控制计算机系统的操作的基本设备。典型的HID类设备包括了:
·键盘和坐标设备比如标准的鼠标设备,轨迹球和操作杆;
·前端控制面板例如:把手(抽屉的圆形把手)、开关、按钮和滑板;
·这些具备控制能力的设备诸如电话、VCR远程控制、游戏或者模拟设备诸如:数据手套、阀门、方向盘和方向踏板。

USB设备驱动
为USB设备寻找驱动能带来很多有趣的情况。有些情况整个USB设备由单个设备驱动来完成。在其他情况中,每一个设备的接口有一个单独的设备驱动。
 楼主| 发表于 2004-3-2 20:59:39 | 显示全部楼层
//我也来了
程序入口函数
    USB驱动程序框架增加了两个入口函数:
void *probe(struct usb_device *dev,unsighed int interface,const struct usb_device_id *id_table);当你开始使用USB接口上的设备时你需要使用这个函数,然后系统就会为这个设备创建位置。
dev指出了相关的设备,interface标识出接口的序号,如果一个USB驱动程序需要某个硬件接口联系起来的话就需要返回一个与某个设备相关的结构变量。

    设备辨认阶段一般在检测厂商标识和设备相关信息后结束,然后将检测到的信息和驱动程序提供的标识相比较,然后驱动程序将进一步收集设备的信息。
    下面是一个普通的设备检测程序:
    void *probe(struct usb_device *dev,unsighed int interface,const struct usb_device_id *id_table)
    {
        struct driver_context *context;
        if (dev->descriptor.idVendor==0x0547  &&  dev->descriptor.idProduct==0x2131 && interface==1){
            MOD_INC_USE_COUNT;
            //开始分配资源
            context=allocate_driver_resources();
            //返回相关信息
            return context;
    }


    void disconnect(struct usb_device *dev,void *drv_context);这个函数在断开设备连接时使用
    dev指定了设备关联的信息,driver_context会返回probe函数中driver_context的量。当这个函数被运行后USB的子系统会收回为这个设备分配的变量存储空间,同时驱动程序也会停止使用usb_device结构变量。
一个disconnect函数例子:
static void dabusb_disconnect(struct usb_device *usbdev,void *drv_context)
{
    struct driver_context *s=drv_context;

    //将移除标记设为1
    s->remove_pending=1;
   
    //唤醒驱动程序的所有部分
    wake_up(&s->wait);

    //等待清除变量空间前的准备工作
    sleeep_on(&s->remove_ok);

    //清除占用的内存空间
    free_driver_resources(s);

    MOD_DEC_USE_COUNT;
}


主要函数

int usb_register(struct usb_driver *drv);
    此函数用来向USB子系统注册新的USB设备。指针drv应指向一个预先初始化的usb_driver结构变量,在返回值零时说明注册成功,其他值表示注册失败。

void usb_deregister(struct usb_driver *drv);
    这个函数用来从USB子系统注销设备。

void usb_driver_claim_interface(struct usb_driver *driver,struct usb_interface *iface,void *driver_context);
    这个函数用来为设备在检测期间为驱动程序申请一个或者多个接口,参数driver需要指向一个预先初始化的usb_driver型结构变量。iface参数需要指向usb_config_descriptor结构中的usb_interface结构变量(包含在probe函数中),drv_context通常指向驱动程序的相关结构(请参看probe函数的返回值)。

int usb_interface_claimed(struct usb_interface *iface);
    这个函数用来检测是否其他的驱动程序占用了所要申请的接口。返回0代表没有被占用。

void usb_driver_release_interface(struct usb_driver *driver,struct usb_interface *iface);
    用来释放已经占用的接口,但你不必去释放probe函数中申请的接口。

const struct usb_device_id *usb_match_id(struct usb_device *dev,struct usb_interface *interface,const struct usb_device_id *id);


配置USB设备
数据描述符
    USB子系统提供了许多扩展参数用来配置USB设备,请参阅usb.h
    struct usb_device
    {
        struct usb_config_descriptor *actconfig;/*激活控制*/
        ....
        struct usb_device_descriptor descriptor;/*描述符*/
        struct usb_config_descriptor *config;    /*所有的设置*/
    }

usb_device结构是所有描述符中最重要的,有时为了正常传输数据需要调整它和其他描述符。

你可以使用下面方法访问所有的可用配置信息的描述符:
for (i=0;i<dev->descriptor.bNumConfigurations;i++)
{
    struct usb_config_descriptor *cfg=&dev->config;
}
你也可以用下面的方法访问一个配置信息作用域中的所有接口:
for(k=0;k<ifp->num_altsetting;k++)
{
    struct usb_interface_descriptor *as=&ifp->altsetting[k];
}
访问某项设置中所有的端点描述符可以用下面的方法:
for(l=0;l<as->bNumEndpoints;l++)
{
    struct usb_endpoint_descriptor *ep=&as->endpoint[k];
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表