Linuxデバイスドライバーの開発:ピン制御サブシステム
編集者注:組み込みLinuxカーネルは、組み込みシステムですでに重要な役割を果たしており、モノのインターネット(IoT)のさまざまな要件に対応する上で重要性を増しています。次に、デバイスドライバーは、アプリケーションとIoTデバイス自体の間の重要なリンクを提供します。 Linuxデバイスドライバーの開発では、著者のJohn Madieuが、詳細な説明と豊富なコードサンプルを組み合わせて、これらのドライバーの開発について包括的に説明しています。
この本の第14章の抜粋では、ピン制御とGPIOに焦点を当てています。これは、カスタムハードウェアデバイスとの対話を検討している組み込みシステム開発者にとって特に重要な領域です。この抜粋のこの最初の記事では、ピン制御サブシステムを紹介します。
JohnMadieuによるLinuxDevice DriversDevelopmentから採用。
第14章ピン制御とGPIOサブシステム
JohnMadieu著
ほとんどの組み込みLinuxドライバーおよびカーネルエンジニアは、GPIOを使用して書き込むか、ピンの多重化で遊んでいます。ピンとは、コンポーネントの出力ラインを意味します。 SoCはピンを多重化します。つまり、ピンには複数の機能があります。たとえば、arch / arm / boot / dts / imx6dl-pinfunc.hのMX6QDL_PAD_SD3_DAT1は、SD3データライン1、UART1のcts / rts、Flexcan2のRx、または通常のGPIO。
ピンが機能するモードを選択するメカニズムは、ピン多重化と呼ばれます。担当するシステムはピンコントローラと呼ばれます。この章の後半では、汎用入出力について説明します。 ( GPIO )、これはピンが動作できる特殊機能(モード)です。
この章では、次のことを行います。
-
ピン制御サブシステムをウォークスルーし、DTでノードを宣言する方法を確認します
-
従来の整数ベースのGPIOインターフェースと新しい記述子ベースのインターフェースAPIの両方を調べてください
-
IRQにマップされたGPIOを処理する
-
GPIO専用のsysfsインターフェースを処理する
ピン制御サブシステム
ピンコントロール ( pinctrl )サブシステムにより、ピンの多重化を管理できます。 DTでは、特定の方法でピンを多重化する必要があるデバイスは、必要なピン制御構成を宣言する必要があります。
pinctrlサブシステムは以下を提供します:
-
ピンの多重化。これにより、1つのピンがUART TXピン、GPIOライン、またはHSIデータライン。多重化は、ピンのグループまたは個々のピンに影響を与える可能性があります。
-
ピン構成、プルダウン、プルダウン、ドライバー強度、デバウンス期間などのピンの電子プロパティの適用。
この本の目的は、ピンコントローラードライバーによってエクスポートされた関数の使用に限定されており、ピンコントローラードライバーの作成方法については説明していません。
Pinctrlとデバイスツリー
pinctrlは、(GPIOだけでなく)ピンを収集してドライバーに渡す方法に他なりません。ピンコントローラドライバは、DTのピン記述を解析し、それらの構成をチップに適用する役割を果たします。ドライバは通常、ピンのグループ構成を記述するために2つのネストされたノードのセットを必要とします。最初のノードはグループの機能(グループが使用される目的)を記述し、2番目のノードはピン構成を保持します。
DTでピングループがどのように割り当てられるかは、プラットフォーム、つまりピンコントローラードライバーに大きく依存します。すべてのピン制御状態には、0から始まり連続する整数IDが与えられます。 IDの上にマップされるnameプロパティを使用して、同じ名前が常に同じIDを指すようにすることができます。
各クライアントデバイスの独自のバインディングによって、DTノードで定義する必要のある状態のセット、および提供する必要のある状態IDのセットを定義するかどうか、または提供する必要のある状態名のセットを定義するかどうかが決まります。いずれの場合も、ピン構成ノードは、次の2つのプロパティを使用してデバイスに割り当てることができます。
-
pinctrl-
:これにより、デバイスの特定の状態に必要なpinctrl構成のリストを提供できます。これはphandleのリストであり、それぞれがピン構成ノードを指しています。これらの参照されるピン構成ノードは、構成するピンコントローラーの子ノードである必要があります。このリストには複数のエントリが存在する場合があります。これにより、複数のピンコントローラを構成したり、単一のピンコントローラの複数のノードから状態を構築したりできます。各ノードは全体的な構成の一部になります。 -
pinctrl-name:これにより、リスト内の各状態に名前を付けることができます。リストエントリ0は、整数状態ID 0の名前を定義し、リストエントリ1は状態ID1の名前を定義します。状態ID0には、通常、 default という名前が付けられます。 。標準化された状態のリストは、include / linux / pinctrl /pinctrl-state.hにあります。
以下はDTの抜粋であり、いくつかのデバイスノードとそのピン制御ノードを示しています。
前の例では、ピン構成は
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x80000000
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09はピン機能(この場合はGPIO)を表し、0x80000000はピン設定を表します。この行については、
MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D25__UART3_RX_DATAは、UART3のRXラインであるピン機能を表し、0x1b0b1は設定を表します。
pin関数は、その値がピンコントローラードライバーに対してのみ意味を持つマクロです。これらは通常、arch // boot / dts /にあるヘッダーファイルで定義されます。たとえば、i.MX6クアッドコア(ARM)を備えたUDOOクアッドを使用する場合、ピン関数ヘッダーはarch / arm / boot / dts /imx6q-pinfunc.hになります。以下は、GPIO5コントローラーの5行目に対応するマクロです。
#define MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x19c 0x4b0 0x000 0x5 0x0
これらの先行ノードは、対応するドライバー固有のノードから呼び出されます。さらに、これらのピンは、対応するドライバーの初期化中に構成されます。ピングループの状態を選択する前に、まずpinctrl_get()関数を使用してピン制御を取得し、要求された状態が存在するかどうかを確認するためにpinctrl_lookup_state()を呼び出し、最後に状態を適用するためにpinctrl_select_state()を呼び出す必要があります。
以下は、ピンコントロールを取得してデフォルト構成を適用する方法を示すサンプルです。
通常、ドライバーの初期化中にこのような手順を実行します。このコードの適切な場所は、probe()関数内である可能性があります。
pinctrl_select_state()は内部でpinmux_enable_setting()を呼び出し、次にpinmux_enable_setting()はピン制御ノードの各ピンでpin_request()を呼び出します。
ピンコントロールは、pinctrl_put()関数を使用して解放できます。 APIのリソース管理バージョンを使用できます。そうは言っても、pinmuxを構成するために、選択する状態の名前を指定してpinctrl_get_select()を使用できます。この関数は、include / linux / pinctrl /consumer.hで次のように定義されています。
static struct pinctrl * pinctrl_get_select(struct device * dev、
const char * name)
ここで、* nameは、pinctrl-nameプロパティに記述されている状態名です。状態の名前がdefaultの場合、pinctr_get_select_default()関数を呼び出すことができます。これはpinctl_get_select()のラッパーです:
static struct pinctrl * pinctrl_get_select_default(
struct device * dev)
{
return pinctrl_get_select(dev、PINCTRL_STATE_DEFAULT);
}
ボード固有のdtsファイル(am335x-evm.dts)で実際の例を見てみましょう:
dcan1:d_can @ 481d0000 {
status =“ OK”;
pinctrl-names =“ default”;
pinctrl-0 =<&d_can1_pins>;
};
そして、対応するドライバーで:
pinctrl =devm_pinctrl_get_select_default(&pdev-> dev);
if(IS_ERR(pinctrl))
dev_warn(&pdev-> dev、”ピンはドライバーから構成されていません”);
ピンコントロールコアは、デバイスがプローブされるときに、デフォルトのpinctrl状態を自動的に要求します。 init状態を定義すると、pinctrlコアはprobe()関数の前に自動的にpinctrlをこの状態に設定し、probe()の後にデフォルト状態に切り替えます(ドライバーが明示的に状態を変更している場合を除く)。
次回の記事では、GPIOサブシステムについて説明します。
PacktPublishingの許可を得て転載。 Copyright©2017Packt Publishing
John Madieuは、フランスのパリに住む組み込みLinuxおよびカーネルエンジニアです。彼の主な活動は、自動化、輸送、ヘルスケア、エネルギー、軍事などの分野の企業向けのドライバーとボードサポートパッケージ(BSP)の開発です。 Johnは、コンピューターオンモジュールに基づく電子ボード設計と組み込みLinuxソリューションのパイオニアであるフランスの企業であるEXPEMBで働いています。彼はオープンソースで組み込みシステムの愛好家であり、知識を共有することによってのみ、より多くのことを学ぶことができると確信しています。
モノのインターネットテクノロジー