linuxPWM子系统源码分析--Apple的学习笔记

一,前言

所谓学习,那么就和单纯完成任务是不同的,我的学习也是有目标的,那么从linux驱动开发的角度来说,若只是配置下就能用了,这样有点知其然而不知其所以然,所以我的目标就是先会用,然后学习框架及源码,便于将来遇到问题后调试定位和代码优化。另外,最主要的就是学习linux中面向对象的抽象设计思路。所以做完了SG90的PWM后,那么就要分析PWM源码了。并且发现了看源码有助于我在写驱动的时候对函数的理解及应用。

二,PWM源码框架

PWM框架算是比较简单的。我画了个图备忘下。


image.png

三,PWM源码分析

每个pwm-芯片.c都会调用pwmchip_add,比如ti的am335芯片,配置了pwm及使能设备树后。
1.ehrpwm_pwm_probe->pwmchip_add(pwm-tiehrpwm.c)添加PWM驱动。
2.pc->chip.ops = &ehrpwm_pwm_ops;将注册的芯片pwm操作挂到chip ops中。
3.pwmchip_add->pwmchip_sysfs_export(core.c)添加到pwm radix树中,以供将来使用时搜索请求设备。
4.pwmchip_sysfs_export->device_create(sysfs.c)进行设备文件创建。

pwm文件夹中core.c是中间代理,自制驱动开始使用pwm是通过调用pwm_request(request a PWM device)开始的,我觉得它就类似于gpio_request、gpio_free的作用。pwm子系统和i2c不同的原因在于i2c它还有一个总线的概念,所以多出来了adapter和algorithm进行i2c和SMBus的抽象。
pwm_request->pwm_device_request(core.c)
pwm->chip->ops->request会跳入具体注册的pwm中(在pwmchip_add中已经挂载绑定了关系)。
看到如下源码,我发现SG90驱动在open文件的时候也不需要加锁,因为request调用的时候会检查此pwm资源是否空闲,否则返回-EBUSY。我只要将-EBUSY返回给APP即可。

static int pwm_device_request(struct pwm_device *pwm, const char *label)
{
    int err;

    if (test_bit(PWMF_REQUESTED, &pwm->flags))
        return -EBUSY;

    if (!try_module_get(pwm->chip->ops->owner))
        return -ENODEV;

    if (pwm->chip->ops->request) {
        err = pwm->chip->ops->request(pwm->chip, pwm);
        if (err) {
            module_put(pwm->chip->ops->owner);
            return err;
        }
    }

    set_bit(PWMF_REQUESTED, &pwm->flags);
    pwm->label = label;

    return 0;
}

四,遇到的问题

我对sysfs,debugfs,config文件系统不熟悉只是死板的使用,所以第一天我搭建pwm硬件环境的时候,没有写任何代码,直接设置pwm文件即可操作pwm,原理是什么呢?通过看源码也找到答案了。在pwm的core.c中,initail call会调用pwm_debugfs_init->debugfs_create_file
通过debugfs_create_file就可以在debugfs中建立一个文件结点,就像字符设备驱动那样,只需要对这个文件结点进行open就可以进行read、write、ioctl,等等操作。

static const struct file_operations pwm_debugfs_ops = {
    .owner = THIS_MODULE,
    .open = pwm_seq_open,
    .read = seq_read,
    .llseek = seq_lseek,
    .release = seq_release,
};

你可能感兴趣的:(linuxPWM子系统源码分析--Apple的学习笔记)