Linux PWMサブシステムの実装

PWMサブシステム概要

PWMサブシステムはパルス幅変調信号の出力管理を担当します。ハードウェアベンダーはPWMコントローラの実装をカーネルに組み込み、開発者は統一されたAPIを介してバックライト制御やモーター制御などの機能を実装できます。

基本概念

パルス幅変調(PWM)はデジタル信号でアナログ回路を制御する技術です。デューティ比は周期内のアクティブ状態時間の比率を表し、50%の場合はハイ/ロー状態が等時間となります。

システムアーキテクチャ

PWMサブシステムは3層構造です:

  • ユーザー空間: アプリケーション層
  • コア層: PWMデバイス管理
  • ハードウェア層: 物理コントローラ

sysfsインターフェースによるデバッグ操作例:

コマンド説明
echo 0 > exportPWMチャネル有効化
echo 50000 > period周期設定(ns)
echo 25000 > duty_cycleアクティブ時間設定

主要構造体

struct pwm_controller {
    struct device *dev;
    const struct pwm_operations *ops;
    int channel_count;
    struct pwm_channel *channels;
};

PWM操作構造体

struct pwm_operations {
    int  (*setup)(struct pwm_controller *ctrl, struct pwm_channel *ch);
    int (*adjust)(struct pwm_channel *ch, int active_time, int period);
    int (*activate)(struct pwm_channel *ch);
    void (*deactivate)(struct pwm_channel *ch);
};

登録手順

カスタムPWMコントローラの実装例:

static const struct pwm_operations custom_pwm_ops = {
    .adjust = custom_pwm_adjust,
    .activate = custom_pwm_activate,
    .deactivate = custom_pwm_deactivate,
};

static struct pwm_controller custom_ctrl = {
    .ops = &custom_pwm_ops,
    .channel_count = 2,
};

API関数

主要なPWM操作API:

// PWM設定
int pwm_adjust(struct pwm_channel *ch, int active_time, int period);

// PWM有効化
int pwm_activate(struct pwm_channel *ch);

// PWM無効化
void pwm_deactivate(struct pwm_channel *ch);

デバイスツリー設定

pwm_controller: pwm@fe6f0000 {
    compatible = "vendor,custom-pwm";
    status = "enabled";
};

mypwm_device {
    compatible = "custom,pwm-device";
    pwm_channels = <&pwm_controller 0 20000000 1>;
};

ドライバ実装

プローブ関数での初期化例:

static int pwm_driver_probe(struct platform_device *pdev)
{
    struct pwm_channel *ch;
    ch = devm_of_pwm_get(&pdev->dev, np, NULL);
    pwm_adjust(ch, 1000, 5000);
    pwm_activate(ch);
}

タグ: linux PWM デバイスドライバ カーネル開発 デバイスツリー

7月5日 00:42 投稿