快速瀏覽

內存映射 GPIO


 

您可以通過為 GPIO 映射物理內存來處理 GPIO 引腳。

參考GPIO 寄存器映射文檔進行編碼。


下載下面的示例源代碼並編譯/運行它。

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <unistd.h>
 
#define	GPIO_REG_MAP            0xFF634000
#define GPIOX_FSEL_REG_OFFSET   0x116
#define GPIOX_OUTP_REG_OFFSET   0x117
#define GPIOX_INP_REG_OFFSET    0x118
#define BLOCK_SIZE              (4*1024)
 
static volatile uint32_t *gpio;
 
int main(int argc, char **argv) {
    int fd;
 
    if ((fd = open("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) {
        printf("Unable to open /dev/gpiomem\n");
        return -1;
    }
 
    gpio = mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_REG_MAP);
    if (gpio < 0) {
        printf("Mmap failed.\n");
        return -1;
    }
 
    // Print GPIOX FSEL register
    printf("GPIOX_FSEL register : 0x%08x\n",
           *(unsigned int *)(gpio + (GPIOX_FSEL_REG_OFFSET)));
 
    // Set direction of GPIOX.4 register to out
    *(gpio + (GPIOX_FSEL_REG_OFFSET)) &= ~(1 << 4);
    printf("GPIOX_FSEL register : 0x%08x\n",
           *(unsigned int *)(gpio + (GPIOX_FSEL_REG_OFFSET)));
    // Set GPIOX.4 to high
    *(gpio + (GPIOX_OUTP_REG_OFFSET)) |= (1 << 4);
    printf("GPIOX_INP register : 0x%08x\n",
           *(unsigned int *)(gpio + (GPIOX_INP_REG_OFFSET)));
 
    usleep(1000000);
 
    // Set GPIOX.4 to low
    *(gpio + (GPIOX_OUTP_REG_OFFSET)) &= ~(1 << 4);
    printf("GPIOX_INP register : 0x%08x\n",
           *(unsigned int *)(gpio + (GPIOX_INP_REG_OFFSET)));
 
    return 0;
}

請注意,在執行示例之前,我們可以處理的所有 GPIO 引腳都設置為輸入模式

該示例將使用GPIOX_FSEL寄存器將GPIOX.4設置為輸出模式

root@odroid:~# gcc -o mmap_gpio mmap_gpio.c
root@odroid:~# ./mmap_gpio
GPIOX_FSEL register : 0xffffffff
GPIOX_FSEL register : 0xffffffef
GPIOX_INP register : 0x00070091
GPIOX_INP register : 0x00070081
快速瀏覽

ODROID-C4

四核ARM CORTEX-A55 |4GB RAM |4 USB3 PORTS