Raspberry pi で AP のレジスタをC言語で直接変更して GPIO を操作する
やること
Raspberry Pi 用の特別なライブラリとドライバを利用せずにGPIOをC言語で操作する。
その他の普通の手段
wiringPi を利用する
Device Tree Overlay でドライバを利用する
gpio コマンドを利用する
- 本質的には wiringPi と同じ
注意点
Linux のシステムコールを含む(mmap関数)ので、root 権限が必要なため sudo コマンドを利用する必要があります。 プログラム名を sample.c とするならば、
$ gcc sample.c $ sudo ./a.out
のように実行してください。
main()
IC 20pin (RaspberryPi の端子だと 38pin) を操作して、High/Low をずっと繰り返す。
アドレスをいちいち addr/4 していますが、仕様書に記載されている byte アドレスを 32bit(4byte)アドレスに変換しているためです。 C言語の int は今回 32bitなので、アドレスを保持しているポインタに 1 を加算すると 32bit 分ポインタがずれます。
void main() { int count; volatile unsigned *addr; gpio = io_mapping(GPIO_BASE); // set GPIO20 to output mode ( bit[2:0] ). offset is 0x8( byte address ) . *( gpio + 0x8/4 ) = (*( gpio + 0x8/4 ) & ~(0x7)) | (0x1 << 0); for( count = 0 ; ; count++){ usleep(1000); addr = ( count % 2 ) ? gpio + 0x1C/4 : gpio + 0x28/4 ; *addr = 0x1 << 20; } }
物理アドレスのアクセス用マッピング
過去記事を参照してください。
使っているレジスタ
ADDRESS | Name | Description | Size | Read/Write |
---|---|---|---|---|
0x3F20_0008 | GPFSEL2 | GPIO Function Select 2 | 32 | R/W |
0x3F20_001C | GPSET0 | GPIO Pin Output Set 0 | 32 | W |
0x3F20_0028 | GPCLR0 | GPIO Pin Output Clear 0 | 32 | W |
GPFSELn
SoC の端子は色々な機能を切り替えられるようになっていて、 RaspberryPi も同じようになっている。 今回は output モードに切り替えていて、GPFSEL2 の bit[2:0] に 1 を書き込んでいます。
GPSETn
Write Only のレジスタで、1 の書き込みで対応するGPIOが High になる。
GPCLRn
Write Only のレジスタで、1 の書き込みで対応するGPIOが Low になる。
その他
レジスタの値をそのまま反映する GPLEVn もあるが、他のGPIOの値を含めてレジスタReadして対応するbitだけ変更する必要がり(Read modified write)、少し手数が増えて複雑となります。