IPA過去問ドリル

平成30年度 春期 エンベデッドシステムスペシャリスト試験 午前Ⅱ 問1

テクノロジ/ソフトウェア

メモリマップド I/O の I/O ポートにアクセスするプログラムを C 言語で記述するときの注意点として,適切なものはどれか。

出典:平成30年度 春期 エンベデッドシステムスペシャリスト試験 午前Ⅱ 問1

正解:イ

解説

メモリマップド I/O では,I/O ポートも主記憶と同じアドレス空間上に配置され,通常のメモリアクセス命令でアクセスされます。しかし,I/O ポートの値はハードウェアの状態変化(センサ入力の変化や割込みフラグのクリアなど)によってプログラムの制御外で変化することがあるため,コンパイラが「同じアドレスへの複数回のアクセスは同じ値を返す」と誤って最適化(読み込みの省略やキャッシュ)してしまうと,実際のハードウェアの状態を正しく読み書きできなくなります。これを防ぐために,I/O ポートに対応する変数は volatile 型修飾子を付けて宣言し,そのアドレスを指すポインタを介してアクセスすることで,アクセスのたびに必ずメモリ(レジスタ)へ読み書きするようにコンパイラの最適化を抑止します。

選択肢ごとの解説

  • 誤り。メモリマップド I/O は,I/O ポートを主記憶と同じアドレス空間にマッピングして通常のメモリアクセス命令でアクセスする方式であり,IN/OUT 命令は用いません。IN/OUT 命令を使うのはスタンダード I/O(I/O マップド I/O)方式であり,本問の前提と矛盾します。
  • 正しい。コンパイラによる最適化(読み込みの省略やレジスタへのキャッシュ)を抑止するために,volatile 型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定してアクセスすることが,メモリマップド I/O へのアクセスの注意点として適切です。
  • 誤り。静的広域変数として宣言することは,他の関数からのアクセスを防ぐスコープの制御であり,コンパイラの最適化によって実際のハードウェアへの読み書きが省略されてしまう問題を防ぐものではありません。
  • 誤り。ポインタを用いてもメモリマップド I/O のアドレスには正しくアクセスできます。配列として実体を宣言する方法は,volatile 修飾がなければ同様に最適化の問題が残り,本質的な注意点への対処になっていません。
エンベデッドシステムスペシャリストの過去問を演習モードで解く