Linux驱动开发之动态分配字符设备、注册

一、驱动源代码

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

static int hello_major = 248; // 主设备号
static int hello_minor = 0; // 次设备号
static int number_of_devices = 1; // 设备的数量

struct cdev *cdev;  //动态分配字符设备
dev_t dev = 0;

// struct inode:物理上的设备信息,只有一个。
static int hello_open (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device opened\n");
return 0;
}


static int hello_release (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device closed\n");
return 0;
}


struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
};

static __init char_driver_init(void)
{
int result;
  
dev = MKDEV (hello_major, hello_minor); // 主设备号、次设备号合并为设备号
result = register_chrdev_region (dev, number_of_devices, "hello"); // 静态注册设备号: name 体现在"/proc/devices"中
if (result<0) {
printk (KERN_ERR "char_driver_init: can't get major number %d\n", hello_major);
return result;
    }

cdev = cdev_alloc(); // 动态分配字符设备
cdev_init(cdev, &hello_fops); // 初始化字符设备
cdev->owner = THIS_MODULE;
//cdev->ops = &hello_fops;
result = cdev_add(cdev, dev, 1); // 注册字符设备
if (result)
printk (KERN_INFO "Error %d adding char_device", result);

printk (KERN_INFO "Char device registered ...\n");
return 0;

}

static __exit char_driver_exit(void)
{
dev_t devno = MKDEV (hello_major, hello_minor);// 主设备号、次设备号合并为设备号
if(cdev)
cdev_del(cdev); // 注销字符设备
unregister_chrdev_region (devno, number_of_devices);// 注销设备号

printk(KERN_INFO "char device cleaned up ...\n");
}

module_init(char_driver_init);
module_exit(char_driver_exit);

MODULE_LICENSE("GPL");
MODULE_VERSION("v1.0");
MODULE_AUTHOR("xz@vichip.com.cn");
MODULE_DESCRIPTION("Char Driver Module");
MODULE_ALIAS("char driver module");

二、Makefile

ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:                               
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:                                             
        $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
else
    obj-m := char_reg.o

endif

三、测试驱动程序

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

#define DEV_NAME "/dev/hello"

int main (void) 
{
int fd;

fd = open(DEV_NAME, O_RDWR);
if (fd < 0) {
perror("open");
return 1;
}
printf("/dev/hello opened ...\n");
close(fd);
printf("/dev/hello closed ...\n");

return 0;
}

四、验证驱动

1、创建设备节点

sudo mknod /dev/hello c 248 0

chmod 0666 /dev/hello

2、执行应用程序

gcc test.c -o test

./test

3、dmesg查看内核消息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值