Linux-PWM驱动实验

在裸机篇我们已经学习过了如何使用 I.MX6ULL 的 PWM 外设来实现 LCD 的背光调节,其实在 Linux 的 LCD 驱动实验我们也提到过 I.MX6ULL 的 PWM 背光调节,但是并没有专门的去讲解 PWM 部分,本章我们就来学习一下 Linux 下的 PWM 驱动开发。

PWM 驱动简析

关于 PWM 原理以及 I.MX6ULL 的 PWM 外设已经在裸机篇进行了详细的讲解,这里就不再赘述了,我们重点来看一下 NXP 原厂提供的 Linux 内核自带的 PWM 驱动。

设备树下的 PWM 控制器节点

I.MX6ULL 有 8 路 PWM 输出,因此对应 8 个 PWM 控制器,所有在设备树下就有 8 个PWM 控制器节点。这 8 路 PWM 都属于 I.MX6ULL 的 AIPS-1 域,但是在设备树 imx6ull.dtsi 中分为了两部分,PWM1~PWM4 在一起,PWM5~PWM8 在一起,这 8 路 PWM 并没有全部放到一起,这一点一定要注意,不要以为 imx6ull.dtsi 没有写完整。这 8 路 PWM 的设备树节点内容都是一样的,除了 reg 属性不同(毕竟不同的控制器,其地址范围不同)。本章实验我们使用GPIO1_IO04 这个引脚来完成 PWM 实验,而 GPIO1_IO04 就是 PWM3 的输出引脚,所以这里我们就以 PWM3 为例进行讲解,imx6ull.dtsi 文件中的 pwm3 节点信息如下:

第 2 行,compatible 属性值有两个“fsl,imx6ul-pwm”和“fsl,imx27-pwm”,所以在整个 Linux源码里面搜索这两个字符窜即可找到 I.MX6ULL 的 PWM 驱动文件,这个文件就是drivers/pwm/pwm-imx.c。

关 于 I.MX6ULL 的 PWM 节 点 更 为 详 细 的 信 息 请 参 考 对 应 的 绑 定 文 档 :Documentation/devicetree/bindings/pwm/ imx-pwm.txt,这里就不去分析了。

PWM 子系统

Linux 内核提供了个 PWM 子系统框架,编写 PWM 驱动的时候一定要符合这个框架。PWM子系统的核心是 pwm_chip 结构体,定义在文件 include/linux/pwm.h 中,定义如下:

第 4 行,pwm_ops 结构体就是 PWM 外设的各种操作函数集合,编写 PWM 外设驱动的时候需要开发人员实现。pwm_ops 结构体也定义在 pwm.h 头文件中,定义如下:

pwm_ops 中的这些函数不一定全部实现,但是像 config、enable 和 disable 这些肯定是需要实现的,否则的话打开/关闭 PWM,设置 PWM 的占空比这些就没操作了。

PWM 子系统驱动的核心就是初始化 pwm_chip 结构体各成员变量,然后向内核注册初始化完成以后的 pwm_chip。这里就要用到 pwmchip_add 函数,此函数定义在 drivers/pwm/core.c 文件中,函数原型如下:

int pwmchip_add(struct pwm_chip *chip)

函数参数和返回值含义如下:

chip:要向内核注册的 pwm_chip。

返回值:0 成功;负数 失败。

卸载 PWM 驱动的时候需要将前面注册的 pwm_chip 从内核移除掉,这里要用到pwmchip_remove 函数,函数原型如下:

int pwmchip_remove(struct pwm_chip *chip)

函数参数和返回值含义如下:

chip:要移除的 pwm_chip。

返回值:0 成功;负数 失败。

PWM 驱动源码分析

我们简单分析一下 Linux 内核自带的 I.MX6ULL PWM 驱动,驱动文件前面都说了,是 pwm-imx.c 这个文件。打开这个文件,可以看到,这是一个标准的平台设备驱动文件,如下所示:

第 3 行,当设备树 PWM 节点的 compatible 属性值为“fsl,imx27-pwm”的话就会匹配此驱动,注意后面的.data 为 imx_pwm_data_v2,这是一个 imx_pwm_data 类型的结构体变量,内容如下:

imx_pwm_config_v2 函数就是最终操作 I.MX6ULL 的 PWM 外设寄存器,进行实际配置的函数。imx_pwm_set_enable_v2 就是具体使能 PWM 的函数。

第 14 行,当设备树节点和驱动匹配以后 imx_pwm_probe 函数就会执行。

imx_pwm_probe 函数具体参考正点原子驱动开发手册。

此处暂略。

PWM 驱动编写

修改设备树

PWM 驱动就不需要我们再编写了,NXP 已经写好了,前面我们也已经详细的分析过这个驱动源码了。我们在实际使用的时候只需要修改设备树即可,ALPHA 开发板上的 JP2 排针引出了 GPIO1_IO04 这个引脚,如图 73.2.1.1 所示:

GPIO1_IO04 可以作为 PWM3 的输出引脚,所以我们需要在设备树里面添加 GPIO1_IO04的引脚信息以及 PWM3 控制器对应的节点信息。

1、添加 GPIO1_IO04 引脚信息

打开 imx6ull-alientek-emmc.dts 文件,在 iomuxc 节点下添加 GPIO1_IO04 的引脚信息,如下所示:

2、向 pwm3 节点追加信息

前面已经讲过了,imx6ull.dtsi 文件中已经有了“pwm3”节点,但是还不能直接使用,需要在 imx6ull-alientek-emmc.dts 文件中向 pwm3 节点追加一些内容,在 imx6ull-alientek-emmc.dts 文件中加入如下所示内容:

第 3 行,pinctrl-0 属性指定 PWM3 所使用的输出引脚对应的 pinctrl 节点,这里设置为示例代码 73.2.1 中的 pinctrl_pwm3。

第 4 和 5 行,设置时钟,第 4 行设置 ipg 时钟,第 5 行设置 per 时钟。有些 pwm 节点默认时钟源是 IMX6UL_CLK_DUMMY,这里我们需要将其改为对应的时钟,比如这里设置为IMX6UL_CLK_PWM3。PWM1~PWM8 分别对应 IMX6UL_CLK_PWM1~ IMX6UL_CLK_PWM8。

3、屏蔽掉其他复用的 IO

检查一下设备树中有没有其他外设用到 GPIO1_IO04,如果有的话需要屏蔽掉!注意,不能只屏蔽掉 GPIO1_IO04 的 pinctrl 配置信息,也要搜索一下“gpio1 4”,看看有没有哪里用到,用到的话也要屏蔽掉。

设备树修改完成以后重新编译设备树,然后使用新的设备树启动系统。

使能 PWM 驱动

NXP 官方的 Linux 内核已经默认使能了 PWM 驱动,所以不需要我们修改,但是为了学习,我们还是需要知道怎么使能。打开 Linux 内核配置界面,按照如下路径找到配置项:

PWM 驱动测试

使用新的设备树启动系统,然后将开发板 JP2 排针上的 GPIO_4(GPIO1_IO04)引脚连接到示波器上,通过示波器来查看 PWM 波形图。

直接参考:

Linux-PWM应用编程-CSDN博客

更多待补充。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql学习-Mysql查询(1)

1.基本查询&#xff08;SELECT&#xff09; SELECT语句基本格式&#xff1a; SELECT {*|<字段列表>} [ FROM<表1>&#xff0c;<表2>.. [WHERE <表达式> [GROUP BY<group by definition>] [HAVING <expression>[{<operator><exp…

深入解析ETL与ELT架构:数据集成技术的演进与发展

摘要&#xff1a;随着大数据时代的到来&#xff0c;数据集成成为企业信息化建设的重要环节。本文将深入探讨ETL与ELT两种架构&#xff0c;分析它们在数据处理、性能、可扩展性等方面的差异&#xff0c;为企业数据集成提供技术指导。 一、引言 在大数据时代&#xff0c;企业需要…

探索自然语言处理奥秘(NLP)

摘要 自然语言处理&#xff08;NLP&#xff09;是人工智能领域的一个重要分支&#xff0c;它致力于使计算机能够理解、解释和生成人类语言。这项技术让机器能够阅读文本、听懂语音&#xff0c;并与人类进行基本的对话交流。 通俗理解 自然语言处理&#xff08;NLP&#xff09…

product/admin/list?page=0size=10field=jancodevalue=4562249292272

文章目录 1、ProductController2、AdminCommonService3、ProductApiService4、ProductCommonService5、ProductSqlService https://api.crossbiog.com/product/admin/list?page0&size10&fieldjancode&value45622492922721、ProductController GetMapping("ad…

Appium:安装uiautomator2失败

目录 1、通过nmp安装uiautomator2&#xff1a;失败 2、通过 Appium 的平台直接安装驱动程序 3、通过pip 来安装 uiautomator2 1、通过nmp安装uiautomator2&#xff1a;失败 我先是通过npm安装的uiautomator2&#xff0c;也显示已经安装成功了&#xff1a; npm install -g …

【Golang】Go语言编程思想(二):函数式编程

函数式编程 函数与闭包 支持函数式编程的语言当中&#xff0c;函数是一等公民&#xff0c;参数、变量、返回值都可以是函数。 以 adder 为例&#xff0c;下例实现了一个函数式编程&#xff1a; package mainimport "fmt"func adder() func(int) int {sum : 0retu…

摄影后期学什么_好学吗?

当你按下相机快门&#xff0c;捕捉到那珍贵的瞬间&#xff0c;摄影可还没画上句号哦&#xff01;摄影后期就像是一场神奇的魔法秀&#xff0c;能让你的照片从平凡瞬间变身惊艳大片。那在这场魔法之旅中&#xff0c;咱们得学习哪些厉害的法术呢&#xff1f; 先来说说光影调整这…

windows11 安装nginx 教程(并开机自启动)

windows11 安装nginx 教程&#xff08;并开机自启动&#xff09; 1、官网下载安装 官网地址&#xff1a;http://nginx.org/en/download.html 2. 找个文件位置解压压缩包 3 启动NGINX 4 相关命令 查詢端口被占用的进程 netstat -ano | findstr "80"1、查看nginx的…

如何在谷歌浏览器中启用双重身份验证

在当今数字化时代&#xff0c;保护个人信息的安全变得尤为重要。双重身份验证&#xff08;2FA&#xff09;是一种增强账户安全性的有效方法&#xff0c;通过要求用户在输入密码之外&#xff0c;还需提供第二种身份验证信息&#xff0c;从而大大降低了账户被非法访问的风险。本文…

高级 CEF 内核集成与 VC++——CEF系统架构与开发环境搭建

目录 1. 系统架构总体设计&#xff1a;CEF 内核与 VC 主程序分层架构设计 1.1 多进程架构设计 1.2 主程序与 CEF 内核的分离 1.3 UI 设计与布局 1.4 性能与资源管理 2. 分进程设计与通信机制&#xff1a;渲染进程与主进程分离&#xff0c;保证安全性与稳定性 2.1 分进程…

RTCMultiConnection 跨域问题解决

js套件地址 https://github.com/muaz-khan/RTCMultiConnection server套件地址 https://github.com/muaz-khan/RTCMultiConnection-Server 要解决的就是server代码的跨域问题 原装写法&#xff1a; 解决写法&#xff1a; // 喜欢组合语法的自己组 const io new ioServer.S…

【Flink】Flink Checkpoint 流程解析

Flink Checkpoint 流程解析 Checkpoint 流程解析 Flink Checkpoint 流程解析Checkpint 流程概括Checkpoint 触发流程解析 (Flink 1.20)任务启动后 JobManager 开始定期对任务执行 CheckpointJobManager 使用 CheckpointCoordinator 触发 CheckpointCheckpointCoordinator 初始化…

Redis探秘Sentinel(哨兵模式)

概述 Redis的高可用机制有持久化、复制、哨兵和集群。其主要的作用和解决的问题分别是&#xff1a; 持久化&#xff1a;持久化是最简单的高可用方法(有时甚至不被归为高可用的手段)&#xff0c;主要作用是数据备份&#xff0c;即将数据存储在硬盘&#xff0c;保证数据不会因进程…

3GPP R18 LTM(L1/L2 Triggered Mobility)是什么鬼?(三) RACH-less LTM cell switch

这篇看下RACH-less LTM cell switch。 相比于RACH-based LTM,RACH-less LTM在进行LTM cell switch之前就要先知道target cell的TA信息,进而才能进行RACH-less过程,这里一般可以通过UE自行测量或者通过RA过程获取,而这里的RA一般是通过PDCCH order过程触发。根据38.300中的描…

波特图方法

在电路设计中&#xff0c;波特图为最常用的稳定性余量判断方法&#xff0c;波特图的根源是如何来的&#xff0c;却鲜有人知。 本章节串联了奈奎斯特和波特图的渊源&#xff0c;给出了其对应关系和波特图相应的稳定性余量。 理论贯通&#xff0c;不在于精确绘…

【React】React常用开发工具

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、React DevTools二、Redux DevTools三、Create React App 前言 React 是一种用于构建用户界面的流行 JavaScript 库&#xff0c;由于其灵活性、性能和可重用…

C++知识整理day4内存管理——new和delete详解

文章目录 1.C/C内存分布2.C语言中动态内存管理&#xff1a;malloc/realloc/calloc3.C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4.malloc/free和new/delete到底什么区别&#xff1f;4.1 对于自定义类型4.2 对于自定义类型4.3 总结&#xff1a;它们…

flex: 1 display:flex 导致的宽度失效问题

flex: 1 & display:flex 导致的宽度失效问题 问题复现 有这样的一个业务场景&#xff0c;详情项每行三项分别占33%宽度&#xff0c;每项有label字数不固定所以宽度不固定&#xff0c;还有content 占满标签剩余宽度&#xff0c;文字过多显示省略号&#xff0c; 鼠标划入展示…

大数据技术Kafka详解 ② | Kafka基础与架构介绍

目录 1、kafka的基本介绍 2、kafka的好处 3、分布式发布与订阅系统 4、kafka的主要应用场景 4.1、指标分析 4.2、日志聚合解决方法 4.3、流式处理 5、kafka架构 6、kafka主要组件 6.1、producer(生产者) 6.2、topic(主题) 6.3、partition(分区) 6.4、consumer(消费…

极限激光雷达点云数据集

https://arxiv.org/pdf/2307.07607v5 ‎ - AirLab 他们的数据集里面有这么多极限场景 点云数据转换 他们的激光用的velodyne,录制的格式是【velodyne_msgs/VelodyneScan】 需要把【velodyne_msgs/VelodyneScan】转化成【sensor_msgs/PointCloud2】 我编译https://github.co…