Part Number: AM3358
Hello,
I am trying to control GPIO via /dev/mem on Beaglebone Black but it gets SIGBUS.
However, it works fine if 'echo 117 > /sys/class/gpio/export' command executed once.
This problem seems to be happen only GPIO module 3.
Is it supposed behaviour?
Should I need any additional procedure?
Simplen reproduction program is as follows.
#define _GNU_SOURCE
#include <inttypes.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#define AM335x_GPIO0_BASE ((uint32_t *)0x44E07000)
#define AM335x_GPIO1_BASE ((uint32_t *)0x4804C000)
#define AM335x_GPIO2_BASE ((uint32_t *)0x481AC000)
#define AM335x_GPIO3_BASE ((uint32_t *)0x481AE000)
#define GPIO_OE_OFF (0x134/(sizeof(uint32_t *)))
#define AM335x_GPIO_LEN ((size_t)0x1000)
const uint32_t *Base_Addrs[] = {AM335x_GPIO0_BASE, AM335x_GPIO1_BASE, AM335x_GPIO2_BASE, AM335x_GPIO3_BASE};
uint32_t *GPIO_Addrs[4]={};
_Bool bbb_gpio_init(void){
int dev_map;
if((dev_map = open("/dev/mem", O_RDWR)) < 0){
perror("open");
return(1);
}
for (uint8_t i=0; i<4; i++){
if((GPIO_Addrs[i] = mmap(0, AM335x_GPIO_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dev_map, (off_t)Base_Addrs[i])) == MAP_FAILED){
fprintf(stderr, "Err: %s: Can not map GPIO register %p\n",__func__, Base_Addrs[i]);
return(1);
}
}
return(0);
}
int main(void){
// GPIO configuration
if(bbb_gpio_init()){
fprintf(stderr, "Can not initialize bbb_gpio lib");
exit(EXIT_FAILURE);
}
// set gpio3_21 to output
uint32_t *ptr = GPIO_Addrs[3]+GPIO_OE_OFF;
*ptr = (*ptr & ~(1<<21));
return(0);
}