linuxPWM子系統源碼分析--Apple的學習筆記 一,前言 二,PWM源碼框架 三,PWM源碼分析 四,遇到的問題

一,前言

所謂學習,那麼就和單純完成任務是不同的,我的學習也是有目標的,那麼從linux驅動開發的角度來說,若只是配置下就能用了,這樣有點知其然而不知其所以然,所以我的目標就是先會用,然後學習框架及源碼,便於將來遇到問題後調試定位和代碼優化。另外,最主要的就是學習linux中面向對象的抽象設計思路。所以做完了SG90的PWM後,那麼就要分析PWM源碼了。並且發現了看源碼有助於我在寫驅動的時候對函數的理解及應用。

二,PWM源碼框架

PWM框架算是比較簡單的。我畫了個圖備忘下。


三,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,
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章