Hi,
I tested GPIOs on a board with a Soc 66AK2E05 on it. When using sysfs to change GPIO registers, I have no problem (see code below).
Since I have performance in mind, I wanted to use memory mapped GPIO but it seems not to work and it returns me always EINVAL after calling mmap from user space.
Here is my current code:
/* * main.c */ #include <stdio.h> #include "csl_gpio.h" #include "csl_gpioAux.h" #include "cslr_device.h" #include "tisocgpio.h" #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h> #include <errno.h> #include <unistd.h> #define GPIO_FIRST (16) #define GPIO_LAST (GPIO_FIRST + 15) //CSL_GPIO_CFG_REGS = 0x0260BF00 #define GPIO_START_ADDR 0x0260BF00 #define GPIO_END_ADDR 0x0260BFFF #define GPIO_MAP_SIZE (GPIO_END_ADDR - GPIO_START_ADDR) #define GPIO_SETDATAOUT 0x18 #define GPIO_CLEARDATAOUT 0x1C #define USE_MEMORY_MAP //#define USE_SYSFS int main(void) { //unsigned int gpio = GPIO_FIRST; unsigned int gpio = ACK; #ifdef USE_SYSFS printf("Sysfs version\n"); gpio_export(gpio); gpio_set_dir(gpio, OUTPUT_PIN); int nLoop=0; while(nLoop<10) { gpio_set_value(gpio, HIGH); usleep(1000000); gpio_set_value(gpio, LOW); usleep(1000000); nLoop++; } gpio_unexport(gpio); #endif #ifdef USE_MEMORY_MAP printf("Memory mapping version\n"); static void *mmap_base = NULL; volatile unsigned int *gpio_setdataout_addr; volatile unsigned int *gpio_cleardataout_addr; int fd_mem = open("/dev/mem", O_RDWR | O_SYNC); if (fd_mem < 1) { printf("Cannot open /dev/mem\n"); return -1; } int page_size = getpagesize(); printf("page size = %d\n",page_size); mmap_base = mmap( NULL, // Start addr,let kernel choose GPIO_MAP_SIZE, // The IO space PROT_READ | PROT_WRITE, // Allow read and write (rw) MAP_SHARED, // Share with all processes fd_mem, // Device is /dev/mem GPIO_START_ADDR); // IO memory region base if(mmap_base == MAP_FAILED) { printf("Memory Mapping Error: %s\n",strerror(errno)); return -1; } gpio_setdataout_addr = mmap_base + GPIO_SETDATAOUT; gpio_cleardataout_addr = mmap_base + GPIO_CLEARDATAOUT; int nLoop=0; while(nLoop<10) { *gpio_setdataout_addr = (1<<gpio); usleep(1000000); *gpio_cleardataout_addr = (1<<gpio); usleep(1000000); nLoop++; } munmap(mmap_base, GPIO_MAP_SIZE); close(fd_mem); #endif printf("App exiting\n"); return 0; }
Is memory mapping somehow protected? Is there an alternative to boost performance for this purpose: already available kernel drivers?