韦东山嵌入式Liunx入门驱动开发三

文章目录

      • 一、GPIO和Pinctrl子系统的使用
        • 1-1 Pinctrl子系统
        • 1-2 GPIO子系统
        • 1-3 基于GPIO子系统的LED驱动程序

本人学习完韦老师的视频,因此来复习巩固,写以笔记记之。
韦老师的课比较难,第一遍不知道在说什么,但是坚持看完一遍,再来复习,基本上就水到渠成了。
看完视频复习的同学观看最佳!
基于 IMX6ULL-PRO
参考视频 Linux快速入门到精通视频
参考资料:01_嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板.pdf

一、GPIO和Pinctrl子系统的使用

1-1 Pinctrl子系统

在这里插入图片描述
Pinctrl子系统把引脚的复用、配置抽出来,给GPIO、I2C等外设模块使用。
这会涉及2 个对象: pin controller、client device 。
pin controller可以用它来复用引脚、配置引脚。
client device声明自己要使用哪些引脚的哪些功能,怎么配置它们
在这里插入图片描述
注意,pin controller和GPIO Controller不是一回事,前者控制的引脚可用于GPIO功能、I2C功能;后者只是把引脚配置为输入、输出等功能。 即先用pin controller把引脚配置为GPIO,再用GPIO Controler把引脚配置为输入或输出。

1-2 GPIO子系统

要操作GPIO引脚,先把所用引脚配置为GPIO功能,这通过Pinctrl子系统来实现。
有了GPIO子系统后,可以在设备树里指定GPIO引脚;在驱动代码中使用GPIO子系统的标准函数获得GPIO、设置GPIO方向、读取、设置GPIO值。

在设备树中指定了GPIO引脚,在驱动代码中使用GPIO子系统的接口函数。要操作一个引脚,首先要get引脚,然后设置方向,读值、写值。
在这里插入图片描述

查看单板上的GPIO控制器,基址为128,对应GPIO5

cd /sys/class/gpio/

在这里插入图片描述
label内容来自设备树,比如它的寄存器基地址。用来跟设备树dtsi文件比较,就可以知道这对应哪一个GPIO Controller。

vi imx6ull.dtsi

在这里插入图片描述

1-3 基于GPIO子系统的LED驱动程序

使用Pinctrl管理引脚的复用、配置(上下拉电阻)
client device:compatible属性与驱动相关联,编写设备引脚状态,并定义到pin controller节点中
使用GPIO设置引脚的方向、读值、写值,也是在client device编写.dtsi文件
pinctrl设备树编写:①使用工具②文档③参考dts④搜索

GPIO和Pinctrl子系统的设备树会被转换为platform_device,通过compatible与platform_driver进行匹配
(1) 定义、注册一个 platform_driver
(2) 在 platform_driver结构体中的probe函数中
① 根据platform_device的设备树信息确定 GPIO:gpiod_get
② 定义、注册一个 file_operations结构体
③ 在 file_operarions中使用 GPIO子系统的函数操作GPIO

gpiod_direction_output(led_gpio, 0); /*配置为输出引脚 输出0*/
gpiod_set_value(led_gpio, status); /* 根据次设备号和status控制LED */

设备树编写
1、利用工具编写出pin ctrl
myled_for_gpiod_subsys: myled_for_gpiod_subsys { fsl,pins = <MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x000110A0 >; };
2、根目录中创建设备节点
myled{ compatible = “100ask,leddrv”; pinctrl-names = “default”; pinctrl-0 = <&myled_for_gpio_subsys>; led-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>; };

设备树硬件配置,需要编写Pinctrl和GPIO子系统
pin contorller 子系统
在这里插入图片描述
client device和gpio子系统
在这里插入图片描述
leddrv.c:驱动程序的统一,只需要这一个

/* 1. 确定主设备号      */
static int major = 0;
static struct class *led_class;
static struct gpio_desc *led_gpio;

/* 3. 实现对应的open/read/write等函数,填入file_operations结构                */
static ssize_t led_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 0;
}

/* write(fd, &val, 1); */
static ssize_t led_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	int err;
	char status;
	//struct inode *inode = file_inode(file);
	//int minor = iminor(inode);
	
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	err = copy_from_user(&status, buf, 1);

	/* 根据次设备号和status控制LED */
	gpiod_set_value(led_gpio, status);
	return 1;
}

static int led_drv_open (struct inode *node, struct file *file)
{
	//int minor = iminor(node);
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	/* 根据次设备号初始化LED */
	gpiod_direction_output(led_gpio, 0); /*配置为输出引脚 输出0*/
	return 0;
}

static int led_drv_close (struct inode *node, struct file *file)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 0;
}

/* 定义自己的file_operations结构        */
static struct file_operations led_drv = {
	.owner	 = THIS_MODULE,
	.open    = led_drv_open,
	.read    = led_drv_read,
	.write   = led_drv_write,
	.release = led_drv_close,
};

/* 4. 从platform_device获得GPIO
 *    把file_operations结构体告诉内核:注册驱动程序
 */
static int chip_demo_gpio_probe(struct platform_device *pdev)
{
	//int err;
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	/* 4.1 设备树中定义了一个属性 led-gpios=<...>;	*/
    led_gpio = gpiod_get(&pdev->dev, "led", 0);
	if (IS_ERR(led_gpio)) {
		dev_err(&pdev->dev, "Failed to get GPIO for led\n");
		return PTR_ERR(led_gpio);
	}
    
	/* 4.2 注册file_operations 	*/
	major = register_chrdev(0, "100ask_led", &led_drv);  /* /dev/led */
	led_class = class_create(THIS_MODULE, "100ask_led_class");
	if (IS_ERR(led_class)) {
		printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
		unregister_chrdev(major, "led");
		gpiod_put(led_gpio);
		return PTR_ERR(led_class);
	}

	device_create(led_class, NULL, MKDEV(major, 0), NULL, "100ask_led%d", 0); /* /dev/100ask_led0 */
        
    return 0;
}

static int chip_demo_gpio_remove(struct platform_device *pdev)
{
	device_destroy(led_class, MKDEV(major, 0));
	class_destroy(led_class);
	unregister_chrdev(major, "100ask_led");
	gpiod_put(led_gpio);
    
    return 0;
}

static const struct of_device_id ask100_leds[] = {
    { .compatible = "100ask,leddrv" },
    { },
};

/* 1. 定义platform_driver */
static struct platform_driver chip_demo_gpio_driver = {
    .probe      = chip_demo_gpio_probe,
    .remove     = chip_demo_gpio_remove,
    .driver     = {
        .name   = "100ask_led",
        .of_match_table = ask100_leds,
    },
};

/* 2. 在入口函数注册platform_driver */
static int __init led_init(void)
{
    int err;
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    err = platform_driver_register(&chip_demo_gpio_driver);  /*注册platform_driver结构体*/
	
	return err;
}

/* 3. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数   卸载platform_driver*/
static void __exit led_exit(void)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    platform_driver_unregister(&chip_demo_gpio_driver);
}

/* 7. 其他完善:提供设备信息,自动创建设备节点                */
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

实验结果,LED灯亮
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/419343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在函数内部定义函数?

在Python中&#xff0c;您可以在一个函数内部定义另一个函数。这种情况下&#xff0c;内部函数的作用域仅限于外部函数&#xff0c;外部函数可以访问内部函数&#xff0c;但外部函数之外的代码无法访问内部函数。那么我们是编程游戏的时候出现一些函数定义的问题&#xff0c;应…

抖音视频批量下载软件|评论数据提取工具

我们团队研发的视频批量下载工具将为您带来全新的视频下载体验&#xff01;在市面上仅能通过单个视频链接提取的无水印工具已经无法满足您的需求&#xff0c;因此我们推出了这款功能强大的工具&#xff0c;不仅支持单个视频链接提取&#xff0c;还可以通过关键词进行视频搜索&a…

Windows WMI详解

WMI简介 WMI ( Windows Management Instrumentation, Windows管理规范)是Windows 2000/XP管理系统的核心&#xff0c;属于管理数据和操作的基础模块。设计WMI的初衷是达到一种通用性&#xff0c;通过WM操作系统、应用程序等来管理本地或者远程资源。它支持分布式组件对象模型(…

基于ssm课程管理系统

基于SSM的课程管理系统的设计与实现 摘 要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。以前学校对于课程信息的管理和控制&#xff0c;采用人工登记的方式保存相关数据&#xff0c;这种以…

【论文阅读笔记】Explicit Visual Prompting for Low-Level Structure Segmentations

1.介绍 Explicit Visual Prompting for Low-Level Structure Segmentations 低级结构分割的显式视觉提示 2023年发表在IEEE CVPR Paper Code 2.摘要 检测图像中低级结构&#xff08;低层特征&#xff09;一般包括分割操纵部分、识别失焦像素、分离阴影区域和检测隐藏对象。虽…

2024开源AI人脸视频替换最新版一张图实现视频或者图片换脸,完全免费自媒体!附演示

这是github上的 roop开源项目强大AI换脸模型&#xff0c;一个大哥的封装&#xff0c;可以拿去做自媒体但是注意别触碰法律 开源项目地址&#xff1a;https://github.com/s0md3v/roop Face Swap技术&#xff1a;开启面部特征融合新纪元 你是否想过&#xff0c;通过技术手段将…

【JavaEE】_第一个SpringBoot项目

目录 1. 第一个SpringBoot项目 1.1 创建项目 1.2 加载依赖 1.3 运行启动类 1.4 创建一个简单类试运行 2. 关于SpringBoot项目的目录结构 3. 关于修改文件名 4. 关于启动日志 5. 关于访问出错 5.1 404 5.1.2 URL输入错误 5.1.2 注解错误 5.2 500 5.3 无法访问此网…

Java进阶-反射

来学习一下Java的反射&#xff0c;通过Class实例获取class信息的方法称为反射&#xff08;Reflection&#xff09;&#xff0c;内容如下 一、反射机制 1、概述 在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一…

Linux基本指令(上)

在Linux中&#xff0c;将文件夹称为目录&#xff0c;后面的内容都与目录相关。 1. ls指令 语法&#xff1a; ls [选项][目录或文件] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用选项 …

【精选】Java项目介绍和界面搭建——拼图小游戏 中

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

经销商文件分发 怎样兼顾安全和效率?

经销商文件分发是指将文件、资料、产品信息等从制造商或经销商传递给经销商的过程。这一过程对于确保经销商能够获取最新的产品信息、销售策略、市场活动资料等至关重要。 想要管理众多经销商合作伙伴之间的文件传输并提高效率&#xff0c;可以采取以下措施&#xff1a; 1、建…

容易发生内存泄漏的八个场景,你都知道吗?

内存泄漏与内存溢出 JVM在运行时会存在大量的对象&#xff0c;一部分对象是长久使用的&#xff0c;一部分对象只会短暂使用 JVM会通过可达性分析算法和一些条件判断对象是否再使用&#xff0c;当对象不再使用时&#xff0c;通过GC将这些对象进行回收&#xff0c;避免资源被用…

调试工具vue,react,redux

React Developer Tools Redux DevTools Vue devtools 使用浏览器官方组件扩展搜索安装

2369. 检查数组是否存在有效划分(动态规划)

2024-3-1 文章目录 [2369. 检查数组是否存在有效划分](https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/)思路&#xff1a;代码&#xff1a; 2369. 检查数组是否存在有效划分 思路&#xff1a; 1.状态定义:f[i]代表考虑将[0,i]是否能被有效划…

PMP考试培训费用多少钱?

PMP考试的相关费用包括报名费用、培训费用和证书续证费用三个部分。 一、PMP考试报名费用&#xff1a; 首次报考费用为3900元&#xff0c;如果未通过考试可以在英文报名有效期内进行补考报名&#xff0c;补考费用为2500元。 付费方式是在项目管理学会官方网站上提交报考资料…

ASO 对App产品性能的影响

可发现性 拥有出色的App还不足以让人们发现它&#xff0c;ASO技术通过提高搜索排名来增强App的可发现性。当用户可以在搜索结果中轻松找到应用程序时&#xff0c;那么下载和成功的潜力就会飙升。 设定期望 实施有效的应用商店优化不仅可以为潜在用户建立正确的期望&#xf…

职场的过早优化

过早优化&#xff0c;指的是还没弄清楚需求未来的变化的走向的时候&#xff0c;忽略了更重要的问题。 放在职业发展上&#xff1a;你在没有积累足够职场资源&#xff08;眼界、能力、人脉等等&#xff09;&#xff0c;也没有对职业发展形成清晰认知的时候&#xff0c;就过早地进…

Hive SQL 开发指南(二)使用(DDL、DML,DQL)

在大数据领域&#xff0c;Hive SQL 是一种常用的查询语言&#xff0c;用于在 Hadoop上进行数据分析和处理。为了确保代码的可读性、维护性和性能&#xff0c;制定一套规范化的 Hive SQL 开发规范至关重要。本文将介绍 Hive SQL 的基础知识&#xff0c;并提供一些规范化的开发指…

2023年世界前沿科技发展态势及2024年趋势展望——综述篇

源自&#xff1a;全球技术地图 “人工智能技术与咨询” 发布 一、2023年前沿科技发展与竞争态势总结 &#xff08;一&#xff09;人工智能引领前沿技术加速进步&#xff0c;产业应用一触即发&#xff0c;技术奇点苗头出现 &#xff08;二&#xff09;科技之变引发战争形态之…

express+mysql+vue,从零搭建一个商城管理系统7--文件上传,大文件分片上传

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、安装multer&#xff0c;fs-extra二、新建config/upload.js三、新建routes/upload.js四、修改routes下的index.js五、修改index.js六、新建上传文件test.html七、开启jwt验证token&#xff0c;通过login接…