前提
- GPIO21を出力させる
- Raspberry Pi Model B+(多分)
コード
includeしてるヘッダは適当
test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint-gcc.h>
#include <fcntl.h>
#include <sys/mman.h>
void main(void){
volatile uint32_t *gpio_base = NULL;
int fd = open("/dev/mem", O_RDWR | O_SYNC );
void *gpio_mmap = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x20200000);
//0x20200000
gpio_base = (volatile uint32_t *)gpio_mmap;
//GPFSEL2の4bit目を1にする
gpio_base[2] = 0x8;
//GPSET0レジスタの21bit目を1にする
gpio_base[7] = 0x200000;
//GPCLR0レジスタの21bit目を1にする
// gpio_base[10] = 0x200000;
}
メモ
- GPIOのレジスタは物理メモリアドレス0x20200000から割り当てられている
- 具体的なマッピングは↓の本等参照
- 出力の操作の流れは
- GPFSEL2レジスタ(=0x20200008)でGPIO毎の機能を切り替える(シリアルにしたり、入力にしたり、出力にできる、らしい)
- GPFSELはGPIO9個毎割り当てられてる
- GPFSEL0: GPIO0 ~ GPIO9
- GPFSEL1: GPIO10 ~ GPIO19
- GPFSEL2: GPIO20 ~ GPIO29
- GPIO毎3bitずつ割り当てられてるので、GPIO21はGPFSEL2の4bit~6bit目を001にする
- GPFSELはGPIO9個毎割り当てられてる
- GPSET0レジスタ(=0x2020001c)で出力させる
- 1bitずつそれぞれのGPIOに割り当てられてる
- GPIO21は21bit目(0x200000)を1にする
- GPFSEL2レジスタ(=0x20200008)でGPIO毎の機能を切り替える(シリアルにしたり、入力にしたり、出力にできる、らしい)
- mmapで仮想アドレス空間に物理アドレスをマッピングさせる
- uint32_tでキャストした配列の添字を増やすと4バイトずつアクセス先が増えていく
#実行
root@raspberrypi:/usr/local/work# gcc test.c
root@raspberrypi:/usr/local/work# ./a.out
参考
RaspberryPiで学ぶ ARMデバイスドライバープログラミング
posted with amazlet at 17.07.04
米田 聡
ソシム
売り上げランキング: 174,251
ソシム
売り上げランキング: 174,251