Linux PWM接口

文章目录

  • 0.脉冲宽度调制(PWM)接口
  • 1.识别PWM
  • 2.使用PWM
  • 3.将PWM与sysfs接口配合使用
  • 4.实现PWM驱动程序
  • 5.锁
  • 6.求助

0.脉冲宽度调制(PWM)接口

这提供了有关Linux PWM接口的概述

PWM通常用于控制手机中的LED,风扇或振动器。具有固定目的的PWM不需要实现Linux PWM API(尽管它们可以)。然而,PWM通常被发现作为SoC上的分立器件,没有固定的目的。电路板设计师可以将它们连接到LED或风扇。为了提供这种灵活性,通用PWM API诞生了。


1.识别PWM

传统PWM API的用户使用唯一ID来指代PWM设备。

不应该通过其唯一ID引用PWM器件,电路板设置代码应该注册静态映射,该映射将PWM使用者与提供者匹配,如以下示例中所示。

static struct pwm_lookup board_pwm_lookup [] = {
PWM_LOOKUP(“tegra-pwm”,0,“pwm-backlight”,NULL,
50000,PWM_POLARITY_NORMAL),
};

static void __init board_init(void)
{
...
pwm_add_table(board_pwm_lookup,ARRAY_SIZE(board_pwm_lookup));
...
}

2.使用PWM

传统用户可以使用pwm_request()请求PWM设备,并在使用pwm_free()后将其释放。

新用户应使用pwm_get()函数请求PWM设备,并将消费者设备(使用者)名称传递给它。 pwm_put()用于释放PWM器件。这些函数的变体,devm_pwm_get()和devm_pwm_put()也存在。

请求后,必须使用如下API进行PWM配置:

int pwm_apply_state(struct pwm_device * pwm,struct pwm_state * state);

此API控制PWM周期/ duty_cycle配置和启用/禁用状态。

pwm_config(),pwm_enable()和pwm_disable()函数只是pwm_apply_state()的封装,如果用户想要一次更改多个参数,则不应使用它。例如,如果你看到pwm_config()和pwm_ {enable,disable}()调用同一个函数,这可能意味着你应该改为使用pwm_apply_state()。

PWM API还允许用户通过pwm_get_state()查询PWM状态。

除PWM状态外,PWM API还会公开PWM参数,这是在PWM上应该使用的参考PWM配置。PWM参数通常是特定于平台的,并且允许PWM用户仅关注相对于整个周期的占空比(例如,占空比=周期的50%)。struct pwm_args包含2个字段(周期和极性),应该用于设置初始PWM配置(通常在PWM用户探测函数中完成)。使用pwm_get_args()检索PWM参数。


3.将PWM与sysfs接口配合使用

如果在内核配置中启用了CONFIG_SYSFS,则会提供一个简单的sysfs接口来使用用户空间的PWM。它在/ sys / class / pwm /中公开。每个被探测的PWM控制器/芯片将被输出为pwmchipN,其中N是PWM芯片的基础。你在目录里面会发现:

  npwm
    该芯片支持的PWM通道数(只读)。

  export
    导出用于sysfs的PWM通道(只写)。

  unexport
   从sysfs中取消导出PWM通道(只写)。

PWM通道使用从0到npwm-1的每芯片索引编号。

导出PWM通道时,将在与其关联的pwmchipN目录中创建pwmX目录,其中X是导出的通道编号。然后将提供以下属性:

  period
    PWM信号的总周期(读/写)。
    值以纳秒为单位,是活动和非活动的总和
    PWM的时间。

  duty_cycle(占空比)
    PWM信号的有效时间(读/写)。
    值以纳秒为单位,且必须小于周期。
	在NORMAL模式下,表示一个周期内高电平持续的时间
	在INVERTED模式下,表示一个周期中低电平持续的时间
  
  polarity
    改变PWM信号的极性(读/写)。
    写入此属性仅在PWM芯片支持更改时才有效
    极性。只有PWM不能改变极性
    启用。值是字符串“normal”或“inversed”。

  enable
    启用/禁用PWM信号(读/写)。

 -  0  - 禁用
 -  1  - 启用

4.实现PWM驱动程序

目前有两种方法可以实现pwm驱动程序。以前每个驱动程序必须自己实现pwm _ *()函数。这意味着系统中不可能有多个PWM驱动器。因此,新驱动程序必须使用通用PWM框架。

可以使用pwmchip_add()添加新的PWM控制器/芯片,并使用pwmchip_remove()再次删除。 pwmchip_add()将填充的struct pwm_chip(PWM芯片的描述、芯片提供的PWM器件数量以及支持的PWM操作的芯片)作为参数,特定实现到框架。

在PWM驱动器中实现极性支持时,请确保遵守PWM框架中的信号约定。根据定义,正常极性表征信号在占空比持续时间内开始为高电平,在剩余的时间内变低。相反,具有反转极性的信号在占空比的持续时间内开始为低电平,并在该周期的剩余时间内变为高电平。
Linux PWM接口_第1张图片
上图分别为INVERTED和NORMAL模式。

鼓励驱动程序实现 - > apply()而不是legacy-> enable(), - > disable()和 - > config()方法。这样做应该在PWM配置工作流程中提供原子性,这在PWM控制关键设备(如稳压器)时是必需的。

由于同样的原因,也鼓励实现 - > get_state()(用于检索初始PWM状态的方法):让PWM用户了解当前的PWM状态将允许他避免毛刺。


5.锁

PWM核心列表操作受互斥锁保护,因此可能无法从原子上下文调用pwm_request()和pwm_free()。 目前,PWM内核不对pwm_enable(),pwm_disable()和pwm_config()强制执行任何锁,因此调用上下文当前是特定于驱动程序的。 这是旧API派生的问题,应尽快修复。


6.求助

目前,PWM只能配置period_ns和duty_ns。 对于部分情况,freq_hz和duty_percent可能会更好。 请考虑在框架中添加适当的帮助程序,而不是在驱动程序中计算。

你可能感兴趣的:(Linux,PWM)