Ubuntu17 01下一次簡單的字元驅動程式設計

2021-08-14 06:48:36 字數 3268 閱讀 7444

驅動程式是一類特殊的應用程式,是針對特定的硬體裝置編寫的程式,它提供了對硬體的基本操作,作業系統可以通過驅動程式來控制硬體裝置。裝置驅動程式是作業系統核心的基本組成部分。

linux將所有的裝置都當作檔案處理,稱為裝置檔案。「/dev」目錄下存在對應的邏輯裝置節點,並且以檔案的形式存在。linux系統下裝置檔案分為四類:字元裝置檔案、塊裝置檔案、網路裝置檔案、雜項裝置檔案。在裝置管理中,除了裝置型別,核心還要主裝置號和次裝置號來唯一標識裝置。主裝置號代表裝置的類別,次裝置號區分具體裝置。

驅動程式可以直接編譯到核心,也可以編寫成模組,在需要時調入。直接編譯到核心的優點是可以隨時呼叫,無需安裝,但是編譯到核心的話需要對核心進行重編譯,重啟系統,花費時間過長,而編寫成模組的話可以隨時對模組進行解除安裝載入,開發方便,因而此次實驗中將驅動程式編寫成模組。

核心模組中通常都需要載入和解除安裝函式來對裝置進行註冊/登出,因此設計載入/解除安裝函式:

#include 

#include

#include

#include

#define chardriver_major 234

static ssize_t cread(struct file *, char *, size_t, loff_t *);

static ssize_t cwrite(struct file*, const

char*, size_t, loff_t*);

struct file_operations char_ops = ;

static

int global_var = 0;

static

int __init chardriver_init(void)

printk("init succeed");

return0;}

static

void __exit chardriver_exit(void)

printk("exit succeed");

}module_init(chardriver_init);

module_exit(chardriver_exit);

module_license("gpl");

巨集module_init和module_exit用來註冊初始化/解除安裝函式,如上,chardriver_init被註冊為初始化函式,chardriver_exit

被註冊為解除安裝函式,分別在模組載入/解除安裝時被呼叫,module_license宣告模組的許可協議。裝置的主裝置號被指定為234,裝置名」chardriver」。

可以看到,上面**中還宣告了cread和cwrite兩個函式,並定義了乙個struct file_operations型別的變數char_ops,關於file_operations

的定義在」include/linux/fs.h「中可以找到,其中有成員

read和write,型別為函式指標,read用來讀取裝置,write對裝置進行寫。而」read:cread,write:cwrite」指定了讀取/寫入裝置的處理函式cread和cwrite。

下面是cread和cwrite的函式定義:

static ssize_t cwrite(struct file *file, const

char *buffer, size_t count, loff_t *ppos)

static ssize_t cread(struct file* file, char *buffer, size_t count, loff_t*ppos)

copy_to_user和copy_from_user原型在」uaccess.h」中,宣告如下:

unsigned long copy_from_user(void *to, const void *from, unsigned long n);

unsigned long copy_to_user (void * to, void * from, unsigned long len);

返回值是不能複製的位元組數。

將上面寫好的**另存為檔案chardriver.c,編寫makefile:

obj-m := chardriver.o

all:

$(make) -c /lib/modules/$(shell uname -r)/build m=$(

pwd) modules

clean:

$(make) -c /lib/modules/$(shell uname -r)/build m=$(

pwd) clean

儲存到同一目錄下,執行make命令,編譯成功後目錄下會有chardriver.ko檔案執行命令;

insmod chardriver.ko,執行時需要管理員許可權,因此可能系統會提示操作被拒絕,可以用「sudo insmod chardriver.ko」提公升許可權後再插入模組。

如果插入成功的話使用命令lsmod檢視已載入模組可以看到chardriver。

接下來執行「mknod /dev/chardriver c 234 0」建立裝置,裝置名為chardriver,型別為「c」即字元裝置,主裝置號234,次裝置號0。

使用「cat /proc/devices」檢視裝置可以看到「234 chardriver」一項。

接下來編寫測試檔案:

#include

#include

#include

#include

#include

int main()

if(fd>=0)

if(fd>=0)

}

編譯後執行,測試成功。

遇到的錯誤:

1、提示read:cread語句中指標不相容,錯誤提示如下圖。經查發現是因為cread函式宣告與file_operations中的read所指向的函式宣告不同,修改cread宣告後編譯成功。

2、執行測試程式,開啟裝置失敗。經過網友啟發,提公升許可權,使用管理員許可權執行測試程式,測試通過。原因不明。但猜測有可能是因為裝置處於核心態,因而禁止普通使用者的訪問。

739。下一次公升溫時間

如題目所示 解題思路 核心就是以後面的數來定義前面的數。利用棧來儲存前面的比棧頂小的數字的下標,方便獲取到第乙個大的數,並且該數一直和剩下的數相比較。class solution tmp.emplace i return res 方法二 採用從後面開始,然後先初始化res所有為0,從最後乙個往後面找...

重灌Ubuntu系統 從第一次到下一次

home下的所有東西 root下看看有沒有東西 root bashrc etc profile可以保留乙份。用軟碟通製作u盤系統 用軟碟通開啟.iso檔案 寫入硬碟映象 寫入方式預設hdd 如果發現製作好了進不去系統,可以選擇raw。u盤啟動 看情況選擇安裝選項 安裝完成之後u盤可能會顯示只有十幾k...

linux下一次cp多個檔案

linux下使用cp命令拷貝多個檔案有幾種方法,一是使用萬用字元,二是使用管道 一.萬用字元的使用 萬用字元是一種特殊語句,主要有星號 和問號 用來模糊搜尋檔案。主要的萬用字元有 匹配任意長度的字串 匹配乙個長度的字元 匹配其中指定的字元 a z 匹配指定的字元範圍 除了其中指定的字元,其他均可匹配...