今天做了linux課設關於裝置驅動的實驗。
實驗採用模組的方法編寫乙個可以進行簡單讀寫的字元裝置驅動,該裝置可以儲存一定長的字串,寫入裝置即可以將字串存入裝置,讀出即可以獲取該字串,並編寫了測試程式對其測試。
(1)首先新建並編寫了字元驅動裝置chardev.c檔案,檔案**如下:
/**
建立乙個字元裝置(讀寫)
*//*
必要的標頭檔案,核心模組標準標頭檔案
*/#include
#include/*
核心工作
*/#include/**/
#include
#include/*
明確指定是模組
*/#include
/*對於字元裝置
*/#include/*
字元裝置定義
*/#include
#include
#include
module_author("author");
module_license("gpl");
struct char_dev *char_device;
int dev_major=0;
int dev_minor=0;
module_param(dev_major,int,s_irugo);
module_param(dev_minor,int,s_irugo);
//裝置儲存區的指標
char *p_mem=null;
//裝置儲存區的大小
long len=1000;
//表示裝置的資料結構
struct char_dev
;int char_open(struct inode *inode,struct file *filp)
//讀時將呼叫的函式
static ssize_t char_read(struct file * filp, char __user *buf, size_t count, loff_t *offset)
printk("you are using the read function!");
return count ;}//
引數定義和
char_read
類似static ssize_t char_write(struct file * filp, const char __user *buf, size_t count, loff_t *offset)
return count;}//
讀寫完畢後呼叫的函式
int char_release(struct inode *inode,struct file *filp)
//定義裝置節點檔案的操作
static struct file_operations char_ops=;
//裝置初始化時呼叫的函式,用於獲取儲存區記憶體空間
int memory_init(void)
return 1;}//
裝置初始化
static int dev_init(void)
else
if(result < 0)
//返回主裝置號
printk("the dev_major %d/n",dev_major);
//獲取全域性
char_dev
結構體char_device = kmalloc(sizeof(struct char_dev),gfp_kernel);
if(!char_device)
memset(char_device,0,sizeof(struct char_dev));
//使用定義了的檔案操作
char_ops
初始化cdev
cdev_init(&char_device->cdev, &char_ops);
char_device->cdev.owner = this_module;
char_device->cdev.ops = &char_ops;
//使用後區的裝置號註冊裝置
devno=mkdev(dev_major,dev_minor);
//新增此字元裝置到系統
err=cdev_add(&char_device->cdev,devno,1);
char_device->data=p_mem;
char_device->len=len;
return 0;}//
裝置被移出時呼叫
static void dev_exit(void)
//註冊模組初始化和解除安裝函式
module_init(dev_init);
module_exit(dev_exit);
(2)然後編寫相應的makefile檔案:
# makefile
# if kernelrelease is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(kernelrelease),)
obj-m := chardev.o
# otherwise we were called directly from the command
# line; invoke the kernel build system.
else
kerneldir ?= /lib/modules/`uname -r`/build
default:
make -c $(kerneldir) m=`pwd` modules
endif
(3)使用make 命令,生成驅動程式chardev.ko
(4)用root
掛載裝置
:
insmod chardev.ko
(5)在檔案系統為其建立乙個代表節點(建立裝置檔案)。
建立節點命令格式如下:
mknod /dev/
例如(若主裝置號為249):
mknod mychardev0 c 249 0
(6)修改屬性:
chmod 666 mychardev*
(7)裝置掛載後,就能夠使用系統命令寫入資料和讀取資料啦~
如讀操作:more mychardev0 (
友情提示:mychardev0會很大,若想體驗計算機編碼的奇妙可嘗試cat命令)
(8)編寫測試程式test.cpp:
#include
#include
#include
#include
using namespace std;
int main()
//向指定裝置寫入使用者輸入文字
cout<<"please input the text:/n";
cin>>buffer_write;
write(fd, buffer_write, 20); //
輸出裝置中的內容
read(fd, buffer_read, 20);
cout<<"
指定裝置中的內容為:
/n"<
close(fd);
return 0; }
**功能:實現了裝置的讀資料與寫資料操作,有以下幾點值得注意:
①fd=open("/home/guest/dev/mychardev0", o_rdwr);
不能只看對應資料夾下是否有
mychardev0
裝置,若開啟不成功可能需要重新
mknod
一下。②
iostream
不能直接寫
#include
,而要寫:
#include
using namespace std;
③關於read
和write
函式的第三個引數n:
其作用要追溯到
copy_to_user
和copy_from_user
兩個函式上,其值就表示要寫入或讀出的字串大小
(以位元組為單位)。
Linux核心裝置驅動註冊
platform device與platform driver 引入devicetree後改變 platform device會由kernel自動展開,呼叫of platform bus probe null,of bus ids,null 即可自動展開所有的platform device 引入de...
Linux裝置驅動 核心開發
linux裝置驅動需要使用核心api來實現,一般被包含在linux核心原始碼樹中。驅動可以編譯到核心,隨著核心一起在系統啟動的時候被載入。也可以編譯成核心模組,在系統執行起來之後動態地載入到核心中,使得除錯的時候無需重新編譯核心,也無需重啟系統,很大程度上方便了驅動 的除錯。但並不是只有裝置驅動才能...
Linux核心混雜裝置驅動
1.1混雜裝置驅動特點 本質上還是一類字元裝置,在驅動軟體上,混雜裝置的主裝置號已經由核心指定主裝置號為10 各個混雜裝置個體通過次裝置號來區分 1.2linux核心描述混雜裝置的資料結構 struct miscdevice 作用 描述混雜裝置 成員 minor 混雜裝置對應的次裝置號,切記主裝置號...