エンベデッドシステムスペシャリスト 2018年 午前2 問01
問題文
メモリマップドI/OのI/OポートにアクセスするプログラムをC言語で記述するときの注意点として、適切なものはどれか。
選択肢
ア:アセンブラのIN/OUT命令を用いたアクセス用関数を呼び出して、アクセスする。
イ:コンパイラによる最適化を抑止するために、volatile型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定して、アクセスする。(正解)
ウ:他の関数からアクセスされるのを防ぐために、静的広域変数として宣言してアクセスする。
エ:ポインタではアクセスできないので、配列として実体を宣言してアクセスする。
🔒 解説は解答すると表示されます
メモリマップドI/Oのアクセス【午前2解説】
正解の理由
メモリマップドI/Oでは、I/Oポートをメモリ上の特定のアドレスに割り当てます。そのため、C言語ではそのアドレスをポインタで指定してアクセスします。
ただし、I/Oポートの値はプログラムの外部、つまりハードウェアによって変化したり、読み書き自体に意味があったりします。通常の変数と同じように扱うと、コンパイラが不要と判断した読み書きを省略したり、まとめたりする可能性があります。
そこで、アクセス先を
volatile で修飾し、コンパイラにその値が予期せず変化する可能性があることを伝えます。この注意点を述べているイが適切です。解法ステップ
- 「メモリマップドI/O」という用語から、I/Oポートがメモリ空間に割り当てられていると判断します。
- メモリ上の特定のアドレスを扱うので、C言語ではポインタを使います。
- ハードウェアとの読み書きはプログラム外の状態に関わるため、コンパイラの最適化によって省略・変更されないよう
volatileを付けます。 - この条件に合うイを選びます。
選択肢別の誤答解説
- ア:アセンブラの
IN/OUT命令は、メモリ空間とは別のI/Oポート空間を扱う方式で使われます。メモリマップドI/Oでは、メモリ上のアドレスを使ってアクセスします。 - イ:正しい選択肢です。
volatileを付けた領域へのアクセスを、コンパイラが通常の変数と同じように省略・最適化することを抑制します。 - ウ:
staticは変数の有効範囲や記憶期間に関わる指定です。ハードウェアとのアクセスを最適化から守る指定ではありません。また、広域変数として宣言した場合でも、他の関数からアクセスされる可能性を一律に防げるわけではありません。 - エ:メモリマップドI/Oでも、ポインタを使ってアドレスを指定できます。配列として実体を宣言する必要はありません。I/Oポートのアドレスに対応する実体が、通常のプログラム内に存在するとは限りません。
よくある誤解
volatileを付ければ、どのような最適化もすべて禁止できると思いがちです。volatileは主に、その対象への読み書きをコンパイラが勝手に省略・変更しないようにする指定です。- メモリマップドI/Oを、アセンブラの
IN/OUT命令でアクセスする方式と混同しがちです。これらは別のI/Oアクセス方式です。 staticを付ければI/Oアクセスが安全になると思いがちです。staticとvolatileは目的が異なります。
補足コラム
例えば、特定のアドレスにある32ビットのI/Oレジスタを扱う場合は、概念的には次のように宣言します。
volatile unsigned int *reg =
(volatile unsigned int *)0x40000000;
この例では、
volatile はポインタが指す先の値に対するアクセスに関係します。実際のプログラムでは、レジスタの幅やアドレス、型の扱いは対象のハードウェア仕様に合わせる必要があります。なお、
volatile は複数の処理間での原子性や、すべてのメモリ操作の順序を保証するものではありません。これらが必要な場合は、ハードウェアや処理系に応じた別の仕組みも検討します。FAQ
Q.
A. コンパイラに対して、その対象へのアクセスを通常の変数のように省略しないよう伝えます。ただし、具体的な動作は処理系やハードウェアの仕様も確認してください。
volatile を付けると、読み書きのたびに必ずハードウェアへアクセスしますか?A. コンパイラに対して、その対象へのアクセスを通常の変数のように省略しないよう伝えます。ただし、具体的な動作は処理系やハードウェアの仕様も確認してください。
Q. メモリマップドI/Oでは、普通のポインタを使ってはいけませんか?
A. ポインタでアドレスを指定しますが、I/O領域へのアクセスでは、通常
A. ポインタでアドレスを指定しますが、I/O領域へのアクセスでは、通常
volatile を付けた型を使います。Q.
A. 併用できます。
static と volatile は併用できますか?A. 併用できます。
static は変数の有効範囲や記憶期間に関わり、volatile は対象へのアクセスが外部要因で変化する可能性をコンパイラに伝えます。関連キーワード: メモリマップドI/O、volatile、I/Oポート、ポインタ、コンパイラ最適化

\ せっかくなら /
エンベデッドシステムスペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

