多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Linux驅動開發、22-USB子系統

Linux驅動開發、22-USB子系統

來源:程序員人生   發布時間:2016-06-29 10:26:46 閱讀次數:3782次

USB子系統

USBuniversal serial bus)總線:通用串行總線,是1種外部總線標準,用于規范電腦與外部裝備的連接和通訊。

 

USB1.01.5MB/S

USB1.1full speed):12MB/S

USB2.0high speed):480MB/S

USB3.0supper sped):4800MB/S

 

USB硬件結構(4):電源(5V,500mA),地線,D+,D-

工作原理:

USB端口的D+、D-數據線上有15K左右的“高值”下拉電阻,從而使USB的數據線懸空電平為低。USB裝備的D+(高速High Speed或全速Full Speed)或D-(低速Low Speed)上具有1.5K左右的“低值”上拉電阻,而USB端口的VCCGND引出線擅長數據線,這保證了USB裝備先上電后掛線,如此上拉電阻能可靠地將USB端口的相應數據線拉高,這樣便可辨別USB裝備的接入及其速度了通過改變D+D- 兩根數據線之間的電壓差來表示0/1

 

拓普結構:

 


 

對每一個USB系統來講,都有1個稱為主機控制器的裝備,該控制器和1個Hub作為
1個整體。這個根Hub下可以接多級的Hub,每一個子Hub又可以接子Hub。每一個USB裝備
作為1個節點接在不同級別的Hub上。 每條USB總線上最多可以接127個裝備

 

常見的USB主控制器規格有:
OHCI(Open HCI 開放主機接口):主要是PC系統上的USB芯片
UHCI:大多是IntelVia主板上的USB控制器芯片。他們都是由USB1.1規格的。
EHCI(Enhanced Host Connective Interface 增強主機控制器接口):由Intel等幾個廠商研發,兼容OHCIUHCI ,遵守USB2.0規范

 

USB OTGon the go)控制器:這類控制器在嵌入式微控制器領域備受歡迎,采取otg 控制器,每一個通訊終端能充當DRD(Dual-Role Device,兩重角色裝備)。用HNP(Host Negotiation Protocol,主機溝通協議)初始化裝備連接后,這樣的裝備可以根據功能需要在主機模式和裝備模式之間任意切換。

 

HCD主控制器驅動:Host Control Driver

 

USB裝備邏輯結構

 

USB裝備的邏輯組織中,包括裝備配置接口端點4個層次。裝備通常有1個或多個配置,配置通常有1個或多個接口,接口有零或多個端點(端點可以比喻成寄存器)。

 

USB裝備中的唯1可尋址的部份是裝備端點,端點的作用類似于寄存器。每一個端點在裝備內部有唯1的端點號,這個端點號是在裝備設計時給定的。主機和裝備的通訊終究都作用于裝備上的各個端點。每一個端點所支持的操作都是單向的,要末只讀,要末只寫。

 

主性能自動裝備USB裝備的緣由:

 

在每個USB裝備內部,包括了固定格式的數據,通過這些數據,USB主機就能夠獲得USB裝備的類型、生產廠商等信息。這些固定格式的數據,我們就稱之為USB描寫符。標準的USB裝備有5USB描寫符:裝備描寫符配置描寫符接口描寫符端點描寫符字符串描寫符

格式查看:《USB specification :Table⑼.8

 

裝備描寫符:1個USB裝備只有1個裝備描寫符,裝備描寫符長度為18個字節

 

 

 

配置描寫符:

 

 

接口描寫符:

 

 

端點描寫符

 

 

USB數據通訊:

USB的數據通訊首先是基于傳輸(Transfer)的,傳輸的類型有:中斷傳輸、批量傳輸、同步傳輸、控制傳輸

 

1次傳輸由1個或多個事務(transaction)構成,事務可分為:In事務,Out事務,Setup事務

 

1個事務由1個或多個包(packet)構成,包可分為:令牌包(setup)、數據包(data)、握手包(ACK)和特殊包

 

1個包由多個域構成,域可分為:同步域(SYNC),標識域(PID),地址域(ADDR),端點域(ENDP),幀號域(FRAM),數據域(DATA),校驗域(CRC

 

 

USB枚舉:

USB裝備在正常工作之前, 第1件要做的事就是枚舉。枚舉是讓主機認得這個USB裝備, 并且為該裝備準備資源,建立好主機和裝備之間的數據傳遞通道。

 

USB 尋址

USB裝備里的每一個尋址單元稱作 端點。每一個端點分配的地址稱作端點地址。每一個端點地址都有與之相干的傳輸模式。如果1個端點的數據傳輸模式時批量傳輸模式,該端點叫做批量端點地址為0的端點專門用來配置裝備。控制管道和它相連,完成裝備枚舉進程.

USB裝備地址和I2C1樣,其實不占用CPU可尋址的空間,它們的地址空間是私有的,一樣采取主從結構..

 

LINUX USB子系統驅動架構

開發板作為主機,掛載U

 

 

開發板作為從裝備,PC機為主機

 

 

 

 

 

 

 

 

 

URBUSB Request Block,USB要求塊)通訊模型:USB數據傳輸機制使用的核心數據結構

 

 

 

dnw下載線履行流程

 

 

驅動程序設計

#include<linux/init.h>

#include<linux/module.h>

#include<linux/types.h>

#include<linux/errno.h>

#include <linux/usb.h>

#include <linux/fs.h>

#include <linux/uaccess.h>

#include <linux/slab.h>

#include <linux/mm.h>

#define USB_VID_TQ210 0x04e8

#define USB_PID_TQ210 0X1234

#define DES_BUF_SIZE 512

 

unsigned char bulk_out_endaddr; /*目標端點地址*/

char *des_buffer;

struct usb_device *usb_dev; /*指向USB裝備*/

 

/***********************************

USB核心檢測到某個裝備的屬性和某個驅動程序

ID匹配時(既枚舉進程完成),

這個驅動程序的prob函數就被khubd履行。

 

查看從裝備時先讓從裝備進入下載狀態,在PC終端

使用 lsusb 查看

***********************************/

static struct usb_device_id dnw_table [] = {

{ USB_DEVICE(USB_VID_TQ210,     USB_PID_TQ210) },

{ },

};

 

/***********************************

文件操作:

 

************************************/

static int dnw_open(struct inode *inode, struct file *file)

{

/*分配內核空間*/

des_buffer = kmalloc(DES_BUF_SIZE,GFP_KERNEL);

return 0;

}

 

static ssize_t dnw_write(struct file *file, const __user char *buffer,

 size_t count, loff_t *ppos)

{

 

size_t toWrite=0,totalshift=0;

int actual_length;

unsigned long  ret = 0;

while(count > 0)

{

/*獲得用戶傳輸下來的數據*/

/*獲得較小值*/

 toWrite = min(count,(size_t)DES_BUF_SIZE);

 ret = copy_from_user(des_buffer,buffer+totalshift,toWrite);

/*將數據提交給USB主控制器*/

/*

usb_dev:指向需要操作的usb裝備

管道操作:

usb_sndbulkpipe(usb_dev,bulk_out_endaddr):建立usb裝備與端點的批量傳輸管道

1)管道包括:端點地址

    數據傳輸方向(IN/OUT

    數據傳輸模式:控制,中斷,批量,等時

1)函數格式:usb_[rcv|snd][ctrl|int|bulk|isoc]pipe

actual_length:實際傳輸的字節數寄存在這里

3*HZ:等待超時

*/

usb_bulk_msg(usb_dev,usb_sndbulkpipe(usb_dev,bulk_out_endaddr),des_buffer,toWrite,&actual_length,3*HZ);

count -= toWrite;

totalshift+=toWrite;

}

return 0;

}

 

static int dnw_release(struct inode *inode, struct file *file)

{

kfree(des_buffer);

return 0;

}

 

/* file operations needed when we register this driver */

static const struct file_operations dnw_fops = {

.owner = THIS_MODULE,

.write = dnw_write,

.open = dnw_open,

.release = dnw_release,

};

 

 

 

struct usb_class_driver dnw_class = {

.name = "dnw%d",

.fops = &dnw_fops,

.minor_base = 100,

};

 

/****************************************************************************

裝備捕獲函數需要做的工作分析:

 

1USB是圍繞URB數據傳輸機制展開的,所以開始應當初始化URBURB使用步驟:

1)分配內存:usb_alloc_urb():這個和網絡裝備差不多

2)初始化:usb_fill_[control|int|bulk]_urb

3)異步提交:usb_sumit_urb():這項工作在讀寫操作函數中進行

 

2、同步提交URB接口函數:既使用1下函數就可以完成1中3步的工作,這個函數合適在讀寫操作中進行

1usb_[control|int|bulk]_msg()

 

3、批量傳輸屬于字符裝備操作,既要初始化字符操作函數集

1usb_register_dev():該函數能將字符裝備和USB總線關聯在1起

綜合以上分析:

prob只需做的就是第3步;關聯字符裝備

其他地方需要用到那種數據結構在來這里初始化就行了

****************************************************************************/

static int dnw_probe(struct usb_interface *intf,const struct usb_device_id *id)

{

int ret = -ENOMEM;

int i=0;

printk("Device prob!\n");

/* 接口設置描寫 ,主機對每一個接口的描寫*/

     struct usb_host_interface *interface;

struct usb_endpoint_descriptor *endpoint;

/*獲得USB裝備,在初始化URB中使用*/

 usb_dev = usb_get_dev(interface_to_usbdev(intf));

 

/*獲得接口*/

 interface = intf->cur_altsetting;

/*獲得目標端點*/

     for(i=0;i<interface->desc.bNumEndpoints;i++)

     {

     endpoint = &interface->endpoint[i].desc;

     if(usb_endpoint_is_bulk_out(endpoint))

     {

          bulk_out_endaddr = endpoint->bEndpointAddress;

          break;

     }

     }

/*把字符裝備和usb裝備關聯起來*/

if((ret =  usb_register_dev(intf,&dnw_class)) < 0)

{

printk("usb_register_dev err!\n");

}

 

return ret;

}

 

void dnw_disconnect (struct usb_interface *intf)

{

usb_deregister_dev(intf,&dnw_class);

}

 

static struct usb_driver dnw_driver = {

.name = "dnw",

.probe = dnw_probe,

.disconnect = dnw_disconnect,

.id_table = dnw_table,

};

 

 

/***********************************

USB 一樣是1種總線協議,所以初始化1般是向

其總線注冊

************************************/

static int dnw_init(void)

{

/*1、向usb核心注冊USB裝備*/

int result;

if ((result = usb_register(&dnw_driver))) {

err("usb_register failed. Error number %d",result);

return result;

}

return 0;

}

 

static void dnw_exit(void)

{

/* deregister this driver from the USB subsystem */

usb_deregister(&dnw_driver);

 

}

 

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Hntea");

module_init(dnw_init);

module_exit(dnw_exit);


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 日本一区二区日本免费 | 精品免费久久久久国产一区 | 欧美精品色精品一区二区三区 | 一级毛片一级毛片一级毛片一级毛片 | 国产成人一区二区三区 | 亚洲精品老司机在线观看 | 成人hd| 亚洲人成网站在线观看播放青青 | 国内精品久久久久激情影院 | 亚洲精品中文字幕乱码无线 | 日本欧美一区二区免费视 | 国产伦精品一区二区三区在线观看 | 麻豆精品不卡国产免费看 | 欧美人与禽xoxo性伦交 | 精品久久久久久国产 | 男人看片网站 | 日本护士xxxxxwww | 国产一级做a爰大片免费久久 | 久久是精品 | 亚洲色图吧 | 三级不卡视频 | 最近的中文字幕大全免费8 最近的中文字幕大全免费版 | 天堂亚洲国产日韩在线看 | 亚洲欧美日韩中文字幕一区二区三区 | 欧美成人h版影院在线播放 欧美成人h版在线观看 | 久久国产精品影院 | 国产女人的一级毛片视频 | 国产三级在线观看播放 | 亚洲精品一区二区三区在线看 | 成人国产亚洲欧美成人综合网 | 欧美性a欧美在线 | 2023av网站 | 欧美三级久久 | 欧洲乱码专区一区二区三区四区 | 台湾成人性视频免费播放 | 最新欧美精品一区二区三区不卡 | 欧美高清一区二区三区欧美 | 亚洲国产系列一区二区三区 | 国内精品伊人久久久久 | 国产成人小视频在线观看 | 一级色网站 |