ハードウェアを意識したプログラミングの基礎(前編)

荘司靖

tag: 組み込み

技術解説 2008年4月 8日

● ポート・マップトI/O

 ポート・マップトI/Oのアドレス空間は,メモリとは完全に異なるため,メモリ・アクセスと同じ方法ではアクセスできません.そのため,CPUはI/Oポート・アドレス空間にアクセスするための専用のアセンブリ命令を持っています.inやoutという命令です.

  in src, dest
  out src, dest

 Linuxはもともとx86用に作られたカーネルです.そのため,x86由来のコードが今でも多く残っています.in()/out()マクロもその一つです.Linuxでは,x86のI/Oアクセス用命令をC言語で使えるようにしたマクロです.アクセス・サイズによってinb,inw,inlという名前で定義されています.リスト4は8ビット・アクセス用のマクロinb()です.

static inline unsigned char inb(int port) {
  unsigned char value;
        __asm__ __volatile__("inb %w1, %b0" : "=a"(value) : "Nd"(port));
  return value;
}


リスト4 マクロinb(include/asm-x86/io_32.h)

● メモリ・マップトI/O

 メモリ・マップトI/Oの場合,デバイス(CPUの周辺機能)はメモリと同じ空間にあるように見えます.このためデバイスへのアクセスに,メモリへのアクセスと同じ命令を使用します.

 当たり前ですが,x86以外のアーキテクチャではinやoutの命令はありません.そのため,inbやoutbのマクロをCPUに合った形で提供する必要があります.メモリ・マップトI/Oのアーキテクチャは,x86のマクロと同じ名前のマクロをメモリ・アクセス用に提供しています.

● アクセス方法の抽象化

 Linuxでは,ポート・マップトI/O用にinX()やoutX()注7のマクロを,メモリ・マップトI/O用にreadX()やwriteX()のマクロを用意しています.しかしこれではまだ,アクセス方法に合わせてコードを書かなければなりません.

注7;Xにはb:8ビット,w:16ビット,l:32ビットが入る.

 そこでLinuxでは,アクセス方法に合わせて適切なマクロに置き換えてくれるマクロが用意されています.ioreadX()/iowriteX()マクロです.このマクロは,与えられたアドレスがI/O空間なのかメモリ空間なのかを判定してくれます(図7).このマクロもinclude/asm/io.hで定義されています.

zu07_01.gif
図7 ioread8(addr)の動作

● 直接書かれているアドレス

 x86だけで使われていたデバイス,特にISAバスにつながるデバイス用のドライバは,デバイス・ドライバのコードの中にアドレスがそのまま埋め込まれていることもありました.これでは,たとえioread()/iowrite()でアクセス方法を抽象化できてもほかのアーキテクチャでは使いものになりません.

 また,同じくメモリ・マップトI/Oを採用しているシステム注8でも,デバイスに割り当てるアドレスが異なることもあります.もし直接書く方法しかなければ,対応しているアーキテクチャの数だけアドレスを書き,#ifdefでコードを条件分岐させなければならなくなってしまいます.これではコードが読みづらくてたまりません.Linuxでは,これを解決するために「The Linux Driver Model」という考え方が導入されています.この話はLinux固有の考え方なので,本稿の最後で解説します.

注8;この場合CPUやCPUを含んだSoC,さらに同じCPUを使っていてもボード設計が異なるものも含む.

組み込みキャッチアップ

お知らせ 一覧を見る

電子書籍の最新刊! FPGAマガジン No.12『ARMコアFPGA×Linux初体験』好評発売中

FPGAマガジン No.11『性能UP! アルゴリズム×手仕上げHDL』好評発売中! PDF版もあります

PICK UP用語

EV(電気自動車)

関連記事

EnOcean

関連記事

Android

関連記事

ニュース 一覧を見る
Tech Villageブログ

渡辺のぼるのロボコン・プロモータ日記

2年ぶりのブログ更新w

2016年10月 9日

Hamana Project

Hamana-8最終打ち上げ報告(その2)

2012年6月26日