当前位置:首页 > 嵌入式 > 嵌入式大杂烩
[导读]点击上方「嵌入式大杂烩」,选择「置顶公众号」第一时间查看编程笔记! 前言 之前我们已经通过几篇笔记来学习点灯了: 【Linux笔记】LED驱动程序 【Linux笔记】LED驱动实验(总线设备驱动模型) 【Linux笔记】设备树实例分析 但之前的点灯实验我们都得去跟一

点击上方「嵌入式大杂烩」,选择「置顶公众号」第一时间查看编程笔记!


前言

之前我们已经通过几篇笔记来学习点灯了:

【Linux笔记】LED驱动程序

【Linux笔记】LED驱动实验(总线设备驱动模型)

【Linux笔记】设备树实例分析

但之前的点灯实验我们都得去跟一些寄存器打交道,如:


我们要配置寄存器,肯定得去阅读参考手册查看相关的寄存器,如:


和寄存器打交道是一件费时费力而收获较小的事情,换句话说就是性价比太低了。

我们在学习STM32的时候,ST都会给我们提供各种各样的库,这些库就是对寄存器操作的一些封装,我们调用那些库函数就可以间接地操控寄存器。

我们就基本不用去查参考手册了,至少点个灯是不用去查手册的。

这些寄存器相关的代码一般都是芯片原厂的工程师给我们写好了,我们只要拿来用就可以了。

同样的,在嵌入式Linux开发中,像上面几篇笔记中的那几种led驱动方式(与寄存器打交道)基本上是用不上的,我们只是为了学习而学习。

Linux内核提供了pinctrl 和 gpio 子系统用于引脚的驱动,这样我们可以避免与寄存器打交道。

认识pinctrl、gpio子系统

这两个子系统是软件上面的概念,属于Linux内核的一部分。但最终要用起来,都是要与实际硬件挂钩,比如:


在前几个led驱动实验中我们知道我们要操控一个引脚,我们需要配置两个模块的寄存器:GPIO模块及IOMUXC模块。

IOMUXC模块是用来配置引脚功能及一些引脚参数(引脚速率、上下拉等);GPIO模块用于配置引脚的输入输出等。

其中,pinctrl子系统管理的是IOMUXC模块;gpio子系统管理的是GPIO模块。

下面简单看一下这两个子系统在设备树代码中的体现(以百问网的设备树文件100ask_imx6ull-14x14.dts为例):

1、pinctrl子系统


可以看到这里有两个节点:iomuxc节点与iomuxc_snvs节点,它们都是用来描述IOMUXC模块的。

其实这两个节点是在imx6ull.dtsi文件中被创建的,这是NXP官方提供的。在 100ask_imx6ull-14x14.dts文件中向这两个节点追加内容。

追加的内容就是实际引脚功能的配置及引脚参数信息配置,下面以一个led的控制引脚为例简单分析一下:


这个宏中前三个值是寄存器的偏移地址,后两个是寄存器的值,另一个寄存器的值就是设备树文件里pinctrl_leds节点里的那个值,即:


下面再进一步分析:


2、gpio子系统


这里需要重点关注如下两个属性:

gpio-controller; #gpio-cells = <2>;

gpio-controller;表明这个节点是一个GPIO控制器,这个控制器下面有很多引脚。

#gpio-cells = <2>; 表示这个控制器下每一个引脚要用 2 个 32 位的数(cell)来描述,其中一个数(cell)用来表示引脚,另一个数(cell)用来表示有效电平或其它特性。如:


至此,基于gpio子系统及pinctrl子系统的设备树文件的代码结构如下(图片来自百问网):


对于pinctrl信息,有些芯片提供了生成工具。

(1)gpio子系统的API接口

设备树用于描述设备相关的信息,而我们的驱动获得设备信息之后也要使用一些API接口来操控设备。

gpio子系统已经帮我们屏蔽掉了寄存器相关的操作,并给我们提供了一些API接口,我们只要调用这些API接口就可以间接地操控相关寄存器。

其有两套API接口:基于描述符的(descriptor-based)、老的(legacy)。如:


其中使用基于描述符的(descriptor-based)的接口需要包含头文件linux/gpio/consumer.h:


使用老的(legacy)接口需要包含头文件linux/gpio.h:


led驱动实验

下面简单看一些基于这两个子系统的led驱动实验(相关代码来自百问网)。

1、设备树文件

我们需要屏蔽掉百问开发板出厂自带的设备树文件100ask_imx6ull-14x14.dts中描述led设备相关的代码,并添加如下内容:

(1)在设备树文件中添加如下Pinctrl信息:

(2)在设备树文件根节点下添加如下led节点信息:

2、驱动核心代码

(1)匹配


(2)probe函数

匹配成功则执行此函数从设备树获取设备信息:


(3)open函数

此函数设置引脚方向:


(4)write函数

此函数设置引脚输出值:

3、应用代码

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

/*
 * ./ledtest /dev/100ask_led0 on
 * ./ledtest /dev/100ask_led0 off
 */

int main(int argc, char **argv)
{
 int fd;
 char status;
 
 /* 1. 判断参数 */
 if (argc != 3
 {
  printf("Usage: %s <dev> <on | off>\n", argv[0]);
  return -1;
 }

 /* 2. 打开文件 */
 fd = open(argv[1], O_RDWR);
 if (fd == -1)
 {
  printf("can not open file %s\n", argv[1]);
  return -1;
 }

 /* 3. 写文件 */
 if (0 == strcmp(argv[2], "on"))
 {
  status = 1;
  write(fd, &status, 1);
 }
 else
 {
  status = 0;
  write(fd, &status, 1);
 }
 
 close(fd);
 
 return 0;
}

4、Makefile文件

5、验证

编译设备树文件、以模块的方式编译驱动文件。并把编译生成以下几个文件上传到板子里:

100ask_imx6ull-14x14.dtb

leddrv.ko

ledtest

这里我们使用百问网开发的100ask_imx6ull_flashing_tool工具来上传,如


也可以使用开发板挂载NFS来上传这几个文件,关于NFS可查看往期笔记:【Linux笔记】挂载网络文件系统

100ask_imx6ull_flashing_tool工具默认把文件上传到根目录。我们需要手动把100ask_imx6ull-14x14.dtb文件拷贝到/boot目录下并重启。

测试结果如:


同时,led灯也对应着亮、灭。

总结

以上就是关于Pinctrl及GPIO子系统的一点学习笔记,主要是从表层来认识这两个子系统,关于这两个子系统的具体源码实验并未深究。小编也是一位初学者,先从初学者的角度认识这些概念、原理,之后深入时再分享出更深层的笔记。

最后

以上就是本次的实验分享。如有错误,欢迎指出!谢谢

本篇笔记会同步至我的个人博客:https://www.lizhengnian.cn/中,欢迎来访。

原创不易,期待您的在看分享~

猜你喜欢:

【Linux笔记】设备树实例分析

【Linux笔记】通俗易懂的Linux驱动基础

【Linux笔记】pc机_开发板_ubuntu互ping实验
【Linux笔记】挂载网络文件系统

学习STM32的一些经验分享

基于LiteOS的智慧农业案例实验分享

从单片机工程师的角度看嵌入式Linux

笔记:编写简单的内核模块


后台回复:加群。添加ZhengN微信,加入交流群



点个赞,证明你还爱我

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭