驅動程式之 1 字元裝置 1

2021-09-09 07:17:20 字數 3039 閱讀 2962

linux裝置驅動分三種,包括字元裝置驅動、塊裝置驅動和網路裝置驅動

其中本文講的字元裝置(如lcd、觸控螢幕等)只能按位元組流先後順序訪問裝置記憶體,不能隨機訪問

字元裝置的基本框架比較簡單

載入驅動時,呼叫入口函式

解除安裝驅動時,呼叫出口函式

應用程式開啟驅動裝置時,呼叫open函式

應用程式讀寫驅動裝置時,呼叫read、write函式

……open、read、write等函式是在linux核心中的統一介面,使用open開啟裝置會返回乙個檔案識別符號,通過檔案識別符號使用read、write等函式會呼叫到裝置自己的read、write函式,從而操作到硬體,這些裝置自己的函式都被存放在乙個檔案結構體中

編寫字元裝置驅動的基本流程:

1、定義、設定檔案結構體

2、編寫入口函式,註冊結構體

3、編寫出口函式,銷毀結構體

4、在裝置開啟時,初始化裝置硬體

5、編寫read、write等功能函式

6、包含一些標頭檔案(參考其他驅動程式即可)

如:入口函式

static int __init ledsinit(void)

出口函式

static void __exit led***it(void)

入口、出口函式需要修飾:

module_init(ledsinit);

module_exit(led***it);

結構體定義

static struct file_operations g_tledsfops = 

;

open、read、write函式宣告如下

static int ledsopen(struct inode *ino, struct file *filep);

static ssize_t ledswrite(struct file *fd, const char __user *buf, size_t cnt, loff_t * lof);

ssize_t ledsread(struct file *file, char __user *buf, size_t size, loff_t * ppos);

註冊結構體所用函式原型

int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
可以人為建立裝置,分配主裝置號,然後在major中輸入相應值,但一般來說都會使用linux核心所自帶的mdev機制,自動分配裝置號,建立裝置,具體操作如下:

定義class、class_device指標變數

static struct class *g_ptledsclass;

static struct class_device *g_ptledsclassdevice;

建立class和class_device所用函式原型

extern struct class *class_create(struct module *owner, const char *name);

extern struct class_device *class_device_create(struct class *cls,

struct class_device *parent,

dev_t devt,

struct device *device,

const char *fmt, ...)

__attribute__((format(printf,5,6)));

銷毀class和class_device所用函式原型

extern void class_unregister(struct class *);

extern void class_device_destroy(struct class *cls, dev_t devt);

使用mdev機制需要包含gpl協議

module_license("gpl");
附上乙個關於led的驅動程式和測試用的應用程式,**僅起示例作用

驅動程式

#include #include #include #include #include #include #include #include #include #include #include #include #include static volatile unsigned long *g_dwgpfcon,*g_dwgpfdat;

static struct class *g_ptledsclass;

static struct class_device *g_ptledsclassdevice;

static int ledopen(struct inode *ino, struct file *filep)

static ssize_t ledwrite(struct file *fd, const char __user *buf, size_t cnt, loff_t * lof)

if(!strcmp(argc[1],"on"))

else if(!strcmp(argc[1],"off"))

else

if(!strcmp(argc[2],"1"))

else if(!strcmp(argc[2],"2"))

else if(!strcmp(argc[2],"3"))

else if(!strcmp(argc[2],"all"))

else

ifd = open("/dev/leds",o_rdwr);

if(ifd < 0)

ierror = write(ifd,&ival,sizeof(ival));

return 0;

}

驅動程式之 1 字元裝置 3

基本排程關係 在應用程式中呼叫poll poll呼叫sys poll sys poll呼叫do sys poll do sys poll呼叫do poll do poll呼叫do pollfd do pollfd呼叫我們的驅動程式實現的my irq drv poll,my irq drv poll呼...

驅動程式之 1 字元裝置 7

阻塞操作 是指在執行裝置操作時若不能獲得資源則掛起程序,直到滿足可操作的條件後再進行操作。被掛起的程序進入休眠狀態,被從排程器的執行佇列移走,直到等待的條件被滿足。非阻塞操作 程序在不能進行裝置操作時並不掛起,它或者放棄,或者不停地查詢,直至可以進行操作為止。驅動程式中 如果是以非阻塞方式開啟檔案,...

驅動程式之 1 字元裝置 8

按下按鍵時,由於按鍵抖動,會產生幾個高低脈衝,而cpu處理太快,這幾次高低脈衝被當作有效訊號處理,處理辦法 使用定時器,檢測到第一次按下後,啟動定時器,延遲一段時間 一般取10ms 再檢測一次,如果這時候檢測到按鍵按下,則確定有按鍵按下 驅動程式中執行流程 按鍵中斷觸發後,記錄鍵值,修改定時值,10...