Sterowanie GPIO Beaglebone przez / dev / mem

Próbuję napisać program w C, żeby mrugał diodą LED na Beaglebone. Wiem, że mogę korzystać ze sposobu sysfs ... ale chciałbym zobaczyć, czy możliwe jest uzyskanie tego samego wyniku mapowania fizycznej przestrzeni adresowej za pomocą / dev / mem.

Mam plik nagłówkowy beaglebone_gpio.h z następującą zawartością:

#ifndef _BEAGLEBONE_GPIO_H_
#define _BEAGLEBONE_GPIO_H_

#define GPIO1_START_ADDR 0x4804C000
#define GPIO1_END_ADDR 0x4804DFFF
#define GPIO1_SIZE (GPIO1_END_ADDR - GPIO1_START_ADDR)
#define GPIO_OE 0x134
#define GPIO_SETDATAOUT 0x194
#define GPIO_CLEARDATAOUT 0x190

#define USR0_LED (1<<21)
#define USR1_LED (1<<22)
#define USR2_LED (1<<23)
#define USR3_LED (1<<24)

#endif

a potem mam swój program C, gpiotest.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include "beaglebone_gpio.h"

int main(int argc, char *argv[]) {
    volatile void *gpio_addr = NULL;
    volatile unsigned int *gpio_oe_addr = NULL;
    volatile unsigned int *gpio_setdataout_addr = NULL;
    volatile unsigned int *gpio_cleardataout_addr = NULL;
    unsigned int reg;
    int fd = open("/dev/mem", O_RDWR);

    printf("Mapping %X - %X (size: %X)\n", GPIO1_START_ADDR, GPIO1_END_ADDR, GPIO1_SIZE);

    gpio_addr = mmap(0, GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_START_ADDR);

    gpio_oe_addr = gpio_addr + GPIO_OE;
    gpio_setdataout_addr = gpio_addr + GPIO_SETDATAOUT;
    gpio_cleardataout_addr = gpio_addr + GPIO_CLEARDATAOUT;

    if(gpio_addr == MAP_FAILED) {
        printf("Unable to map GPIO\n");
        exit(1);
    }
    printf("GPIO mapped to %p\n", gpio_addr);
    printf("GPIO OE mapped to %p\n", gpio_oe_addr);
    printf("GPIO SETDATAOUTADDR mapped to %p\n", gpio_setdataout_addr);
    printf("GPIO CLEARDATAOUT mapped to %p\n", gpio_cleardataout_addr);

    reg = *gpio_oe_addr;
    printf("GPIO1 configuration: %X\n", reg);
    reg = reg & (0xFFFFFFFF - USR1_LED);
    *gpio_oe_addr = reg;
    printf("GPIO1 configuration: %X\n", reg);

    printf("Start blinking LED USR1\n");
    while(1) {
        printf("ON\n");
        *gpio_setdataout_addr= USR1_LED;
        sleep(1);
        printf("OFF\n");
        *gpio_cleardataout_addr = USR1_LED;
        sleep(1);
    }

    close(fd);
    return 0;
}

Dane wyjściowe to:

Mapping 4804C000 - 4804DFFF (size: 1FFF)
GPIO mapped to 0x40225000
GPIO OE mapped to 40225134
GPIO SEDATAOUTADDR mapped to 0x40225194
GPIO CLEARDATAOUTADDR mapped to 0x40225190
GPIO1 configuration: FE1FFFFF
GPIO1 configuratino: FE1FFFFF
Start blinking LED USR1
ON
OFF
ON
OFF
...

ale nie widzę migającej diody.

Jak widać z wyjścia programu, konfiguracja jest poprawna, FE1FFFFF, jest spójny, ponieważ GPIO1_21, GPIO1_22, GPIO1_23 i GPIO1_24 są skonfigurowane jako wyjścia, z których każde steruje diodą LED.

Masz jakiś pomysł na temat przyczyny?

questionAnswers(7)

yourAnswerToTheQuestion