令和2年度 10月 エンベデッドシステムスペシャリスト試験 午前Ⅱ 問1
テクノロジ/ソフトウェアメモリマップド I/O の I/O ポートにアクセスするプログラムを C 言語で記述するときの注意点として,適切なものはどれか。
出典:令和2年度 10月 エンベデッドシステムスペシャリスト試験 午前Ⅱ 問1
- アアセンブラの IN/OUT 命令を用いたアクセス用関数を呼び出して,アクセスする。
- イコンパイラによる最適化を抑止するために,volatile 型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定して,アクセスする。
- ウ他の関数からアクセスされるのを防ぐために,静的広域変数として宣言してアクセスする。
- エポインタではアクセスできないので,配列として実体を宣言してアクセスする。
正解:イ
解説
メモリマップド I/O では,I/O ポートが主記憶と同じアドレス空間に割り当てられます。コンパイラは,同じアドレスへの連続した読み書きを最適化によって省略・並べ替えしてしまうことがあり,これを行うとハードウェアの状態変化を正しく読み取れなくなります。これを防ぐには,対象アドレスを指すポインタの型を volatile 修飾子付きで宣言し,アクセスのたびに必ずメモリ上の実アドレスへ読み書きさせる必要があります。
選択肢ごとの解説
- ア誤り。IN/OUT 命令はポートマップド I/O 用の命令であり,主記憶と同じアドレス空間にマッピングされるメモリマップド I/O のアクセス方法としては適切ではありません。
- イ正しい。volatile 型修飾子を付けて宣言した変数へのポインタとしてアドレスを指定することで,コンパイラによる最適化(読み書きの省略や順序の入れ替え)を抑止し,アクセスのたびに確実にハードウェアへ読み書きできます。
- ウ誤り。静的広域変数として宣言することは,他の関数からのアクセスを防ぐスコープの制御であり,コンパイラの最適化を抑止する仕組みとは関係がありません。
- エ誤り。メモリマップド I/O のアドレスは,volatile 修飾子を付けたポインタとして扱ってアクセスするのが一般的であり,配列として実体を宣言する必要はありません。