❶ linux操作系統怎麼識別USB介面設備
linux系統會自動識別USB介面為串口磁碟sda(通常為sda1,可通過fdisk
-l命令查詢),掛載就可用。
例:新建掛載目錄mkdir
/mnt/usb,掛載mount
/dev/sda1
/mnt/usb,用完卸載掛起點unmount
/dev/sda1
/mnt/usb。
❷ linux下怎麼查找usb對應的設備,比如滑鼠....
1、首先Linux 系統使用 /dev 目錄下特定的設備文件來標識插入的設備。會發現該目錄下的某些文件,包括 /dev/sda 或者 /dev/hda 表示第一個主設備,每個分區使用一大殲個數字來表示,比如 /dev/sda1 或 /dev/hda1 表示主設備的第一個分區等。
❸ 怎樣寫linux下的USB設備驅動程序
寫一個USB的驅動程序最 基本的要做四件事:驅動程序要支持的設備、注冊USB驅動程序、探測和斷開、提交和控制urb(USB請求塊)
驅動程序支持的設備:有一個結構體struct usb_device_id,這個結構體提供了一列不同類型的該驅動程序支持的USB設備,對於一個只控制一個特定的USB設備的驅動程序來說,struct usb_device_id表被定義為:
/* 驅動程序支持的設備列表 */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
{ } /* 終止入口 */
};
MODULE_DEVICE_TABLE (usb, skel_table);
對 於PC驅動程序,MODULE_DEVICE_TABLE是必需的,而且usb必需為該宏的第一個值,而USB_SKEL_VENDOR_ID和 USB_SKEL_PRODUCT_ID就是這個特殊設備的製造商和產品的ID了,我們在程序中把定義的值改為我們這款USB的,如:
/* 定義製造商和產品的ID號 */
#define USB_SKEL_VENDOR_ID 0x1234
#define USB_SKEL_PRODUCT_ID 0x2345
這兩個值可以通過命令lsusb,當然你得先把USB設備先插到主機上了。或者查看廠商的USB設備的手冊也能得到,在我機器上運行lsusb是這樣的結果:
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 002: ID 1234:2345 Abc Corp.
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
得到這兩個值後把它定義到程序里就可以了。
注冊USB驅動程序:所 有的USB驅動程序都必須創建的結構體是struct usb_driver。這個結構體必須由USB驅動程序來填寫,包括許多回調函數和變數,它們向USB核心代碼描述USB驅動程序。創建一個有效的 struct usb_driver結構體,只須要初始化五個欄位就可以了,在框架程序中是這樣的:
static struct usb_driver skel_driver = {
.owner = THIS_MODULE,
.name = "skeleton",
.probe = skel_probe,
.disconnect = skel_disconnect,
.id_table = skel_table,
};
探測和斷開:當 一個設備被安裝而USB核心認為該驅動程序應該處理時,探測函數被調用,探測函數檢查傳遞給它的設備信息,確定驅動程序是否真的適合該設備。當驅動程序因 為某種原因不應該控制設備時,斷開函數被調用,它可以做一些清理工作。探測回調函數中,USB驅動程序初始化任何可能用於控制USB設備的局部結構體,它 還把所需的任何設備相關信息保存到一個局部結構體中,
提交和控制urb:當驅動程序有數據要發送到USB設備時(大多數情況是在驅動程序的寫函數中),要分配一個urb來把數據傳輸給設備:
/* 創建一個urb,並且給它分配一個緩存*/
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
retval = -ENOMEM;
goto error;
}
當urb被成功分配後,還要創建一個DMA緩沖區來以高效的方式發送數據到設備,傳遞給驅動程序的數據要復制到這塊緩沖中去:
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
goto error;
}
if (_from_user(buf, user_buffer, count)) {
retval = -EFAULT;
goto error;
}
當數據從用戶空間正確復制到局部緩沖區後,urb必須在可以被提交給USB核心之前被正確初始化:
/* 初始化urb */
usb_fill_bulk_urb(urb, dev->udev,
usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
buf, count, skel_write_bulk_callback, dev);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
然後urb就可以被提交給USB核心以傳輸到設備了:
/* 把數據從批量OUT埠發出 */
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
goto error;
}
當urb被成功傳輸到USB設備之後,urb回調函數將被USB核心調用,在我們的例子中,我們初始化urb,使它指向skel_write_bulk_callback函數,以下就是該函數:
static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
{
struct usb_skel *dev;
dev = (struct usb_skel *)urb->context;
if (urb->status &&
!(urb->status == -ENOENT ||
urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN)) {
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, urb->status);
}
/* 釋放已分配的緩沖區 */
usb_buffer_free(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
}
有時候USB驅動程序只是要發送或者接收一些簡單的數據,驅動程序也可以不用urb來進行數據的傳輸,這是里涉及到兩個簡單的介面函數:usb_bulk_msg和usb_control_msg ,在這個USB框架程序里讀操作就是這樣的一個應用:
/* 進行阻塞的批量讀以從設備獲取數據 */
retval = usb_bulk_msg(dev->udev,
usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
dev->bulk_in_buffer,
min(dev->bulk_in_size, count),
&count, HZ*10);
/*如果讀成功,復制到用戶空間 */
if (!retval) {
if (_to_user(buffer, dev->bulk_in_buffer, count))
retval = -EFAULT;
else
retval = count;
}
usb_bulk_msg介面函數的定義如下:
int usb_bulk_msg(struct usb_device *usb_dev,unsigned int pipe,
void *data,int len,int *actual_length,int timeout);
其參數為:
struct usb_device *usb_dev:指向批量消息所發送的目標USB設備指針。
unsigned int pipe:批量消息所發送目標USB設備的特定端點,此值是調用usb_sndbulkpipe或者usb_rcvbulkpipe來創建的。
void *data:如果是一個OUT端點,它是指向即將發送到設備的數據的指針。如果是IN端點,它是指向從設備讀取的數據應該存放的位置的指針。
int len:data參數所指緩沖區的大小。
int *actual_length:指向保存實際傳輸位元組數的位置的指針,至於是傳輸到設備還是從設備接收取決於端點的方向。
int timeout:以Jiffies為單位的等待的超時時間,如果該值為0,該函數一直等待消息的結束。
如果該介面函數調用成功,返回值為0,否則返回一個負的錯誤值。
usb_control_msg介面函數定義如下:
int usb_control_msg(struct usb_device *dev,unsigned int pipe,__u8 request,__u8requesttype,__u16 value,__u16 index,void *data,__u16 size,int timeout)
除了允許驅動程序發送和接收USB控制消息之外,usb_control_msg函數的運作和usb_bulk_msg函數類似,其參數和usb_bulk_msg的參數有幾個重要區別:
struct usb_device *dev:指向控制消息所發送的目標USB設備的指針。
unsigned int pipe:控制消息所發送的目標USB設備的特定端點,該值是調用usb_sndctrlpipe或usb_rcvctrlpipe來創建的。
__u8 request:控制消息的USB請求值。
__u8 requesttype:控制消息的USB請求類型值。
__u16 value:控制消息的USB消息值。
__u16 index:控制消息的USB消息索引值。
void *data:如果是一個OUT端點,它是指身即將發送到設備的數據的指針。如果是一個IN端點,它是指向從設備讀取的數據應該存放的位置的指針。
__u16 size:data參數所指緩沖區的大小。
int timeout:以Jiffies為單位的應該等待的超時時間,如果為0,該函數將一直等待消息結束。
如果該介面函數調用成功,返回傳輸到設備或者從設備讀取的位元組數;如果不成功它返回一個負的錯誤值。
這兩個介面函數都不能在一個中斷上下文中或者持有自旋鎖的情況下調用,同樣,該函數也不能被任何其它函數取消,使用時要謹慎。
我們要給未知的USB設備寫驅動程序,只需要把這個框架程序稍做修改就可以用了,前面我們已經說過要修改製造商和產品的ID號,把0xfff0這兩個值改為未知USB的ID號。
#define USB_SKEL_VENDOR_ID 0xfff0
#define USB_SKEL_PRODUCT_ID 0xfff0
還 有就是在探測函數中把需要探測的介面端點類型寫好,在這個框架程序中只探測了批量(USB_ENDPOINT_XFER_BULK)IN和OUT端點,可 以在此處使用掩碼(USB_ENDPOINT_XFERTYPE_MASK)讓其探測其它的端點類型,驅動程序會對USB設備的每一個介面進行一次探測, 當探測成功後,驅動程序就被綁定到這個介面上。再有就是urb的初始化問題,如果你只寫簡單的USB驅動,這塊不用多加考慮,框架程序里的東西已經夠用 了,這里我們簡單介紹三個初始化urb的輔助函數:
usb_fill_int_urb :它的函數原型是這樣的:
void usb_fill_int_urb(struct urb *urb,struct usb_device *dev,
unsigned int pipe,void *transfer_buff,
int buffer_length,usb_complete_t complete,
void *context,int interval);
這個函數用來正確的初始化即將被發送到USB設備的中斷端點的urb。
usb_fill_bulk_urb :它的函數原型是這樣的:
void usb_fill_bulk_urb(struct urb *urb,struct usb_device *dev,
unsigned int pipe,void *transfer_buffer,
int buffer_length,usb_complete_t complete)
這個函數是用來正確的初始化批量urb端點的。
usb_fill_control_urb :它的函數原型是這樣的:
void usb_fill_control_urb(struct urb *urb,struct usb_device *dev,unsigned int pipe,unsigned char *setup_packet,void *transfer_buffer,int buffer_length,usb_complete_t complete,void *context);
這個函數是用來正確初始化控制urb端點的。
還有一個初始化等時urb的,它現在還沒有初始化函數,所以它們在被提交到USB核心前,必須在驅動程序中手工地進行初始化,可以參考內核源代碼樹下的/usr/src/~/drivers/usb/media下的konicawc.c文件。
❹ Linux下怎麼枚舉usb設備
http://jingyan..com/article/fd8044fa3608eb5031137a04.html
-供纖沒參物握考罩豎慶
❺ usb枚舉設置配置後沒再發命令
1、檢測到USB設備後,對USB設備復位,使設備地址友段變為0x0。發80060100004000命令,讀取設備描述符命令,由於不知道設備描述符的長度,暫時要求返回數據長度為0x40。
2、給這個新接上的設備分配地址。
3、設置地址成功後,對新地址發送獲取設備描述符命令,此時已經知道了它的長度,直接按這個長度即可。
4、在得芹納到設備描述符後,我們再發獲取配置描述符命令。
5、從上一步,我們可以得到設備支持的介面數及端點數,此時再發一次得到配置描述符命令,把數據長度改大,數據長度我們可以從wTotallLength中讀取,但我們一般在這里設為0xFF。
6、如果有字元嫌告沒串描述符,在這里可以發命令讀取。接下來再一次發命令完整讀取設備描述符和配置描述符。
7、在這里發送設置配置命令,到此,我們已經完整地得到了設備的信息。枚舉過程結束。
❻ 編程作業:編寫 linux系統 識別usb設備的代碼!!
如果不是系統級別的代碼,不是很難;
lsusb
命令可以列出機含帶器的usb設備,可以編態余寫程序讀帆老滾取這個命令的輸出,
投機取巧。
或者,找到lsusb的源程序,自己精簡,修改。
❼ linux下如何安全彈出USB介面設備
可以用umonut卸載USB。
代碼如下:
umount /mnt/usb。
linux下掛哪笑載USB的方法如下:
假設U盤掛載到/mnt/usb目錄(沒有的話,新建)中,就是mount -t msdos /dev/sdb1 /mnt/usb
如果是fat32:
❽ linux 下如何實現USB設備重新枚舉
umount,mount,umount,mount....巴拉巴拉
❾ 如何在linux下讀寫usb設備的數據
Linux不直接支持NTFS文件系統,如果U盤是NTFS文件系統就無法直接掛載使用。首先用lsblk列出所有塊設備:
1
lsblk
sd表示SCSI磁碟,後面跟a,b,c之類的字母表示第幾個磁碟,字母之後再跟數字表示這個磁碟的第幾個分區。大部分人只有一個硬碟,此時再接一個U盤,這個U盤就是sdb,U盤上的分區就是sdb1。除此以外,還可以根據顯示的容量判斷U盤設備名是sdb還是sdc。其他情況以此類推。
然後可以在用戶目錄創建一個usb目錄:(也可以根據喜好設置在其他地方,下面的掛載地址跟著改變即可)
1
mkdir ~/usb1
最後把U盤分區掛載到這個目錄即可:(可能會提示輸入密碼,輸入密碼後回車即可)
1
sudo mount /dev/sdb1 ~/usb1
然後就可以通過訪問 ~/usb1目錄來訪問U盤:
1
2
cd ~/usb1
ls
最後要拔出U盤以前,要卸載U盤:(卸載時要退出usb1目錄,不然無法卸載)(可能會提示輸入密碼,輸入密碼後回車即可)
❿ 嵌入式Linux,載入USB驅動報錯,何解
上位機USB EHCI匯流排復位失敗,無法枚型哪念舉到USB從設備,有可緩祥能是由於上位機內部的USB EHCI控制器損壞或者USB線纜短路了,建議用示波器量一下差分信號電壓看是不是超出閾值,或者換一個從設備測試一下,卜困都正常的話就可能是上位機的問題了