三、字元裝置的註冊於登出
四、裝置號
五、file_operations的具體實現
六、驅動**工程
七、linux基本應用程式開發
字元裝置驅動的編寫主要就是驅動對應的open、close、read…其實就是file_operations結構體的成員變數的實現。
應用程式執行在使用者空間,而 linux 驅動屬於核心的一部分,因此驅動執行於核心空間。當我們在使用者空間想要實現對核心的操作,比如使用 open 函式開啟/dev/led 這個驅動,因為使用者空間不能直接對核心進行操作,因此必須使用乙個叫做「系統呼叫」的方法來實現從使用者空間「陷入」到核心空間,這樣才能實現對底層驅動的操作。open、close、write 和 read 等這些函式是由 c 庫提供的,在 linux 系統中,系統呼叫作為 c 庫的一部分。當我們呼叫 open 函式的時候流程如下圖:
程式設計師重點關注的是應用程式和具體的驅動,應用程式使用到的函式在具體驅動程式中都有與之對應的函式,比如應用程式中呼叫了 open 這個函式,那麼在驅動程式中也得有乙個名為 open 的函式。每乙個系統呼叫,在驅動中都有與之對應的乙個驅動函式,在 linux 核心檔案include/linux/fs.h中有個叫做 file_operations 的結構體,此結構體就是 linux 核心驅動操作函式集合,內容如下:
struct file_operations
;
簡單介紹一下 file_operation 結構體中比較重要的、常用的函式:
模組有載入和解除安裝兩種操作,我們在編寫驅動的時候需要註冊這兩種操作函式:
linux核心使用dev_t
typedef
unsigned
int __u32;
typedef __u32 __kernel_dev_t;
typedef __kernel_dev_t dev_t;
裝置號分為兩個部分:高12位是主裝置號(0~4056),低20位是次裝置號(1048576)。裝置號的核心巨集操作在:/include/linux/kdev_t.h
#define minorbits 20
#define minormask ((1u << minorbits) - 1)
#define major(dev) ((unsigned int) ((dev) >> minorbits))
#define minor(dev) ((unsigned int) ((dev) & minormask))
#define mkdev(ma,mi) (((ma) << minorbits) | (mi))
linux下使用命令:cat /proc/devices
檢視系統內所有裝置:第一列是主裝置號 ,第二列是裝置名
linux下使用命令:cat /proc/devices
檢視系統內所有裝置:第一列是主裝置號 ,第二列是裝置名
檢視空餘的主裝置號:
chrdevbase.c
#include
#include
#include
#include
#define chrdevbase_major 200
// 主裝置號
#define chrdevbase_name "chrdevbase"
// 名字
static
intchrdevbase_open
(struct inode *inode,
struct file *filp)
static
intchrdevbase_release
(struct inode *inode,
struct file *filp)
static ssize_t chrdevbase_read
(struct file *filp, __user char
*buf,
size_t count, loff_t *ppos)
static ssize_t chrdevbase_write
(struct file *filp, __user char
*buf,
size_t count, loff_t *ppos)
// 字元裝置 操作集合
static
struct file_operations chrdevbase_fops =
;static
int __init chrdevbase_init
(void
)return0;
}static
void __exit chrdevbase_exit
(void
)/**
* 模組入口與出口
**/module_init
(chrdevbase_init)
;// 入口
module_exit
(chrdevbase_exit)
;// 出口
module_license
("gpl");
module_author
("liefyuan"
);
makefile
kerneldir := /home/liefyuan/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
current_path :=
$(shell pwd
)obj-m := chrdevbase.o
build : kernel_modules
kernel_modules:
$(make)
-c $(kerneldir)
m=$(current_path)
modules
clean:
$(make)
-c $(kerneldir)
m=$(current_path)
clean
.vscode 資料夾–vscode頭檔案目錄配置資料夾
setting.json
,
"files.exclude"
:}
c_cpp_properties.json
/**",
"/home/liefyuan/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/include",
"/home/liefyuan/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/include",
"/home/liefyuan/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/include/generated/"
], "defines":[
], "compilerpath"
:"/usr/bin/clang",
"cstandard"
:"c11",
"cppstandard"
:"c++17",
"intellisensemode"
:"clang-x64"}],
"version"
: 4}
以上的是乙個驅動工程,它最終會被編譯成乙個.ko檔案,放到乙個固定的資料夾裡面。使用的時候需要編寫乙個應用程式–這就是傳說中的linux應用開發。
初識嵌入式 嵌入式開發概述
1 什麼是嵌入式技術 1 嵌入式軟體與非嵌入式軟體的區別?答 嵌入式軟體是結合作業系統之上做的開發 非嵌入式軟體是做的裸機開發。裸機 沒有作業系統 2 嵌入式開發與微控制器開發的區別?答 區別 是否有作業系統。拓展 答 優點 解決了軟體的移植性 解決了開發人員的能力的劃分問題。提供了豐富的網路協議 ...
嵌入式linux字元裝置驅動
arm linux 驅動 抵岸科技 1.我們需要先呼叫register chrdev region 或 alloc chrdev region 來向系統申請裝置號 int register chrdev region dev t first,unsigned int count,char name ...
嵌入式linux字元裝置驅動
1.我們需要先呼叫register chrdev region 或 alloc chrdev region 來向系統申請裝置號 int register chrdev region dev t first,unsigned int count,char name 函式通過已知的裝置號first來註冊...