Linux字符设备能驱动

最后发布时间:2021-01-24 18:23:58 浏览量:

图片alt

图片alt


图片alt

图片alt

开始你的创作:Linux字符设备能驱动

  • Linux所有的设备文件放在/dev目录下
  • 通过字符设备文件找到设备驱动
    图片alt

    图片alt

设备和划分

向内核申请设备号

设备号属于资源,使用要向内核申请

静态申请

  • cat /proc/devices 查看使用的设备号
  • 调用register_chrdev_region向内核申请设备号
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#define CDD_MAJOR 265
#define CDD_MINOR 0
#define CDD_COUNT 1

// 设备号
dev_t dev;

int cdd_init(void){
	// 构造设备号
	dev = MKDEV(CDD_MAJOR,CDD_MINOR);
	// 静态设备号申请

	int ret = register_chrdev_region(dev,CDD_COUNT,"cdd_demo2");
	if(ret<0){
		printk("register_chardev_region failed!");
		return ret;
	}
	printk("register_chardev_region success!");
    return 0;
}
void cdd_exit(void){
	// 构造设备号
	dev = MKDEV(CDD_MAJOR,CDD_MINOR);
	unregister_chrdev_region(dev,CDD_COUNT);
	printk("unregister_chrdev_region");
}

module_init(cdd_init)
module_exit(cdd_exit)

动态申请

	int ret = alloc_chrdev_region(&dev,CDD_MINOR,CDD_COUNT,"cdd_alloc_demo");

设备注册

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


#define CDD_MINOR 0
#define CDD_COUNT 1

// 设备号
dev_t dev;

//声明cdev
struct cdev cdd_cdev;

/**
 *inode是文件的结构节点,用来存储静态文件。
 * 文件创建时,内核中就有inode结构 
 * 文件打开时会创建一个file结构
 */
int cdd_open(struct inode *inode, struct file *filp){
	printk("cdd_open\n");
	return 0;
}
int cdd_release(struct inode *inode, struct file *filp){
	printk("cdd_release\n");
	return 0;
}
ssize_t cdd_read(struct file *filp, char __user *buf, size_t size, loff_t *offset){
	printk("cdd_read\n");
	return 0;
}
ssize_t cdd_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset){
	printk("cdd_write\n");
}

long cdd_unlocked_ioctl (struct file *filp, unsigned int cmd, unsigned long data){
	printk("cdd_unlocked_ioctl\n");
}


struct file_operations cdd_fops={
	.owner = THIS_MODULE,
	.open = cdd_open,
	.read = cdd_read,
	.write = cdd_write,
	.unlocked_ioctl = cdd_unlocked_ioctl, //io ctrl 接口
	.release = cdd_release,
};


int cdd_init(void){

	// 设备号申请
	int ret = alloc_chrdev_region(&dev,CDD_MINOR,CDD_COUNT,"cdd_alloc_demo");
	if(ret<0){
		printk("register_chardev_region failed!\n");
		return ret;
	}
	// 初始化cdev
	cdev_init(&cdd_cdev,&cdd_fops);
	// 将cdev添加到内核并绑定设备号
	ret = cdev_add(&cdd_cdev,dev,CDD_COUNT);
	if(ret<0){
		unregister_chrdev_region(dev,CDD_COUNT);
		printk("cdev_add error!\n");
		return ret;
	}
	printk("cdev_add success!\n");
    return 0;
}

void cdd_exit(void){
	// 构造设备号
	unregister_chrdev_region(dev,CDD_COUNT);
	cdev_del(&cdd_cdev);
	printk("unregister_chrdev_region\n");
}

module_init(cdd_init)
module_exit(cdd_exit)

创建设备文件

  • 手动创建
mknod 设备文件路径 文件类型 主设备号 次设备号
  • 自动创建
#include <linux/device.h>

拓展

  • 使用ffmpeg录制视频
ffmpeg  -i /dev/video0 out1.avi