Linux-PWM-framework(1)-简介和API描述

上传人:自*** 文档编号:28028477 上传时间:2018-01-14 格式:DOCX 页数:9 大小:56.87KB
返回 下载 相关 举报
Linux-PWM-framework(1)-简介和API描述_第1页
第1页 / 共9页
Linux-PWM-framework(1)-简介和API描述_第2页
第2页 / 共9页
Linux-PWM-framework(1)-简介和API描述_第3页
第3页 / 共9页
Linux-PWM-framework(1)-简介和API描述_第4页
第4页 / 共9页
Linux-PWM-framework(1)-简介和API描述_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《Linux-PWM-framework(1)-简介和API描述》由会员分享,可在线阅读,更多相关《Linux-PWM-framework(1)-简介和API描述(9页珍藏版)》请在金锄头文库上搜索。

1、Linux PWM framework(1)_简介和 API 描述作者:wowo 发布于: 2015-10-11 15:45 分类:通信类协议http:/ 前言PWM 是 Pulse Width Modulation(脉冲宽度调制)的缩写,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其本质是一种对模拟信号电平进行数字编码的方法。在嵌入式设备中,PWM 多用于控制马达、LED、振动器等模拟器件。PWM framework 是 kernel 为了方便 PWM driver 开发、PWM 使用而抽象出来的一套通用API,之所以要分析该 framework,原因如下:1)PWM

2、接口,本质上一种通信协议,和 I2C、SPI、USB、WIFI 等没有任何差别。因此,本文将会是 kernel 通信协议有关 framework 的分析文章的第一篇。2)它太简单了!但是,虽然简单,思路却大同小异,因而非常适合做第一篇。3)我计划整理显示子系统的分析文章,而 PWM,是显示子系统中最基础的那一个。闲话少说,言归正传!2. 软件框架及 API 汇整PWM framework 非常简单,但它同样具备 framework 的基本特性:对上,为内核其它driver( Consumer)提供使用 PWM 功能的统一接口;对下,为 PWM driver(Provider )提供driver

3、 开发的通用方法和 API;内部,抽象并实现公共逻辑,屏蔽技术细节。下面我们通过它所提供的 API,进一步认识 PWM framework。2.1 向 PWM consumer 提供的 APIs对 consumer 而言,关注 PWM 的如下参数:1)频率PWM 的频率决定了所模拟出来的模拟电平的平滑度,通俗的讲,就是逼真度。不同的模拟器件,对期待的频率是有要求的,因此需要具体情况具体对待。另外,人耳能感知的频率范围是 20Hz16KHz,因此要注意 PWM 的频率不要落在这个范围,否则可能会产生莫名其妙的噪声。2)占空比占空比,决定了一个周期内 PWM 信号高低的比率,进而决定了一个周期内的

4、平均电压,也即所模拟的模拟电平的电平值。3)极性简单的说,一个 PWM 信号的极性,决定了是高占空比的信号输出电平高,还是低占空比信号输出电平高。假设一个信号的占空比为 100%,如果为正常极性,则输出电平最大,如果为翻转的极性,则输出电平为 0。4)开关控制 PWM 信号是否输出。基于上述需求,linux pwm framework 向 consumer 提供了如下 API: 1: /* include/linux/pwm.h */2: 3: /*4: * pwm_config - change a PWM device configuration5: */6: int pwm_config

5、(struct pwm_device *pwm, int duty_ns, int period_ns);7: 8: /*9: * pwm_enable - start a PWM output toggling10: */11: int pwm_enable(struct pwm_device *pwm);12: 13: /*14: * pwm_disable - stop a PWM output toggling15: */16: void pwm_disable(struct pwm_device *pwm);17: 18: /*19: * pwm_set_polarity - con

6、figure the polarity of a PWM signal20: */21: int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);pwm_config,用于控制 PWM 输出信号的频率和占空比,其中频率是以周期(period_ns)的形式配置的,占空比是以有效时间(duty_ns)的形式配置的。pwm_enable/pwm_disable,用于控制 PWM 信号输出与否。pwm_set_polarity,可以更改 pwm 信号的极性,可选参数包括normal(PWM_POLARITY_NO

7、RMAL)和 inversed(极性翻转,PWM_POLARITY_INVERSED)两种。上面的 API 都以 struct pwm_device 类型的指针为操作句柄,该指针抽象了一个 PWM 设备(consumer 不需要关心其内部构成),那么怎么获得 PWM 句柄呢?使用如下的 API:注 1:本文只介绍基于 DTS 的、新的 pwm request 系列接口,对于那些旧接口,让它随风而去吧。1: /* include/linux/pwm.h */2: 3: struct pwm_device *pwm_get(struct device *dev, const char *con_i

8、d);4: struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id);5: void pwm_put(struct pwm_device *pwm);6: 7: struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id);8: struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np,9: const char *con_id

9、);10: void devm_pwm_put(struct device *dev, struct pwm_device *pwm);pwm_get/devm_pwm_get,从指定设备(dev )的 DTS 节点中,获得对应的 PWM 句柄。可以通过 con_id 指定一个名称,或者会获取和该设备绑定的第一个 PWM 句柄。设备的 DTS 文件需要用这样的格式指定所使用的 PWM device(具体的形式,还依赖 pwm driver 的具体实现,后面会再介绍): bl: backlight pwms = ; pwm-names = backlight; ; 如果“con_id”为 NUL

10、L,则返回 DTS 中“pwms”字段所指定的第一个 PWM device;如果“con_id”不为空,如是“backlight”,则返回和“pwm-names ”字段所指定的 name 对应的 PWM device。 上面“pwms”字段各个域的含义如下: 1)&pwm,对 DTS 中 pwm 节点的引用; 2)0,pwm device 的设备号,具体需要参考 SOC 以及 pwm driver 的实际情况; 3)5000000,PWM 信号默认的周期,单位是纳秒(ns); 4)PWM_POLARITY_INVERTED ,可选字段,是否提供由 pwm driver 决定,表示 pwm 信号

11、的极性,若为 0,则正常极性,若为 PWM_POLARITY_INVERTED,则反转极性。of_pwm_get/devm_of_pwm_get,和 pwm_get/devm_pwm_get 类似,区别是可以指定需要从中解析 PWM 信息的 device node,而不是直接指定 device 指针。 2.2 向 PWM provider 提供的 APIs接着从 PWM provider 的角度,看一下 PWM framework 为 provider 编写 PWM 驱动提供了哪些 API。2.2.1 pwm chipPWM framework 使用 struct pwm_chip 抽象 PW

12、M 控制器。通常情况下,在一个 SOC 中,可以同时支持多路 PWM 输出(如 6 路),以便同时控制多个 PWM 设备。这样每一路 PWM 输出,可以看做一个 PWM 设备(由上面 struct pwm_device 抽象),没有意外的话,这些 PWM设备的控制方式应该类似。PWM framework 会统一管理这些 PWM 设备,将它们归类为一个PWM chip。struct pwm_chip 的定义如下:1: /* include/linux/pwm.h */2: 3: /*4: * struct pwm_chip - abstract a PWM controller5: * dev:

13、 device providing the PWMs6: * list: list node for internal use7: * ops: callbacks for this PWM controller8: * base: number of first PWM controlled by this chip9: * npwm: number of PWMs controlled by this chip10: * pwms: array of PWM devices allocated by the framework11: * can_sleep: must be true if

14、 the .config(), .enable() or .disable()12: * operations may sleep13: */ 14: struct pwm_chip 15: struct device *dev;16: struct list_head list;17: const struct pwm_ops *ops;18: int base;19: unsigned int npwm;20: 21: struct pwm_device *pwms;22: 23: struct pwm_device * (*of_xlate)(struct pwm_chip *pc,24

15、: const struct of_phandle_args *args);25: unsigned int of_pwm_n_cells;26: bool can_sleep;27: ;dev,该 pwm chip 对应的设备,一般由 pwm driver 对应的 platform 驱动指定。必须提供!ops,操作 PWM 设备的回调函数,后面会详细介绍。必须提供!npwm,该 pwm chip 可以支持的 pwm channel(也可以称作 pwm device 由 struct pwm_device 表示)个数,kernel 会根据该 number,分配相应个数的 struct pwm_device 结构,保存在 pwms 指针中。必须提供!pwms,保存所有 pwm device 的数组,kernel 会自行分配,不需要 driver 关心。base,在将该 chip 下所有 pwm device 组成 radix tree 时使用,只有旧的 pwm_request 接口会使用,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号