分享
 
 
 

Linux Device Driver学习笔记(1)—— 字符设备(1)

王朝system·作者佚名  2006-08-03
窄屏简体版  字體: |||超大  

Linux Device Driver学习笔记(1)

字符设备(1)

修改历史

内容

版本

初始版本

V1.0

说明:

本文档记录了创建一个字符设备的学习小结。内容包括如何创建一个字符设备,如何对该设备进行互斥读写操作,如何通过mknode在/dev/下创建一个设备文件和如何编写一个简单的Makefile。

1 创建字符设备

在Linux 2.6下使用“struct cdev”记录字符设备的信息。结构定义如下:

struct cdev {

struct module *owner;

struct file_operations *ops;

dev_t dev;

};

void cdev_init(struct cdev *, struct file_operations *);

struct cdev *cdev_alloc(void);

int cdev_add(struct cdev *, dev_t, unsigned);

void cdev_del(struct cdev *);

如果cdev是嵌套在一个设备结构中的数据成员,需要使用cdev_init来初始化cdev结构。“cdev_add”函数将字符设备加入到内核的字符设备数组中(chrdev[])。在调用“cdev_add”前需要调用“alloc_chrdev_region”函数来获得设备的主设备号和将设备的名称记录到内核的字符设备链表中,该方法将会动态的分配设备号,主设备号就是字符设备数组的下标,如果已经确定设备号可以使用“register_chrdev_region”来记录设备的名称和检查是否可以获得改设备号。在释放设备时需要使用“cdev_del”和“unregister_chrdev_region”函数来释放资源。在创建了设备后可以在“

/proc/devices”文件中获取到设备的名称和主设备号,可以使用该设备号在“/dev”下创建设备文件。

关键代码如下:

struct my_dev_t {

struct cdev cdev;

...

} my_dev;

static int __init hello_init(void)

{

...

cdev_init(&my_dev.cdev, &my_op); //初始化

my_dev.cdev.owner = THIS_MODULE;

alloc_chrdev_region(&my_dev_no, 0, 1, DEV_NAME);//获取字符设备号

ret = cdev_add(&my_dev.cdev, my_dev_no, 1); //注册设备

...

}

static void __exit hello_exit(void)

{

unregister_chrdev_region(my_dev_no, 1);//释放占用的设备号

cdev_del(&my_dev.cdev);//注销设备

...

}

2 互斥读写操作

为了实现互斥的读写操作使用了“struct semaphore”创建一个读信号量来协调操作,代码如下:

ssize_t my_read(struct file *f, char __user *buf, size_t count, loff_t *offset)

{

...

等待有数据的时候读取数据。

if (down_interruptible(&my_dev.sem_r)) {

return -ERESTARTSYS;

}

...

}

ssize_t my_write(struct file *f, char __user *buf, size_t count, loff_t *offset)

{

...

将如数据写入缓存后释放信号量,通知读进程可以读取数据,

在这个练习程序中并没有考虑到写数据时另一个进程正在读

数据的情况。

up(&my_dev.sem_r);

...

}

struct my_dev_t {

struct semaphore sem_r;

...

} my_dev;

static int __init hello_init(void)

{

...

由于初始时是没有数据的,所以信号量初始化为locked状态。

init_MUTEX_LOCKED(&my_dev.sem_r);

...

}

读写操作使用,“copy_to_user”和“copy_from_user”来完成对用户控件缓存的读写操作,注意这两个函数的返回值表示还有多少数据没有写入用户空间或没有从用户空间读取,如果成功返回的是0。

3 编写简单的Makefile

ifneq ($(KERNELRELEASE),)

obj-m = helloworld.o

else

KERNELDIR = /lib/modules/2.6.15-1.2054_FC5/build

PWD = $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:

rm -rf *.o *.ko *.mod.c

endif

4 通过脚本创建/dev/XXXX设备

#!/bin/sh

if [ "$#" -ne "3" ]; then

echo "setup <name> <major> <minor>"

exit 0

fi

mknod /dev/$1 c $2 $3

if [ "$?" -ne "0" ]; then

echo "setup successfully"

else

echo $?

echo "setup failed"

fi

使用mknod在/dev目录下创建一个设备文件,通过ll可以看到所创建设备的详细信息

crw-r--r-- 1 root root 253, 0 Jun 17 19:42 /dev/hello

“c”表示是字符设备

“253”是主设备号

“0”是次设备号

5 问题

描述

状态

备注

在linux 2.4下可以使用“devfs_register”在“/dev/”下创建设备文件,但在2.6的内核中没有发现该函数,是在2.6内核中不支持该函数了吗?

Open

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有