1. 程式人生 > >USB裝置驅動基礎 >>Linux裝置驅動程式

USB裝置驅動基礎 >>Linux裝置驅動程式

最常用的裝置卻不懂它的工作原理,豈不是最大的不尊敬,感謝USB為我們帶來的便利;
今天也要繼續堅定的前行的…

文章目錄

[0x100] 特徵與概念

[0x110] USB介面特徵

  • 主從樹形點對點結構,主機控制器輪詢連線,從機控制器迴應資料;
  • 四線結構雙線傳輸,地線、電源、接收訊號線、傳送訊號線;
  • 非結構型別的通訊方式,遮蔽了下層的硬體裝置,以序列資料流的方式來傳輸資料;
  • 支援熱插拔功能;

[0x120] USB驅動型別

  1. USB裝置驅動 :宿主機控制硬體作為USB裝置與主機通訊;
  2. USB器件驅動 :USB裝置如何控制連線到計算機,之前只能傳送資料,現在可以傳送指令,由器件驅動去執行;

[0x130] USB裝置基本組成

在這裡插入圖片描述

[0x131] 端點[struct usb_host_endpoint]

  • 定義 :單方向傳輸資料的管道類通道,共有四種類型;
  1. 控制端點 :配置新入裝置初始化,獲取裝置狀態資訊,向裝置傳送命令;
  2. 中斷端點 :用於接收少量高頻率的資料,如 鍵盤、滑鼠等等;
  3. 批量端點 :不可靠的非同步大量資料傳輸,;
  4. 實時端點 :可靠恆定速率大量資料傳輸,用於高實時的資料傳輸;

[0x132] 介面[struct usb_host_interface]

  • 定義 :同邏輯型別USB埠的繫結抽象
  1. 不同的介面執行不同的單一邏輯職能,不同的頻寬
  2. 每個介面可以擁有多個可選配置
  3. 介面的計數從0開始計數;
  4. 實際驅動程式中要使用的結構 struct usb_device 而不是結構結構體本身;

[0x133] 配置規則[struct usb_host_config]

  1. USB 裝置捆綁多個介面,介面捆綁多個配置
  2. 一個介面只可以啟用一個配置,裝置可以繫結多個介面,一次有多個配置;
  3. 需要繫結到介面使用,不能單獨使用

[0x140] USB request Block [struct urb]

  • 定義:異步向指定裝置的指定埠傳送/接收資料;
  1. 每個埠可以接收多個urb的資料收發,也可以多個埠共享一個urb;
  2. 一種埠間的非同步通訊機制;

[0x200]相關資料結構

[0x210] USB 端點描述結構

#include <linux/usb.h>  
 */struct usb_host_endpoint {     /*描述了USB端點組成資訊*/

       struct usb_endpoint_descriptor  /*USB標準資料結構*/
       {
        __u8  bLength;               
        __u8  bDescriptorType;

        __u8  bEndpointAddress;    /*8位 表示端點的USB地址,包括了方向和位置標識*/
        __u8  bmAttributes;        /*8位 表示端點的型別屬性*/
        __le16 wMaxPacketSize;     /*16位 資料塊限定大小*/
        __u8  bInterval;           /*與中斷型別端點關聯使用,端點的請求中斷的間隔*/
        __u8  bRefresh;
        __u8  bSynchAddress;
      } __attribute__ ((packed))desc;
        struct usb_ss_ep_comp_descriptor        ss_ep_comp;
        struct list_head                        urb_list;       /*URB佇列頭*/
        void                                    *hcpriv;        /*DMA佇列頭*/
        struct ep_device                        *ep_dev;        /*裝置檔案系統資訊*/
        /*描述介面的作用 沒啥用*/
        unsigned char *extra;                                  /* Extra descriptors */
        int extralen;
        
        int enabled;                                            /*端點URB 啟用提交*/
};
/*端點的型別屬性*/
#define USB_ENDPOINT_XFERTYPE_MASK      0x03   /*掩碼bmAttributes用來獲取當前位*/
#define USB_ENDPOINT_XFER_CONTROL       0      /*控制端點*/
#define USB_ENDPOINT_XFER_ISOC          1      /*實時端點*/
#define USB_ENDPOINT_XFER_BULK          2      /*批量端點*/
#define USB_ENDPOINT_XFER_INT           3      /*中斷端點*/

[0x220] USB 介面描述結構

#include <linux/usb.h> 
struct usb_interface {
        struct usb_host_interface *altsetting;              /*介面結構陣列 用於記錄可選的介面資訊陣列 無序*/
        struct usb_host_interface *cur_altsetting;          /* 當前介面啟用的可選設定 */
        unsigned num_altsetting;                            /* 可選設定的數量 */
        struct usb_interface_assoc_descriptor *intf_assoc;  /*組介面配置繫結*/
        /*驅動程式包含了USB裝置的主裝置號,該選項表示為介面的次裝置號 */
        int minor;   
        enum usb_interface_condition condition;            /* 介面繫結狀態*/
        /*操作配置功能引數位*/
        unsigned sysfs_files_created:1; /* 檔案系統已存在該裝置檔案*/
        unsigned ep_devs_created:1;     /* 終端裝置已存在*/
        unsigned unregistering:1;       /* 程序未註冊*/
        unsigned needs_remote_wakeup:1; /* 驅動遠端喚醒*/
        unsigned needs_altsetting0:1;   /* 開啟抑制altsetting 0 */
        unsigned needs_binding:1;       /* 需要延遲繫結*/
        unsigned reset_running:1;
        unsigned resetting_device:1;    /*重置後頻寬重分配*/

        struct device dev;
        struct device *usb_dev;
        atomic_t pm_usage_cnt;            /*引用變數 用於確定介面是否正在使用*/         
        struct work_struct reset_ws;      /*工作佇列結構*/
};

[0x230] USB 介面配置結構

#include <linux/usb.h> 
struct usb_host_config {
        /*配置引數資訊*/
        struct usb_config_descriptor    desc;
        char *string; 
        /*介面描述繫結陣列 無序*/         
        struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS]; 
       /*介面引數資訊繫結陣列 無序*/   
        struct usb_interface *interface[USB_MAXINTERFACES];
        struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];

        unsigned char *extra;   /* Extra descriptors */
        int extralen;
};

[0x240] USB urb結構

#include <linux/usb.h>
struct urb {
        /* private: usb core and host controller only fields in the urb */
        struct kref kref;               /* reference count of the URB */
        void *hcpriv;                   /* private data for host controller */
        atomic_t use_count;             /* concurrent submissions counter */
        atomic_t reject;                /* submissions will fail */
        int unlinked;                   /* unlink error code */

        /* public: documented fields in the urb that can be used by drivers */
        struct list_head urb_list;      /* list head for use by the urb's
                                         * current owner */
        struct list_head anchor_list;   /* the URB may be anchored */
        struct usb_anchor *anchor;
        struct usb_device *dev;         /* 需要繫結Urb的USB裝置結構,必須由對應的USB驅動初始化 */
        struct usb_host_endpoint *ep;   /* (internal) pointer to endpoint */
        unsigned int pipe;              /* 需要繫結Urb的USB端點屬性,決定了傳輸資料的方向 */
        unsigned int stream_id;         /* (in) stream ID */
        int status;                     /* 實時埠狀態 */
        unsigned int transfer_flags;    /* urb埠傳輸型別標識*/
        void *transfer_buffer;          /* 普通資料緩衝區中轉 必須使用kmalloc 建立空間*/
        dma_addr_t transfer_dma;        /* DMA作為資料緩衝區中轉 */
        struct scatterlist *sg;         /* (in) scatter gather buffer list */
        int num_mapped_sgs;             /* (internal) mapped sg entries */
        int num_sgs;                    /* (in) number of entries in the sg list */
        u32 transfer_buffer_length;     /* 傳輸資料緩衝區大小*/
        u32 actual_length;              /* (return) actual transfer length */
        unsigned char *setup_packet;    /* 設定資料包指標,優先於普通緩衝區中資料傳送到目標,只允許控制型別埠使用 */
        dma_addr_t setup_dma;           /* 設定資料包指標,優先於DMA緩衝區中資料傳送到目標,只允許控制型別埠使用 */
        int start_frame;                /* 僅實時型別資料包使用,起始幀數量 */
        int number_of_packets;          /* (in) number of ISO packets */
        int interval;                   /* urb傳送到USB核心之前設定,處理終端間隔 僅對中斷型別埠與實時埠有效 */
        int error_count;                /* USB核心設定,報告實時埠傳輸結束後的實時傳輸錯誤數量 */
        void *context;                   /* 終結傳輸無資料小包位置 */
        usb_complete_t complete;         /* 終結函式指標 void (*usb_complete_t)(struct urb *);控制權返回驅動*/
        struct usb_iso_packet_descriptor /*可以一次定義多個實時傳輸 */
        {
          unsigned int offset;
          unsigned int length;            /* expected length */
          unsigned int actual_length;
          int status;
        };
};

[0x250]使用者空間USB裝置列表

#include <linux/usb.h>
struct usb_device_id {
       /*用來匹配識別USB裝置方式 不直接設定 #include linux/mod_devicetable.h USB_DEVICE_*()*/
        __u16           match_flags;    
        __u16           idVendor;      /*裝置廠商編號*/
        __u16           idProduct;     /*產品型號*/
        __u16           bcdDevice_lo;  /*裝置特徵版本編號最小值*/
        __u16           bcdDevice_hi;  /*裝置特徵版本編號最大值*/

        /* Used for device class matches */
        __u8            bDeviceClass;    /*裝置主類編號*/
        __u8            bDeviceSubClass; /*繫結主類的裝置次類編號*/
        __u8            bDeviceProtocol; /*繫結主類的裝置協議編號*/

        /* Used for interface class matches */
        __u8            bInterfaceClass;    /*介面主類編號*/
        __u8            bInterfaceSubClass; /*繫結主類的介面次類編號*/
        __u8            bInterfaceProtocol; /*繫結主類的介面協議編號*/

        /* not matched against */
        kernel_ulong_t  driver_info; /*驅動描述或者裝置描述標識*/
};

[0x260]USB驅動資料結構

#include <linux/usb.h>
struct usb_driver {
        /*驅動程式標識名稱,應該與模組名稱一致*/
        const char *name;
        /*探測函式指標 可選配置*/
        int (*probe) (struct usb_interface *intf,const struct usb_device_id *id);
        /*裝置斷開連線或者驅動程式沒有載入的清理工作*/
        void (*disconnect) (struct usb_interface *intf);
        /*USBfs 配置函式,用於驅動程式與使用者空間的通訊*/
        int (*unlocked_ioctl) (struct usb_interface *intf, unsigned int code,void *buf);
        /*USB核心裝置抑制、喚醒、重置替代喚醒 處理函式回撥*/
        int (*suspend) (struct usb_interface *intf, pm_message_t message);
        int (*resume) (struct usb_interface *intf);
        int (*reset_resume)(struct usb_interface *intf);
        /*重置檢測URB啟用狀態*/
        int (*pre_reset)(struct usb_interface *intf);
        int (*post_reset)(struct usb_interface *intf);
        /*USB外設列表*/
        const struct usb_device_id *id_table;
 
        struct usb_dynids dynids;
        struct usbdrv_wrap drvwrap;
        
        unsigned int no_dynamic_id:1;
        unsigned int supports_autosuspend:1;
        unsigned int soft_unbind:1;
};

[0x270]USB裝置 字元裝置類結構

struct usb_class_driver {
        char *name;                                          //sysfs 中裝置路徑名
        char *(*devnode)(struct device *dev, umode_t *mode); //為裝置建立devfs檔案處理函式
        const struct file_operations *fops;                  //裝置檔案操作函式集
        int minor_base;                                      //次裝置號起始值
};

[0x300]USB request Block

[0x310] urb生命週期

[0x320] urb端點屬性

[0x321] urb埠型別與傳輸方向標識[unsigned int pipe]

功能 操作位 描述
資料方向 【bit 7】 0 = 主機->裝置 1 = 裝置到主機
裝置編號 【bits 08-14】 位地址指導來自於uhci-hcd控制器
端點編號 【bits 15-18】 位地址指導來自於uhci-hcd控制器
端點型別 【bits 30-31】 (00 = 實時, 01 = 中斷,10 = 控制命令, 11 = 非同步批量)
#include <linux/usb.h>
#define PIPE_ISOCHRONOUS                0               /*實時埠型別*/
#define PIPE_INTERRUPT                  1               /*中斷埠型別*/
#define PIPE_CONTROL                    2               /*控制埠型別*/
#define PIPE_BULK                       3               /*非同步批量埠*/

#define USB_DIR_OUT                     0               /* 主機向USB外設傳送資料標識 */
#define USB_DIR_IN                      0x80            /* 外設向USB宿主機發送資料標識 */

#define usb_pipein(pipe)        ((pipe) & USB_DIR_IN)   /*裝置向主機送資料*/
#define usb_pipeout(pipe)       (!usb_pipein(pipe))     /*主機向外設送資料*/

#define usb_pipedevice(pipe)    (((pipe) >> 8) & 0x7f)  /*獲取USB裝置編號 bit08-bit14*/
#define usb_pipeendpoint(pipe)  (((pipe) >> 15) & 0xf)  /*獲取USB埠編號 bit15-bit18*/

#define usb_pipetype(pipe)      (((pipe) >> 30) & 3)    /*埠型別決定傳輸資料型別*/
#define usb_pipeisoc(pipe)      (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS) /*設定 實時型別埠*/
#define usb_pipeint(pipe)       (usb_pipetype((pipe)) == PIPE_INTERRUPT)   /*設定 中斷型別埠*/
#define usb_pipecontrol(pipe)   (usb_pipetype((pipe)) == PIPE_CONTROL)     /*設定 控制型別埠*/
#define usb_pipebulk(pipe)      (usb_pipetype((pipe)) == PIPE_BULK)        /*設定 批量型別埠*/

/* Create various pipes... */
#define usb_sndctrlpipe(usb_device, endpoint)  \                          /*設定 控制型別 傳送埠*/
        ((PIPE_CONTROL << 30) | __create_pipe(usb_device, endpoint))
#define usb_rcvctrlpipe(usb_device, endpoint)  \                          /*設定 控制型別 接收埠*/
        ((PIPE_CONTROL << 30) | __create_pipe(usb_device, endpoint) | USB_DIR_IN)
#define usb_sndisocpipe(usb_device, endpoint)  \                          /*設定 實時型別 傳送埠*/
        ((PIPE_ISOCHRONOUS << 30) | __create_pipe(usb_device, endpoint))
#define usb_rcvisocpipe(usb_device, endpoint)  \                          /*設定 實時型別 接收埠*/
        ((PIPE_ISOCHRONOUS << 30) | __create_pipe(usb_device, endpoint) | USB_DIR_IN)
#define usb_sndbulkpipe(usb_device, endpoint)  \                          /*設定 批量型別 傳送埠*/
        ((PIPE_BULK << 30) | __create_pipe(usb_device, endpoint))
#define usb_rcvbulkpipe(usb_device, endpoint)  \                          /*設定 批量型別 接收埠*/
        ((PIPE_BULK << 30) | __create_pipe(usb_device, endpoint) | USB_DIR_IN)
#define usb_sndintpipe(usb_device, endpoint)   \                          /*設定 中斷型別 傳送埠*/
        ((PIPE_INTERRUPT << 30) | __create_pipe(usb_device, endpoint))
#define usb_rcvintpipe(usb_device, endpoint)   \                          /*設定 中斷型別 接收埠*/
        ((PIPE_INTERRUPT << 30) | __create_pipe(usb_device, endpoint) | USB_DIR_IN)
/*核心函式實現*/        
static inline unsigned int __create_pipe(struct usb_device *dev,unsigned int endpoint)
{
        return (dev->devnum << 8) | (endpoint << 15);
}

[0x322] urb埠傳輸型別標識[unsigned int transfer_flags]

#define URB_SHORT_NOT_OK        0x0001  /* report short reads as errors */
#define URB_ISO_ASAP            0x0002  /* iso-only, urb->start_frame ignored */
#define URB_NO_TRANSFER_DMA_MAP 0x0004  /* urb->transfer_dma valid on submit */
#define URB_NO_FSBR             0x0020  /* UHCI-specific */
#define URB_ZERO_PACKET         0x0040  /* Finish bulk OUT with short packet */
#define URB_NO_INTERRUPT        0x0080  /* HINT: no non-error interruptneeded */
#define URB_FREE_BUFFER         0x0100  /* Free transfer buffer with the URB */

/* The following flags are used internally by usbcore and HCDs */
#define URB_DIR_IN              0x0200  /* Transfer from device to host */
#define URB_DIR_OUT             0
#define URB_DIR_MASK            URB_DIR_IN
功能 描述
URB_SHORT_NOT_OK 對於外設向主機傳送的短資料,將被USB核心認定為錯誤
URB_ISO_ASAP 只有實時型別的埠 強制等待指定start_frame
URB_NO_TRANSFER_DMA_MAP USB核心向DMA緩衝區傳輸資料,即向transfer_dma而不是transfer_buffer
URB_NO_FSBR 主控器設定的標識位,不執行前端匯流排回收邏輯
URB_ZERO_PACKET 主機到外設傳送資料時,使用無資料小資料包結束髮送
URB_NO_INTERRUPT 目標裝置不會產生中斷,通常用於USB核心到DMA緩衝區傳輸資料
URB_FREE_BUFFER 清空Urb埠的傳輸緩衝區

[0x330] urb函式介面

[0x331] 建立與銷燬urb結構空間

Func :建立一個urb埠結構
args1:實時包計數;
args2:用於kmalloc 記憶體分配的型別標識,通常GFP_kernel;
retal :成功返回struct urb 地址 失敗 為NULL

/*implement drivers/usb/core/urb.c*/
struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
{
        struct urb *urb;

        urb = kmalloc(sizeof(struct urb) +
                iso_packets * sizeof(struct usb_iso_packet_descriptor),
                mem_flags);
        if (!urb) {
                printk(KERN_ERR "alloc_urb: kmalloc failed\n");
                return NULL;
        }
        usb_init_urb(urb);
        return urb;
}
/*銷燬urb結構空間*/
void usb_free_urb(struct urb *urb)
{
        if (urb)
                kref_put(&urb->kref, urb_destroy);
}
  • 不可以手動建立struct urb,會破壞USB核心的引用計數機制;
  • 如果不想建立實時型別埠,第一個引數應該為0;

[0x332] 填充不同型別的urb埠

引數 描述 需配置埠型別
struct urb *urb 初始化urb指標 詳見[0x331]建立urb 通用標準
struct usb_device *dev USB外設結構 通用標準
unsigned int pipe 傳送方向與埠型別,詳見[0x321] urb埠型別與傳輸方向標識 通用標準
void *transfer_buffer 資料緩衝區,必須是kmalloc建立的位置 通用標準
int buffer_length 資料緩衝區大小 通用標準
usb_complete_t complete_fn urb 結束後的銷燬規程函式指標 通用標準
void *context 置零的小資料塊用於結束髮送 通用標準
int interval urb允許中斷間隔 終端埠與實時埠
unsigned char *setup_packet, 傳送至端點的配置資料的地址 控制埠
unsigned int transfer_flags 傳輸型別標識 詳見 [0x322] urb埠傳輸型別標識 實時埠
int number_of_packets 實時包數量 實時埠
struct usb_iso_packet_descriptor iso_frame_desc[0] 定義多個實時傳輸例項 實時埠
#include <linux/usb.h>
/*建立批量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->complete   = urb_complete_iso;     /* handler */
                urb->dev        = udev;
                urb->context    = video->front;
                urb->pipe       = usb_rcvisocpipe(udev, video->endpoint_addr);
                urb->interval   = 1;
                urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
                urb->number_of_packets  = PK_PER_URB;
                urb->transfer_buffer    = mem;
                urb->transfer_buffer_length = PK_PER_URB * ISO_PKT_SIZE;

                for (j = 0; j < PK_PER_URB; j++) {
                        urb->iso_frame_desc[j].offset = ISO_PKT_SIZE * j;
                        urb->iso_frame_desc[j].length = ISO_PKT_SIZE;
                }

[0x333] 註冊urb埠

int usb_submit_urb(struct urb *urb, gfp_t mem_flags)

Func :將urb資料結構提交到USB核心註冊埠裝置,允許在中斷上下文使用,控制權到USB核心;
args1:初始化urb指標 詳見[0x331]建立urb;
args2:用於kmalloc 記憶體分配的型別標識,
根據不同使用環境 不同 不允許休眠=GFP_ATOMIC 塊裝置路徑 GFP_NOIO其它都是GFP_KERNEL;
retal :正確返回0 錯誤錯誤碼

[0x334]初始化與釋放 urb 緩衝區

/*建立一個 DMA urb 緩衝區*/
static inline void *
usb_buffer_alloc(struct usb_device *dev, size_t size,gfp_t mem_flags, dma_addr_t *dma)
{
        return usb_alloc_coherent(dev, size, mem_flags, dma);
}
/*銷燬一個 DMA urb 緩衝區*/

            
           

相關推薦

linux驅動基礎開發1——linux 裝置驅動基本概念

二、裝置型別 硬體是千變萬化的,沒有八千也有一萬了,就像世界上有三種人:男人、女人、女博士一樣,linux做了一個很偉大也很艱難的分類:把所有的硬體裝置分為三大類:字元裝置、塊裝置、網路裝置。 1)字元裝置:字元(char)裝置是個能夠像位元組流(類似檔案)一樣被訪問的裝置。     對字

linux驅動基礎開發0——linux 裝置驅動概述

目前,Linux軟體工程師大致可分為兩個層次:  (1)Linux應用軟體工程師(Application Software Engineer): 主要利用C庫函式和Linux API進行應用軟體的編寫;       從事這方面的開發工作,主要需要學習:符合linux posix標準的API函式及系統呼

USB裝置驅動基礎 &gt;&gt;Linux裝置驅動程式

最常用的裝置卻不懂它的工作原理,豈不是最大的不尊敬,感謝USB為我們帶來的便利; 今天也要繼續堅定的前行的… 文章目錄 [0x100] 特徵與概念 [0x110] USB介面特徵 [0x120] USB驅動型別 [0x1

PCI驅動基礎 &gt;&gt; Linux裝置驅動程式

俗話說的好,免費是最貴,閒暇是最累的,但是我自己選的路就要負責走完; 壓力一天比一天重,當學習了理論卻不知道該如何輸出的時候,會有一種油然而生的挫敗感; 看來必須得調整自己的心態還是要調整學習方法,如何才能用最好狀態去接受新的知識; 文章目錄 [0x1

kobject,Kset,bus_type &gt;&gt;Linux裝置驅動程式

狀態不錯,快要元旦了,這是我計劃開始的第一年;時間過的真快啊! 也是逃離舒適圈的一年,不能在日復一日的無聊工作沉浸下去,要明白自己今生適合做哪些事情,而不是隨波逐流; 文章目錄 [0x100]內容概述 [0x110] 核心的裝置管理特性

IO記憶體 與 IO埠 &gt;&gt;Linux 裝置驅動程式

啥時候要是寫程式碼的時候像玩遊戲一樣開心就好了,我覺得那一天應該不會遙遠,要做一個快樂的小二逼 哈哈哈; 懂得越多責任就越重大,喜歡責任重大,那就要讓自己一天天的變強大。 如是說就得每天早上給自己一杯自己造的“雞血”喝,熱乎乎的比別人給的容易喝下去;不是嗎? 文章

分配記憶體相關函式 &gt;&gt;Linux裝置驅動程式

據離職開始自學轉行到現在已經有3個月的時間,理解了為啥只有少部分願意去理解核心,不是沒有原因的; 承受著多種壓力和快節奏的生活,讓人們越來越趨向於即時反饋,這樣其實並不是很好; 有段可以安安靜靜自我提升的時間簡直就是奢望,比起他們來說我已經很幸運了; 看了加布里爾·穆奇諾的《當幸福來

jiffies操作、核心計時器、tasklet、workqueue 相關函式 &gt;&gt;Linux裝置驅動程式

文章目錄 [0x100] 內容概述 [0x200] 與延遲有關的核心應用 [0x210] jiffies 時鐘中斷計數器 [0x211] 獲取計數值 [0x212] 比較計數值 [0x213] 計數值的轉換

Ioctl命令組成、阻塞IO實現、IO多路複用 &gt;&gt;Linux裝置驅動程式

我又來了,一天學習一點點,一天成長一點點就會很開心的說! 今天的狀態很好,況且還有好喝的咖啡陪伴著我,元氣滿滿喲!^. ^? 文章目錄 [0x100]內容概述 [0x200] 編寫ioctl的命令編號 [0x210]命令編號組成

管理訊號量、自旋鎖、原子變數函式介面&gt;&gt;Linux 裝置驅動程式

文章目錄 [0x100] 程序競態特徵 [0x200] 訊號量 [0x210] 程序訊號量函式介面[struct semaphore] [0x211] 初始化訊號量 [0x212] 獲取與釋放訊號量 [0x2

核心程式除錯手段 &gt;&gt;Linux裝置驅動程式

文章目錄 [0x100]常用核心除錯方式 [0x110]核心的DEBUG選項 [0x120]核心列印函式 >>printk [0x121]預設規則 [0x122]終端列印日誌級別配置 [0x12

註冊字元裝置 &gt;&gt;Linux裝置驅動程式

文章目錄 [0x100] 字元裝置相關規則 [0x110]裝置檔案特徵 [0x120]裝置編號特徵 [0x200]操作函式介面核心實現 [0x210]轉換裝置編號 [0x220]分配裝置編號 [0x2

《5.linux驅動開發-第2部分-5.2.字元裝置驅動基礎

《5.linux驅動開發-第2部分-5.2.字元裝置驅動基礎》 第一部分、章節目錄 5.2.1.開啟驅動開發之路 5.2.2.最簡單的模組原始碼分析1 5.2.3.最簡單的模組原始碼分析2 5.2.4.最簡單的模組原始碼分析3 5.2.5.用開發板來除錯模組 5.2.6.字元裝置驅動工作

14 Linux裝置驅動基礎程式設計

Linux裝置驅動基礎程式設計 核心功能模組:程序排程,記憶體管理(mmu,分配程序記憶體),檔案系統管理(如:支援的檔案系統格式),裝置驅動(硬體驅動由核心來統一管理),網路協議棧。 模組機制: 靜態載入:把驅動模組編進核心,在核心啟動時自動載入。 動態載入:把驅動模

13 Linux裝置驅動基礎知識

Linux裝置驅動基礎知識 驅動是硬體與使用者程序之間的通訊橋樑。 使用者程序是不可以直接訪問硬體的。 資料是驅動先接收到硬體反饋的資料處理後再移交給使用者程序的。 驅動不屬於任何一個使用者程序,可以給多個使用者程序呼叫。 驅動是常駐於記憶體裡,等待使用者程序呼叫。

linux驅動基礎知識-白陽(四) 字元裝置

相關標頭檔案 #include <linux/init.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/of.h> #in

Linux核心驅動基礎-裝置樹相關匯流排使用

mmc匯流排使用例項 broken-cd  表示沒有熱插拔探測引腳,使用輪詢檢測 cd-gpios  使用gpio管腳作為熱插拔探測引腳 non-removable  表示不能進行熱插拔,裝置一直連線(比如eMMC) 上面三個選項用於指定熱插拔探測選項,如果三個選項都沒有指

linux裝置驅動USB資料傳輸分析(之五)

也許,有人會有這樣的疑問: 對於控制傳輸,它不也是基於toggle的糾錯麼,為什麼它就不需要修改後續的包的toggle值呢? 這是因為,控制傳輸的toggle都是從1開始的,刪除掉當前的urb,也不會對後面的發包造成影響. 之後,處理完之後,將無用的td刪除. 跟

Linux裝置驅動USB hub驅動(續)

5.2.2:介面驅動中的hub_thread()函式 我們之前在分析usb_hub_init()的程式碼的時候,忽略掉了一部份. 程式碼片段如下所示: int usb_hub_init(void) {    ……     khubd_task = kthread_run(hub_thread, NULL, "

linux裝置驅動USB主機控制器驅動分析 (一)

一:前言 Usb是一個很複雜的系統.在usb2.0規範中,將其定義成了一個分層模型.linux中的程式碼也是按照這個分層模型來設計的.具體的分為 usb裝置,hub和主機控制器三部份.在閱讀程式碼的時候,必須要參考相應的規範.最基本的就是USB2.0的spec.