新着情報
採用情報
日本語
|
English
|
中文
ユーザーサポート
資料ダウンロード
お問い合わせ
3つの強み
組み込みソフト開発・検証ツール
Windows開発環境向けユニットテストツール
カバレッジマスターwinAMS
カバレッジマスターwinAMS MBTオプション
Linux開発環境向けユニットテストツール
QTE(Quality Town for Embedded grade)
パフォーマンス検証ツール
PLAS-Qlite
テストデータ生成ツール
PROMPT
C/C++ 組込み用プログラム仕様書作成・解析ツール
Caseplayer2
共有変数自動解析ツール
SharedVariableChecker2
ISO 26262セーフティ&セキュリティ
Safilia(セイフィリア)
Seculia
HighTec社 TriCore/Power Architecture クロスコンパイラ
HighTec社 TriCore 開発プラットフォーム
HighTec社 Power Architecture 開発プラットフォーム
組込みシステム仮想検証環境
シミュレータベーストファミリ仮想検証ツール
実機連携 組込みソフト自動テストシステム
リアルタイムファンクションテスター
モデルガイドラインチェック製品
Model Dr. MDiA
エンジニアリングサービス
MCD -モデル中核開発事業-
MBD Back-to-Backテスト 定着運用サポート
モデルベース開発(MBD+MDD)のプロセス構築とツールの導入支援
IS&S
-サイバーセキュリティ 向け エンジニアリング支援-
ガイオ サイバーセキュリティサービス
(サイバーセキュリティ 現場業務)
ガイオ サイバーセキュリティサービス
(サイバーセキュリティワークパッケージ)
ガイオ サイバーセキュリティサービス
(サイバーセキュリティ 教育支援)
セキュリティ脅威分析支援サービス
セキュリティ検証支援サービス
-機能安全開発効率化支援-
Safilia導入支援サービス
機能安全に対応した派生開発の影響分析サービス
SAQT -先進品質技術ソリューション事業-
テストパートナーSQV
ユニットテスト・オンザトラック
QEMUを使った仮想検証環境構築サービス
SAQT HILSエンジニアリングサービス
HILS テストシナリオ作成及びシナリオ実行自動化サービス
HILS 車両モデル作成サービス
HILS CANモデル作成サービス
リアルタイムハードとSimulinkモデルの割り付けソフト設定サービス
道路、交通流CGの設定・作成サービス
大規模ソフトウェア開発者向けテストツール導入支援
QTE導入支援サービス
GAIO CLUB
導入事例
セミナーイベント
企業情報
ガイオ・テクノロジーの3つの強み
モダン型開発/従来型開発について
組込みソフト開発・検証ツール
Windows開発環境向けユニットテストツール
カバレッジマスターwinAMS
カバレッジマスターwinAMS MBTオプション
Linux開発環境向けユニットテストツール
Quality Town for Embedded grade(QTE)
パフォーマンス検証ツール
PLAS-Qlite
テストデータ生成ツール
PROMPT
C/C++ 組込み用プログラム仕様書作成・
解析ツール
CasePlayer2
共有変数自動解析ツール
SharedVariableChecker2
ISO 26262セーフティ&セキュリティ
Safilia
Seculia
HighTec社 クロスコンパイラ
HighTec社 TriCore 開発プラットフォーム
HighTec社 Power Architecture 開発プラットフォーム
組込みシステム仮想検証環境
シミュレータベーストファミリ仮想検証ツール
実機連携 組込みソフト自動テストシステム
リアルタイムファンクションテスター
モデルガイドラインチェック製品
Model Dr. MDiA
エンジニアリングサービス
モデル中核開発事業
リバースモデリング代行サービス
MBD Back-to-Backテスト 定着運用サポート
モデルベース開発(MBD+MDD)のプロセス構築と
ツールの導入支援
セキュリティサービス
サイバーセキュリティ 現場業務
サイバーセキュリティワークパッケージ
サイバーセキュリティ 教育支援
セキュリティ脅威分析支援サービス
セキュリティ検証支援サービス
機能安全開発効率化支援
Safilia導入支援サービス
機能安全に対応した派生開発の影響分析サービス
先進品質技術ソリューション事業(SAQT)
テストパートナーSQV
ユニットテスト・オンザトラック
SAQT HILSエンジニアリングサービス
HILS テストシナリオ作成及びシナリオ実行自動化サービス
HILS 車両モデル作成サービス
HILS CANモデル作成サービス
リアルタイムハードとSimulinkモデルの割り付けソフト設定サービス
道路、交通流CGの設定・作成サービス
QEMUを使った仮想検証環境構築サービス
企業情報
新着情報
採用情報
導入事例
セミナーイベント
資料ダウンロード
動画一覧
GAIOサイバーチャンネル
GAIO CLUB
お問い合わせ
プライバシーポリシー
情報セキュリティ基本方針
ユーザーサポート
GAIO CLUB
HOME
>
GAIO CLUB
>
初めての組み込みLinuxドライバ開発
2004年05月02日
初めての組み込みLinuxドライバ開発
GAIO CLUB 特集
GAIO CLUB【2004/5月号】
組み込みLinuxでハードウエアをコントロール
はじめてのLinuxドライバ
μITRONとの比較によるLinuxドライバの仕組み早わかり
目次
組み込み機器へ採用されるLinux
RTOSとLinuxの違い
Linuxのデバイスドライバとは
周辺ハードウエアをファイルとしてアクセス
アプリケーションがデバイスのデータを読み取る処理の流れ
デバイスドライバの組み込み
カーネルへの割り込みハンドラ登録
カーネルへのデバイスドライバの組み込み
LEDドライバの組み込み実行例
組み込まれたドライバを使用する
まとめ
組み込み機器へ採用されるLinux
Linuxは、マルチタスク、仮想メモリ、共有ライブラリ、メモリ管理、TCP/IP等ネットワーク機能を持ち、従来のUNIXと同じコマンド、プログラミング・インターフェースを持つUNIXライクなOSです。ほとんどのLinuxシステムはPCで使用されていますが、組み込みシステムとしても信頼性が高く、便利で安全なシステムといえます。
この約10年の間に、一般にシステムの小型化が進みました。これに伴って、組み込みシステムも小型化され、ネットワーク接続の実装などにより、システムがより複雑化し、オペレーティング・システム(OS)の機能が求められるようになりました。そこで組み込みシステム上で動作するOSとしてLinuxが登場したわけです。
組み込みシステム上で動作するOSとして、Linuxには以下のようなメリットがあります。
・ ソースが入手可能
・ ロイヤリティフリー
・ デバイスドライバが豊富
・ ネットワークプロトコルスタックやミドルウェアが豊富
・ 安定しているOS
・正式にサポートされているCPUアーキテクチャが豊富 – x86、Alpha、SPARC、68K、PowerPC、ARM、SH、MIPSなど
RTOSとLinuxの違い
組み込みシステムは、周辺ハードウエアとマイコンが密接に関連しています。ハードウエアをコントロールするためには、デバイスドライバを作成しなければなりません。μITRONなどのRTOSでは、アプリケーションが直接ハードウエアにアクセスできる構造となっているため、デバイスドライバの定義自体がなく、標準的なAPIも用意されていません。μITRONなどのRTOSは、アプリケーションからハードウエアをアクセスする自由度は高いですが、悪く言えば野放し状態であり、アプリケーションの1つのバグにより、システムを止めてしまうことも頻繁に起こります。
一方、Linuxは、ユーザーモードとカーネルモードの2つの動作モードを持ち、ユーザーモードとして動作するアプリケーションは、直接ハードウエアにアクセスすることができない構造となっています。アプリケーションは、標準的なAPIを通じてデバイスドライバを動作させ、ハードウエアに間接的にアクセスする仕組みを取っています。これにより、ハードウエアをアプリケーションから完全に隠蔽した構造となり、アプリケーションの可搬性を高くしています。
Linuxのデバイスドライバとは
Linuxのデバイスドライバは、OSの起動時にメモリ上に読み込まれて常駐し、周辺装置からのハード的な割り込みによって駆動される、OSに付属する一種のサブルーチン群です。
Linuxのカーネル自体はきわめてシンプルなマイクロカーネル・アーキテクチャによるものです。Linuxの基本的な機能であるネットワークおよびファイルシステムなどは、モジュール形式でカーネル最上部に置かれています。
これに追加されるドライバーは、実行時にロード可能なモジュールとして作成されます。カーネルと一緒にコンパイルされて1つのオブジェクトとして組み込まれる「スタティックリンク方式」と、実行時に必要に応じてメモリへ展開する「ローダブル方式」があります。(後半で取り上げます。)
周辺ハードウエアをファイルとしてアクセス
Linuxに関連するデバイスには、主に次のようなものがあります。
キャラクタ型デバイス
これは、「シーケンシャルアクセス」、「バイト単位の入出力」の様な、1バイト単位のデータの入出力を行うデバイスです。
ブロック型デバイス
これは、「ランダムアクセス」、「ブロック単位の入出力」の様な、ある決められたブロック単位でのデータの入出力を行うデバイスです。主にストレージなどで使用します。「ファイルシステムを構成できるデバイス」とも言うことができます。
Linuxでは、これらの全てのデバイスを、ファイルシステムの1ファイルとして扱います。つまり、デバイスを認識して、初期化する作業を、ファイルをopen する作業として行い、デバイスからデータを読み込む作業では、ファイルをread する作業として行うと言うことです。
上位アプリケーションは、システムコールというOSとのインターフェースを使ってファイル単位の入出力要求を行います。アプリケーションからはデバイスドライバの存在は見えず、唯一、「/dev/xxx」というデバイスを仮想化したデバイススペシャルファイルが見えるだけです。
アプリケーションがデバイスへのアクセス要求を出した場合、カーネルは、デバイススペシャルファイルで定義された番号を用いて、実際のドライバ関数を示すデバイスドライバテーブルを検索します。この番号は、「メジャー番号」と呼ばれており、デバイス毎に割り当てるものです。
また、メジャー番号の他に、「マイナー番号」があります。これは、例えばシリアルデバイスの様に、COM1、COM2など、ポートだけが異なり、同一のデバイスドライバを使用する場合に使用されます。
マイナー番号も、デバイススペシャルファイルに記述されていますが、この番号は、カーネルがデバイスドライバを呼び出す際に、引数としてそのままドライバへ渡されます。ドライバ側では、マイナー番号をポート番号として扱い、呼び出されたポート番号を判別するために使用できます。この定義は、ドライバ側で自由に決めることができます。
アプリケーションがデバイスのデータを読み取る処理の流れ
デバイスドライバは以下の3つの部分から構成されます。
初期化ルーチン
これは、OSの起動時にカーネルから1度だけコールされる部分で、ハードウェアの存在チェックを行った後、自分自身をデバイスドライバとしてOSに認識させます。
トップハーフルーチン(Top Half)
これは、上位から(間接的に)コールされる部分で、アプリケーションがopen,read のシステムコールを発行すると、カーネルから当該関数がコールされます。カーネルからの周辺装置との入出力要求を実行し、その結果をカーネルに返します。
ボトムハーフルーチン(Bottom Half)
ハードウェア割り込みによって駆動されるハンドラ部分です。
例えば、read()メソッドにより、外部のハードウエアから情報を読み取る場合、アプリケーションは標準APIをコールします。これを受けて、システムコールライブラリのread()メソッドがコールされ、データ転送の要求をi/oデバイスに対して発行します。通常は、メモリ空間にマッピングされたi/oデバイスのレジスタに、要求の書き込みを行うことで発行が行われます。
i/oデバイスは、要求されたデータをデータ読み出しのためのレジスタ、あるいはメモリ空間にセットし、準備が完了すると割り込みにより、カーネルへ通知を行います。
通知を受けたカーネルは、トップハーフルーチンを呼び出しi/oデバイスが準備したデータの読み出しを行います。実際は、処理をボトムハーフルーチンに委ね、ここがi/oデバイスのレジスタをアクセスして、データを取得します。同期転送の場合、read()メソッドの中では、処理の終了を待つ「interrupible_sleep_on()」がコールされています。この場合は、このボトムハーフルーチンの終了を受けて、カーネルが待ちの解除を行います。
デバイスドライバの組み込み
作成したデバイスドライバを使用するための手順について説明します。まず、デバイスドライバをカーネルに登録する必要があります。この登録とは、デバイススペシャルファイルに記述した「メジャー番号」と、そのデバイス操作のための関数を結びつける事を言います。
Linuxではドライバモジュールがロードされたとき(insmodコマンドが実行されたとき)、予め決められている初期化関数init_module()がコールされます。この中に、カーネルに対してドライバを登録するための関数 register_chrdev()を記述します。
この引数にあるfile_operations構造体とは、デバイスを操作するための決められたメソッド関数へのポインタを保持するものです。Linux2.4では、以下のようなメソッドが定義されています。
以下の4つは、デバイス操作のための主要なメソッドの内容です。
open
デバイスを扱うときに最初に実行される関数で、タイマー等、ドライバで使用するリソースの初期を行います。
release
デバイスがクローズされるときに呼び出されます。
read
デバイスからデータを取り出すために使用します。通常は、copy_to_userを使用してカーネル領域からユーザー領域にデータを転送します。処理が成功した場合には読み出したバイト数を戻り値として返します。
write
データをデバイスに送るために使用します。通常は、copy_from_userを使用してユーザー領域からカーネル領域にデータを転送します。処理が成功した場合、書き込んだバイト数を戻り値として返します。
カーネルへの割り込みハンドラ登録
前述のように、i/oデバイスが動作を完了して、その終了をカーネルに通知するためには、割り込みが使用されます。この割り込みを受けて、デバイスドライバのトップハーフルーチンを起動するために、割り込みハンドラの登録を行う必要があります。
登録には標準のAPIが用意されています。割り込みハンドラへのポインタ引数には、デバイスドライバのトップハーフルーチンを設定します。
カーネルへのデバイスドライバの組み込み
デバイスドライバを組み込んで使用する方法として、Linuxでは2通りの方法が提供されています。
1つは、デバイスドライバを、カーネルにスタティックリンクしてしまう方法です。これは、カーネルのコンパイル時に、ドライバ部分も合わせてコンパイルし、1つのオブジェクトとしてリンクしてしまう方法です。
カーネルブート時に、デバイスドライバの登録と初期化の処理さえ行えば、直ぐに使用可能になります。
この方法では、スタティックなメモリ領域にドライバが常駐することになり、安全性の高い組み込み方法ですが、メモリを多く消費してしまう欠点があります。μITRONや通常のRTOSのほとんどは、この方法で組み込みを行っています。
もう1つの方法として、Linuxには「ローダブルモジュール方式」がサポートされています。これは、必要に応じてメモリへロードして使用し、不要になったら、メモリから取り除くことができるものです。普段使用しないドライバモジュールは、メモリへ常駐させる必要が無いため、最小限のメモリでシステムを動作させることが可能になります。
Linuxには、ローダブルモジュールを使用するためのコマンドが用意されています。
LEDドライバの組み込み実行例
では、LEDの点灯を制御するドライバを組み込んで、アプリケーションから利用する方法をご覧頂きます。ここでは、コンソールからのコマンドにより、ローダブルモジュールとして、コンパイル後のLEDドライバモジュール「led_driver.o」を組み込みます。
まず、ドライバモジュールのファイルパスを指定して組み込みます。ドライバが初期化されると、応答メッセージ「hello!LED_DRIVER」を返すようになっています。
組み込まれたかをコマンドにより、確認してみます。これには、lsmodコマンドを使用します。
メジャー番号を調べてみましょう。catコマンドにより、組み込まれたデバイスをリスト出力してみます。メジャー番号10に組み込まれていることが分かります。
組み込まれたドライバを使用する
LEDドライバは正しく組み込まれました。では、このLEDを操作するアプリケーションを作成してみます。このLEDをアクセスするためのデバイススペシャルファイルは、mkmodコマンドを使用して作成されます。このファイルは、/dev ディレクトリにリストされますが、仮想的なファイルであり、実体は持ちません。(下図A参照)
アプリケーションでは、このデバイススペシャルファイルをオープンして、LEDを点灯するための値(0x80)を書き込みます。操作は、通常のファイル操作と同じであり、open、write、close の各標準APIを使用して行います。この操作のソースコードを下に示します。(下図B参照)
まとめ
このように、Linuxではデバイスをファイルの1つとして扱い、標準のAPIにより操作する方法を採っています。この仕組みにさえ従えば、容易にデバイスドライバを作成できることが体感頂けたかと思います。
関連ページ
QTE(Linux開発環境向けユニットテストツール)
AUTOSAR Adaptive Platformに対応可能な単体テストツールで、自動運転/統合ECUソフトの開発に求められるC++、Host-Linux、Target-Linux、オープンソース型ソフトウェア(OSS)環境に対応しています。
今すぐ資料ダウンロード!
前のコラム
コラム一覧に戻る
次のコラム
人気のコラム
OSの無い環境でC言語プログラムを動かすときは、マイコンのメモリを意識する必要があります。今回は、メモリとCソースプログラムの関係についての話です。
複数のタスクが並列動作する場合、競合に注意する必要があります。シングルタスクであっても割り込み処理との競合があります。
本特集では、モデルベース開発開発において、制御仕様として作成したMATLAB/Simulinkモデルからマイコンへ実装するコードを生成した場合に必要となる、モデル/コード間の比較検証と、その方法や課題について解説します。
最新のコラム
Google Test
今回は、g++と関連するコマンドを使用してカバレッジを確認してみます。使用するのは、前回と同じGoogle Mockを使用したC言語プログラムのテスト環境です。
Google Test
Google Mock使用例の最後に、C言語プログラムのテストで使ってみようと思います。前回までに使用したプログラムをC言語に書き換え、Google Mock使ってテストします。
Google Test
前回は、Google Mockで子関数の戻り値をあらかじめ決めた後にテストを実施してみました。Google Mockの感じをつかんだので、今回はGoogle Mockでどんなことができるのか、いくつか見て行こうと思います。
Google Test
Google Mockは、単体テストの対象関数が使用している子関数の代理関数とその関数の振る舞いを定義する環境を提供します。今回は簡単な例を見ながらGoogle Mockの使い方を見てみます。
Google Test
単体テストをする際、対象関数の動作確認のために、その関数が使用する(読む)変数に値を入れておく必要があります。関数の動作結果は前回お話ししたアサーションによって確認しますが、繰り返しテストをする際に異なる値を設定したい時はどうするのでしょうか。また、致命的なエラーが起きた時にテストを中止する方法はあるでしょうか。今回は、Google Testを使ってテストドライバーを書く時の、そんな話です。
技術情報
近年、自動車産業を取り巻く環境は大きく変化しており、100年に1度の大変革時代と言われている。欧米をはじめとして、中国及び日本でも車載ECUの統合化(ADAS Domain Controller, Cockpit Domain Controller等)が進み、2020年頃からSDV化された車両が増えてきている。本寄稿では、車載業界のSDVされたシステムの進化の流れを説明し、SDV化の進展により新たに発生する機能安全対応の課題と対策について、事例を交えて説明する。
Google Test
前回お話ししたように、Google Testはテストドライバーを作る環境を提供しています。今回は、Google Testを使ってテストドライバーをどのように書いて動かすのか、見て行こうと思います。
お問い合わせ・お見積りはこちら
03-4455-4767
[代表]9:00~17:30
(土・日・祝日・年末年始・夏季休暇を除く)