Linux字符设备驱动(入门)

字符驱动模块程序

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
 
static struct cdev chr_dev;
static dev_t ndev;
 
static int chr_open(struct inode* nd, struct file* filp)
{
	int major ;
	int minor;
	
	major = MAJOR(nd->i_rdev);
	minor = MINOR(nd->i_rdev);
	
	printk("chr_open, major = %d, minor = %d\n", major, minor);
	return 0;
}
 
static ssize_t chr_read(struct file* filp, char __user* u, size_t sz, loff_t* off)
{
	printk("chr_read process!\n");
	memcpy(u, "hello world", sz);
	return 0;
}
 
struct file_operations chr_ops = {
	.owner = THIS_MODULE,
	.open = chr_open,
	.read = chr_read
};
 
static int demo_init(void)
{
	int ret;
	
	cdev_init(&chr_dev, &chr_ops);
	ret = alloc_chrdev_region(&ndev, 0, 1, "chr_dev");
	if(ret < 0 )
	{
		return ret;
	}
	
	printk("demo_init(): major = %d, minor = %d\n", MAJOR(ndev), MINOR(ndev));
	ret = cdev_add(&chr_dev, ndev, 1);
	if(ret < 0)
	{
		return ret;
	}
	
	return 0;
}
 
static void demo_exit(void)
{
	printk("demo_exit process!\n");
	cdev_del(&chr_dev);
	unregister_chrdev_region(ndev, 1);
}
 
module_init(demo_init);
module_exit(demo_exit);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxxx");
MODULE_DESCRIPTION("A simple device example!");

创建编译字符驱动模块Makefile

ifneq ($(KERNELRELEASE),)
obj-m := demo.o
 
else
PWD  := $(shell pwd)
KVER := $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
	rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions modules.*  Module.*
endif 
# 备注:Makefile 
# 编译驱动模块时,需要当前编译系统的内核环境,其中:
# 1. uname -r : 获取当前内核版本信息
# 2. /lib/modules/$(shell uname -r)/build : 调用内核编译的环境目录
# 3. M : 输出目录
# 4. obj-m := demo.o : 与输出的驱动名称为 demo 有关

编译字符驱动模块程序

# 编译字符设备的 Makefile 写好后,可以直接执行 make 即可
# 成功后,产生一些如 *.cmd,*.mod.c,*.ko,module*等文件
make

加载驱动模块

# 使用 insmod 命令进行加载
# 使用 rmmod  命令进行卸载
# 使用 mknod  设置模块的主备设备号和设备名称
insmod demo

设置驱动模块的主从设备号

# 使用 dmesg 查询加载设备后的主从设备号,当前为 250 和 0
# 执行完之后,在 /dev 目录下产生 demo 设备名,
# 直接可以进行 open, read, close 灯操作。
mknod  /dev/demo 250 0

测试程序

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>


#define CHAR_DEV_NAME    "/dev/demo"

int main(int argc, char const *argv[])
{
	int fd = 0;
	char buf[32] = {'\0'};

	fd = open(CHAR_DEV_NAME, O_RDONLY|O_NDELAY);
	if(0 > fd)
	{
		printf("open failed\n");
		return -1;
	}

	read(fd, buf, 32);
	printf("buf = (%s)\n", buf);

	close(fd);


	return 0;
}



更多内容

Linux 驱动开发

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值