栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux驱动学习记录-18.MISC的LED驱动

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux驱动学习记录-18.MISC的LED驱动

misc的意思是混杂的,因此叫做混杂驱动。MISC驱动是最简单的字符设备驱动,通常嵌套在platform总线驱动里。

目录标题
  • 一、MISC驱动简介
    • 1.结构体
    • 2.使用
  • 二、LED驱动程序
    • 1.MISC设备结构体
    • 2.开、写等操作函数,以及函数集
    • 3.MISC驱动结构体
    • 4.probe和remov函数、匹配表以及platform结构体
    • 5.出口入口函数以及最后的定义
  • 三、测试编译

一、MISC驱动简介 1.结构体

所有MISC驱动的主设备号都是10,不同的设备使用不同的次设备号。MISC会自动创建cdev,不用像之前一样手动创建。因此只要向Linux注册一个miscdevice设备,定义在miscdevice.h。结构体如下:

struct miscdevice  {
	int minor;
	const char *name;
	const struct file_operations *fops;
	struct list_head list;
	struct device *parent;
	struct device *this_device;
	const struct attribute_group **groups;
	const char *nodename;
	umode_t mode;
};

我们关心的成员主要是前三个:

  • minor:测设备号
  • *name:设备名字
  • *fops:设备函数操作集
    预定义的次设备号在结构体上面,使用MISC的时候从上面已定义的次号选择一个,自己也可添加设备号。
2.使用

当设置好miscdevice后,需要使用misc_register向内核注册MISC设备。移除时,用misc_deregister来注销设备。

int misc_register(struct miscdevice *misc)
//成功返回0,失败返回负数
int misc_deregister(struct miscdevice *misc)
//成功返回0,失败返回负数

而不用像以前一样,调用一大堆函数来注册注销。

二、LED驱动程序

采用设备树platform总线方式下的MISC的led驱动。程序框架如下:

1.MISC设备结构体

相比于从前,MISC驱动少了主、此设备号的成员,因为主设备号默认10,次设备号在预定义里。

struct miscled_dev{
	dev_t devid;
	struct cdev cdev;
	struct calss *calss;
	struct device *device;
	struct device_node *nd;
	int led_gpio;
};
struct miscled_dev miscled;
2.开、写等操作函数,以及函数集
static int miscled_open(struct inode *inode, struct file *filp)
{
	filp->peivate_data = &miscled;
	return 0;
}

static ssize_t miscled_write(struce file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
	int retvalue;
	unsigned cahr databuf[1];
	unsigned char ledstate;
	struct miscled_dev *dev = filp->peivate_data;

	retvalue = copy_from_user(databuf, buf, cnt);
	if(retvalue < 0){
		printk("kernel write failed!rn");
		return -EFAULT;
	}
	ledstate = databuf[0];

	if(ledstate == LEDON){
		gpio_set_value(dev->led_gpio, 0);
	} else if(ledstate == LEDOFF){
		gpio_set_value(dev->led_gpio, 1);
	}
	return 0;
}

static sturt file_operations miscled_fops = {
	.owner = THINS_MODULE,
	.open = miscled_open,
	.write = miscled_write,
};
3.MISC驱动结构体
#define MISCLED_NAME "miscled"
#define MISCLED_MINOR 144

static struct miscdevice miscled_dev = {
	.minor = MISCLED_MINOR,
	.name = MISCLED_NAME,
	.fops = miscled_fops,
};
4.probe和remov函数、匹配表以及platform结构体
static int miscled_probe(struct platform_device *dev)
{
	int ret = 0;
	ret = misc_register(&miscled_dev); //注册misc设备,输入结构体地址

	miscled.nd = of_find_node_by_path("/led");

	miscled.led_gpio = of_get_named_gpio(miscled.nd, "led-gpio", 0);

	gpio_request(miscled.led_gpio, "miscled");
	gpio_direction_output(miscled.led_gpio, 1);

	return 0;
}

static int miscled_remove(struct platform_device *dev)
{
	gpio_set_value(miscled.led_gpio, 1);
	misc_deregister(&miscled_dev); //注销misc设备
	return 0;
}

static const struct of_device_id led_of_match[] = {
	{ .compatible = "gpio-led" },
	{  }
};
static struct platform_device miscled_driver = {
	.driver = {
		.name = "imx6ul-led", //驱动名字,加载成功会在/sys/bus/platform/drivers目录下存一个“imx6ul-led”的文件,用于和platform设备的name匹配。
		.of_math_table = led_of_match,
	},
	.probe = miscled_probe,
	.remove = miscled_remove,
};
5.出口入口函数以及最后的定义
static int __init miscled_init(void)
{
	return platform_driver_register(&miscled_driver);
}
static void __exit miscled_exit(void)
{
	platform_driver_unregister(&miscled_driver);
}

module_init(miscled_init);
module_exit(led_eximiscled_exitt);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Gordon");
三、测试编译

进入/sys/class/misc/可以看到对应的MISC设备文件。
驱动和设备匹配成功后会生成/dev/miscled这个设备驱动文件。
测试驱动直接用设备树led的应用程序即可。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510698.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号