字符设备驱动(随笔)


先奉上代码

模块代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>

#define MYMAJOR 0
#define NAME	"MyModule"
int major;

static int module_open(struct inode *inode, struct file *file)
{
	printk("module_open\n");
	return 0;
}

static ssize_t module_write(struct file *file,
	const char __user *user_buf,
	size_t count, loff_t *ppos)
{
	printk("module_write\n");
	return 0;
}

static ssize_t module_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	printk("module_read\n");	
	return 0;
}

static int module_release(struct inode *inode, struct file *file)
{
	printk("module_release\n");
	return 0;
}

static const struct file_operations fops = {
	.open = module_open,
	.write = module_write,
	.read = module_read,
	.release = module_release,
	.owner = THIS_MODULE,
};

static int __init module_test(void)
{
	printk(KERN_DEBUG "install module_test");
	major = register_chrdev(MYMAJOR, NAME, &fops);
	if (major < 0) 
	{
		printk(KERN_ERR "register_chrdev failed\n");
		return -EINVAL;
	}
	printk("module_test major: %d\n",major);
}

static void __exit module_ex(void)
{
	unregister_chrdev(major, NAME);
	printk(KERN_DEBUG "uninstall module_test");
}


module_init(module_test);
module_exit(module_ex);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Zhou");

(1)register_chrdev字符注册函数的作用是什么?

首先,我们来看看它需要什么参数。第一个参数输入的主设备号,第二参数传入你的驱动名字,第三个参数传入对应的file_operations结构体。

reguster_chrdev成功调用后,驱动就被注册到内核的驱动表当中,本质上是将驱动的file_operations结构体注册到内核的驱动表中。

register_chrdev默认的次设备号是 0.
cd = __register_chrdev_region(major, 0, 256, name);这个是内部其中的一行代码。第一个传入注射比号,第二个传入次设备号。

register_chrdev_region函数,可以区分设备的主次设备号。

有了注册,应当也有注销驱动。unregister_chrdev

(2)怎么查看已经注册好的驱动?

输入命令 cat /proc/devices 可以查看。
在这里插入图片描述

(3)驱动的设备号本质的作用是什么?

从上图我们可以看到,最左边的一列就是主设备号,从低到高往下排列。主设备号这相当于这一列表的一个索引,最多能存放256个。在调用register_chrdev时,我传入了MYMAJOR,即输入 0,表示内核自动分配一个设备号,它采取的策略是从后往前寻找一个空闲的位置。

有了驱动的设备号,那么,字符设备就能很轻易地找到它对应的驱动,只要设备号对上了。

(4)有了驱动,那怎么调用它的函数?

首先,我们要明确一条的路线:
在应用程序中,操作字符设备文件(open、read、write) -->
字符设备文件的操作已经被重映射到对应的驱动,最终调用的file_operations结构体中的open、read、write。

(5)字符设备文件怎么与注册了的驱动关联上?

在 /dev 的文件夹中,mknod MyModule c 248 0新建字符类型的文件,248是主设备号,0是次设备号。这样,就跟驱动关联上。设备号与次设备号必须跟驱动的对应上。

应用程序代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define DEV_DIR "/dev/MyModule" 


int main(void)
{
	int fd;
	char buf[10];
	//打开字符设备文件
	fd = open(DEV_DIR, O_RDWR);
	if (fd < 0)
	{
		perror("open failed!\n");
	}
	
	//测试是否能打开对应驱动的write和read函数,即file_operations中的函数
	write(fd, "12345", 5);		//读写的内容可以随意,此处用不上
	read(fd, (char*)buf, 10);
	
	close(fd);
	return 0;
}

Makefile编写

obj-m = module_test.o
KER_DIR = /home/iTOP4421/iTop4412_Kernel_3.0	# 开发板Linux内核的位置
PWD = $(shell pwd)

all:
	make -C $(KER_DIR) M=$(PWD) modules
	arm-linux-gnueabi-gcc -o app app.c

.PHONY:clean
clean:
	make -C $(KER_DIR) M=$(PWD) clean

实验现象

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值