使用核心定時器的秒字元裝置

2021-09-06 01:30:11 字數 4577 閱讀 2177

秒字元裝置

秒字元裝置也是字元驅動,所以與之前的字元裝置驅動程式的框架類似,模組編譯,模組載入與解除安裝也與核心模組的編譯,載入解除安裝一致。秒字元裝置驅(second)的實現,建立目錄(second),在該目錄下建立裝置檔案(second.c),內容按下面的**寫即可,在同一目錄下編寫相應的makefile檔案,然後make就可以編譯模組了,然後插入模組(可以帶引數,如:sudo insmod second.ko second_major=249),裝置驅動程式就好了,但是現在在/dev中並沒有」second」這個字元裝置驅動,必須建立裝置節點才行,建立裝置節點的命令是:mknod /dev/chardev0 c 250 0其中chardev0是裝置名,c說明裝置是字元裝置,250是主裝置號,0是次裝置號,這些都要根據自己的裝置驅動程式來賦予相應的值(此處為:mknod /dev/second c 249 0)。裝置節點建立成功後在/dev中就可以看到自己建立的裝置了或者使用ls-l second(裝置名)來檢視詳細資訊。

秒字元裝置驅動實現後要進行測試,建立測試檔案(test.c)內容按下面的**寫即可。然後編譯執行測試檔案,就可以看到效果了。

秒字元裝置(second.c)原始碼:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define second_major 249//巨集定義主裝置號

static int second_major =second_major; //模組引數,可以輸入主裝置號

struct second_dev//second裝置結構體

struct cdev cdev;//cdev結構體

atomic_t counter;//一共經歷的秒數

struct timer_lists_timer;//裝置要使用的定時器

struct second_dev*second_devp; //裝置結構體指標

//定時器處理函式

static voidsecond_timer_handle(unsigned long arg)

mod_timer(&second_devp->s_timer,jiffies+hz);

atomic_inc(&second_devp->counter);//counter加1

printk(kern_notice "currentjiffies is %d \n",jiffies);

//檔案開啟

int second_open(struct inode*inode,struct file *filp)

//初始化定時器

init_timer(&second_devp->s_timer);

second_devp->s_timer.function=&second_timer_handle;

second_devp->s_timer.expires=jiffies+hz;

add_timer(&second_devp->s_timer);//註冊定時器

atomic_set(&second_devp->counter,0);//設定counter初值為0

return 0;

/檔案釋放

int second_release(structinode *inode,struct file *filp)

del_timer(&second_devp->s_timer);//釋放定時器

return 0;

//讀函式

static ssize_tsecond_read(struct file *filp,char __user *buf,size_t count,loff_t*ppos)

int counter;

counter=atomic_read(&second_devp->counter);//獲得counter 的當前值

if(put_user(counter,(int*)buf)) //由於核心空間和使用者空間不能直接互訪,所以用put_user函式將counter的值從核心複製到使用者buf所指的空間。

return -efault;

else

return sizeof(unsigned int);

//檔案操作結構體

static const structfile_operations second_fops =

.owner=this_module,

.open=second_open,

.release=second_release,

.read=second_read

//初始化並註冊cdev

static voidsecond_setup_cdev(struct second_dev *dev,int index)

interr,devno=mkdev(second_major,index); //獲得主裝置號

cdev_init(&dev->cdev,&second_fops);

dev->cdev.owner=this_module;

dev->cdev.ops=&second_fops;

err=cdev_add(&dev->cdev,devno,1);//註冊裝置號

if(err)

printk(kern_notice "error %dadding led %d",err,index);

//模組載入函式

intsecond_init(void)

int ret;

dev_tdevno=mkdev(second_major,0);

if(second_major)

ret=register_chrdev_region(devno,1,"second");//申請裝置號

else

ret=alloc_chrdev_region(&devno,0,1,"second");//動態申請裝置號

second_major=major(devno);//獲得申請到的裝置號

if(ret<0)

return ret;

//動態申請裝置結構體的記憶體

second_devp=kmalloc(sizeof(structsecond_dev),gfp_kernel);

if(!second_devp)//申請失敗

ret = -enomem;

goto fail_malloc;

//設定second_devp所指的大小為sizeof(strcutsecond_dev)的記憶體均為0

memset(second_devp,0,sizeof(struct second_dev));

second_setup_cdev(second_devp,0);//初始化並註冊cdev

return 0;

fail_malloc:unregister_chrdev_region(devno,1);

//模組解除安裝函式

voidsecond_exit(void)

cdev_del(&second_devp->cdev);//登出cdev

kfree(second_devp);//釋放裝置結構體內存

unregister_chrdev_region(mkdev(second_major,0),1);//釋放裝置號

module_author("wangfangyong");

module_license("gpl");

module_param(second_major,int,s_irugo);

module_init(second_init);

module_exit(second_exit);

makefile檔案原始碼:

obj-m := second.o

path =/usr/src/linux-headers-$(shell uname -r)

all:

make -c $(path) m=$(pwd)modules

clean:

make -c $(path) m=$(pwd)clean

測試檔案(test.c)原始碼:

#include

#include

#include

#include

#include

#include

#include

int main()

int fd;

int counter=0;

int old_counter=0;

fd=open("/dev/second",o_rdonly); //開啟裝置檔案

if(fd!=-1)

while(1)

read(fd,&counter,sizeof(unsigned int ));//讀目前經歷的秒數

if(counter!=old_counter)

printf("seconds after open/dev/second:%d\n",counter);

old_counter=counter;

else

printf("device openfail\n");

使用核心定時器的second字元裝置驅動

second.c include include include file operations include dev t include include kcalloc include copy to user,copy from user include 中斷 include define s...

核心 核心定時器的使用

概要 核心定時器是核心用來控制在未來某個時間點 基於jiffies 排程執行某個函式的一種機制,其實現位於 和 kernel timer.c 檔案中。被排程的函式肯定是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 current 指標 不允...

Linux裝置驅動 核心定時器

核心定時器使用 核心定時器是核心用來控制在未來某個時間點 基於jiffies 排程執行某個函式的一種機制,其實現位於 和 kernel timer.c 檔案中。被排程的函式肯定是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 current ...