Linux驱动——生成设备节点

一、为什么引入杂项设备

启动开发板, 在超级终端中输入命令“cat /proc/misc”也可以查看对应的杂项设备。

        前面介绍过主设备号只有 256 个, 设备又非常多, 所以引入了子设备号。

        其中杂项设备的主设备号是 10, 在任何 Linux 系统中它都是固定的。
        一般将 Linux 驱动分为字符设备、 块设备、 网络设备, 但是这个分类不能包含所有的设备, 所以将无法归类的设备统称为杂项设备, 杂项设备可能用到字符设备、 快设备、 网络设备中的一项或者多项设备。

        这样杂项设备的引入即解决了设备号数量少的问题, 又降低了使用难度, 还能防止碎片化, 一举多得。

二、杂项设备注册函数及结构体

        杂项设备的头文件在“include/linux/miscdevice.h” , 有两个需要掌握的函数和一个结构体, 如下图所示, 在源码目录下使用命令“vim include/linux/miscdevice.h” 。

extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice *misc);

杂项设备注册函数; 一般在 probe 中调用, 参数是 miscdevice

杂项设备卸载函数; 一般是在 hello_remove 中用于卸载驱动。
结构体 miscdevice 中参数很多, 下面几个是常用的。

int .minor; 设备号, 赋值为 MISC_DYNAMIC_MINOR, 这个宏定义可以查到为 10 const char *name;设备名称

const struct file_operations *fops; file_operations 结构体, 在下一小节专门介绍。

三、file_opreation结构体

        file_operations 结构体的成员函数属于驱动设计的主体内容, 里面的函数和 Linux 系统给应用程序提供系统接口一一对应。

        file_operations 结构体在头文件“include/linux/fs.h” 中, 如下图所示, 使用命令“vim include/linux/fs.h”打开头文件。

 如上图所示, 可以看到结构体中包含的参数非常多。

struct module *owner;一般是 THIS_MODULE。

int (*open) (struct inode *, struct file *);对应上层的 open 函数, 打开文件。

int (*release) (struct inode *, struct file *);对应上层的 close 函数, 打开文件操作之后一般需要关闭。

ssize_t (*read) (struct file *, char user *, size_t, loff_t *);读函数, 上层应用从底层读取函数。

ssize_t (*write) (struct file *, const char user *, size_t, loff_t *);写函数, 上层应用向底层传输数据。

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);这个函数功能和写函数稍微有点重合, 但是这个函数占用的内存非常小, 主要针对 IO 口的控制。

四、代码例程

 

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

/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>

#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl123"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");

static long hello_ioctl( struct file *files, unsigned int cmd, unsigned long arg){

	
	printk("cmd is %d,arg is %d\n",cmd,arg);
	return 0;
}

static int hello_release(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello release\n");
	return 0;
}

static int hello_open(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello open\n");
	return 0;
}

static struct file_operations hello_ops = {
	.owner = THIS_MODULE,
	.open = hello_open,
	.release = hello_release,
	.unlocked_ioctl = hello_ioctl,
};

static  struct miscdevice hello_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &hello_ops,
};


static int hello_probe(struct platform_device *pdv){
	
	printk(KERN_EMERG "\tinitialized\n");
	misc_register(&hello_dev);
	
	return 0;
}

static int hello_remove(struct platform_device *pdv){
	
	printk(KERN_EMERG "\tremove\n");
	misc_deregister(&hello_dev);
	return 0;
}

static void hello_shutdown(struct platform_device *pdv){
	
	;
}

static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
	
	return 0;
}

static int hello_resume(struct platform_device *pdv){
	
	return 0;
}

struct platform_driver hello_driver = {
	.probe = hello_probe,
	.remove = hello_remove,
	.shutdown = hello_shutdown,
	.suspend = hello_suspend,
	.resume = hello_resume,
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
	}
};


static int hello_init(void)
{
	int DriverState;
	
	printk(KERN_EMERG "HELLO WORLD enter!\n");
	DriverState = platform_driver_register(&hello_driver);
	
	printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
	return 0;
}


static void hello_exit(void)
{
	printk(KERN_EMERG "HELLO WORLD exit!\n");
	
	platform_driver_unregister(&hello_driver);	
}

module_init(hello_init);
module_exit(hello_exit);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琪琪猫不会嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值