linux基於urb的以及usb的資料傳輸
Urb:usb的請求塊(include/linux/usb.h)
負責與usb裝置通訊。以一種非同步的特定的方式從USB裝置特定的端點接收發送資料,裝置驅動可以為單個端點分配多個urb,或多個端點共用單個urb。
urb的建立週期:由usb裝置驅動程式建立,分配一個特定usb的特定端點,usb驅動遞交給usb核心,由usb主控制器驅動處理,他從裝置進行usb傳送,usb結束,usb主控制器程式通知usb裝置驅動程式。
結構體 struct urb
一些Urb需要欄位:
unsigned int pipe; urb所要傳送的特定目標usb_device的端點資訊,該值取決於資料的傳輸方向:
usb_rcvintpipe()設定端點為控制輸入端點,usb_sndctrlpipe()將端點號設定為控制輸出端點。
usb_rcvbulkpipe批量輸入輸出端點,usb_rcvintpipe中斷輸入輸出端點,usb_rcvisocpipe等時輸入輸出端點。
unsigned int transfer_flags;不同的值不同的標誌,(具體問題具體對待)。
void *transfer_buffer:緩衝資料指標(需要kmalloc去建立)
dma_addr_t transfer_dma;dma方式傳輸到緩衝資料指標中去,
u32 transfer_buffer_length; 資料傳輸長度(指向緩衝區的大小)。
u32 actual_length;urb結束後傳送或者接受的實際長度。
dma_addr_t setup_dma;設定dma資料緩衝區。
usb_complete_t complete;(比較重要):urb傳輸完成,則呼叫該函式。
int status; urb的當前狀態
int interval;等時傳輸時間間隔。
int number_of_packets;等時傳輸時緩衝區的包的數量,
struct usb_iso_packet_descriptor iso_frame_desc[0];該結構體用來容許單個urb一次定義許多的等時傳輸,
(暫時就寫這麼些)還有一些,具體用到的時候還要查資料。
分配銷燬urb:
分配urb:usb_alloc_urb()
釋放:usb_free_urb()
幾種不同urb的初始化
中斷urb
static inline void usb_fill_int_urb(struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context,
int interval);
批量urb
static inline 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_fn,
void *context);
控制urb
static inline 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_fn,
void *context);
等時urb的建立
urb->dev = dev;
urb->context = uvd;
urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
urb->interval = 1;
urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = cam->sts_buf[i];
urb->complete = konicawc_isoc_irq;
urb->number_of_packets = FRAMES_PER_DESC;
urb->transfer_buffer_length = FRAMES_PER_DESC;
for (j=0; j < FRAMES_PER_DESC; j++) {
urb->iso_frame_desc[j].offset = j;
urb->iso_frame_desc[j].length = 1;
}
提交urb:
int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
在 urb 被成功提交給 USB 核心之後, 直到結束處理例程函式被呼叫前,都不能訪問 urb 結構的任何成員.
urb結束處理:
usb_submit_urb被成功呼叫之後,對urb的控制權傳遞給USB核心,函式呼叫成功,urb被結束例程會被呼叫,表示usb核心完成了urb,並將控制權返回給驅動裝置。
status狀態設定,
取消urb void usb_kill_urb(struct urb *urb)
不使用urb的傳輸::(使用條件:usb驅動程式值傳送或者接受一些簡單的usb資料)
usb_bulk_msg()建立一個批量urb,把它傳送到指定裝置等待完成,
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
批量傳送的目標usb裝置指標usb_dev, 端點,資料,長度,實際長度,超時時間。
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)
可以傳送接收usb的控制訊息。