USB裝置驅動基礎 >>Linux裝置驅動程式
最常用的裝置卻不懂它的工作原理,豈不是最大的不尊敬,感謝USB為我們帶來的便利;
今天也要繼續堅定的前行的…
文章目錄
- [0x100] 特徵與概念
- [0x110] USB介面特徵
- [0x120] USB驅動型別
- [0x130] USB裝置基本組成
- [0x131] 端點[struct usb_host_endpoint]
- [0x132] 介面[struct usb_host_interface]
- [0x133] 配置規則[struct usb_host_config]
- [0x140] USB request Block [struct urb]
- [0x200]相關資料結構
- [0x210] USB 端點描述結構
- [0x220] USB 介面描述結構
- [0x230] USB 介面配置結構
- [0x240] USB urb結構
- [0x250]使用者空間USB裝置列表
- [0x260]USB驅動資料結構
- [0x270]USB裝置 字元裝置類結構
- [0x300]USB request Block
- [0x400] USB驅動程式
- [0x410] 填充USB裝置列表[struct usb_device_id]
- [0x420] 註冊與登出驅動程式到核心
- [0x430] 新插入裝置獲取讀寫端點
- [0x440] USB介面 獲取與儲存 USB端點資料
- [0x450] USB介面設備註冊與登出
- [0x460] 分配urb埠
- [0x500] 非urb驅動程式
[0x100] 特徵與概念
[0x110] USB介面特徵
- 主從樹形點對點結構,主機控制器輪詢連線,從機控制器迴應資料;
- 四線結構雙線傳輸,地線、電源、接收訊號線、傳送訊號線;
- 非結構型別的通訊方式,遮蔽了下層的硬體裝置,以序列資料流的方式來傳輸資料;
- 支援熱插拔功能;
[0x120] USB驅動型別
- USB裝置驅動 :宿主機控制硬體作為USB裝置與主機通訊;
- USB器件驅動 :USB裝置如何控制連線到計算機,之前只能傳送資料,現在可以傳送指令,由器件驅動去執行;
[0x130] USB裝置基本組成
[0x131] 端點[struct usb_host_endpoint]
- 定義 :單方向傳輸資料的管道類通道,共有四種類型;
- 控制端點 :配置新入裝置初始化,獲取裝置狀態資訊,向裝置傳送命令;
- 中斷端點 :用於接收少量高頻率的資料,如 鍵盤、滑鼠等等;
- 批量端點 :不可靠的非同步大量資料傳輸,;
- 實時端點 :可靠恆定速率大量資料傳輸,用於高實時的資料傳輸;
[0x132] 介面[struct usb_host_interface]
- 定義 :同邏輯型別USB埠的繫結抽象
- 不同的介面執行不同的單一邏輯職能,不同的頻寬
- 每個介面可以擁有多個可選配置
- 介面的計數從0開始計數;
- 實際驅動程式中要使用的結構 struct usb_device 而不是結構結構體本身;
[0x133] 配置規則[struct usb_host_config]
- USB 裝置捆綁多個介面,介面捆綁多個配置
- 一個介面只可以啟用一個配置,裝置可以繫結多個介面,一次有多個配置;
- 需要繫結到介面使用,不能單獨使用
[0x140] USB request Block [struct urb]
- 定義:異步向指定裝置的指定埠傳送/接收資料;
- 每個埠可以接收多個urb的資料收發,也可以多個埠共享一個urb;
- 一種埠間的非同步通訊機制;
[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裝置驅動基礎 >>Linux裝置驅動程式
最常用的裝置卻不懂它的工作原理,豈不是最大的不尊敬,感謝USB為我們帶來的便利; 今天也要繼續堅定的前行的…
文章目錄
[0x100] 特徵與概念
[0x110] USB介面特徵
[0x120] USB驅動型別
[0x1
PCI驅動基礎 >> Linux裝置驅動程式
俗話說的好,免費是最貴,閒暇是最累的,但是我自己選的路就要負責走完; 壓力一天比一天重,當學習了理論卻不知道該如何輸出的時候,會有一種油然而生的挫敗感; 看來必須得調整自己的心態還是要調整學習方法,如何才能用最好狀態去接受新的知識;
文章目錄
[0x1
kobject,Kset,bus_type >>Linux裝置驅動程式
狀態不錯,快要元旦了,這是我計劃開始的第一年;時間過的真快啊! 也是逃離舒適圈的一年,不能在日復一日的無聊工作沉浸下去,要明白自己今生適合做哪些事情,而不是隨波逐流;
文章目錄
[0x100]內容概述
[0x110] 核心的裝置管理特性
IO記憶體 與 IO埠 >>Linux 裝置驅動程式
啥時候要是寫程式碼的時候像玩遊戲一樣開心就好了,我覺得那一天應該不會遙遠,要做一個快樂的小二逼 哈哈哈; 懂得越多責任就越重大,喜歡責任重大,那就要讓自己一天天的變強大。 如是說就得每天早上給自己一杯自己造的“雞血”喝,熱乎乎的比別人給的容易喝下去;不是嗎?
文章
分配記憶體相關函式 >>Linux裝置驅動程式
據離職開始自學轉行到現在已經有3個月的時間,理解了為啥只有少部分願意去理解核心,不是沒有原因的; 承受著多種壓力和快節奏的生活,讓人們越來越趨向於即時反饋,這樣其實並不是很好; 有段可以安安靜靜自我提升的時間簡直就是奢望,比起他們來說我已經很幸運了; 看了加布里爾·穆奇諾的《當幸福來
jiffies操作、核心計時器、tasklet、workqueue 相關函式 >>Linux裝置驅動程式
文章目錄
[0x100] 內容概述
[0x200] 與延遲有關的核心應用
[0x210] jiffies 時鐘中斷計數器
[0x211] 獲取計數值
[0x212] 比較計數值
[0x213] 計數值的轉換
Ioctl命令組成、阻塞IO實現、IO多路複用 >>Linux裝置驅動程式
我又來了,一天學習一點點,一天成長一點點就會很開心的說! 今天的狀態很好,況且還有好喝的咖啡陪伴著我,元氣滿滿喲!^. ^?
文章目錄
[0x100]內容概述
[0x200] 編寫ioctl的命令編號
[0x210]命令編號組成
管理訊號量、自旋鎖、原子變數函式介面>>Linux 裝置驅動程式
文章目錄
[0x100] 程序競態特徵
[0x200] 訊號量
[0x210] 程序訊號量函式介面[struct semaphore]
[0x211] 初始化訊號量
[0x212] 獲取與釋放訊號量
[0x2
核心程式除錯手段 >>Linux裝置驅動程式
文章目錄
[0x100]常用核心除錯方式
[0x110]核心的DEBUG選項
[0x120]核心列印函式 >>printk
[0x121]預設規則
[0x122]終端列印日誌級別配置
[0x12
註冊字元裝置 >>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.