LoginSignup
1
2

More than 5 years have passed since last update.

【Raspberry Pi】ユーザランドからレジスタ経由でGPIOを制御する小さなメモ

Posted at

前提

  • 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にする
    • GPSET0レジスタ(=0x2020001c)で出力させる
      • 1bitずつそれぞれのGPIOに割り当てられてる
      • GPIO21は21bit目(0x200000)を1にする
  • mmapで仮想アドレス空間に物理アドレスをマッピングさせる
  • uint32_tでキャストした配列の添字を増やすと4バイトずつアクセス先が増えていく

実行

root@raspberrypi:/usr/local/work# gcc test.c
root@raspberrypi:/usr/local/work# ./a.out

ファイル 2017-07-05 0 15 26.jpeg

ファイル 2017-07-05 0 15 43.jpeg

参考

RaspberryPiで学ぶ ARMデバイスドライバープログラミング
米田 聡
ソシム
売り上げランキング: 174,251
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2