1. 程式人生 > >linux基於urb的以及usb的資料傳輸

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的控制訊息。