tonygrim
Posts: 6
Joined: Sun Jun 23, 2013 9:46 pm

[SOLVED]GPIO issues

Tue Jul 02, 2013 5:53 am

I'm running 3.6.11+ #474 (soft float) and I've written a c++ app (in Qt4.8.2) that listens for signals on one or more GPIO pins. My app was working just fine until I upgraded to the current release, but now it can't map the GPIO locations.

The code (somewhat abridged, but you get the idea):

Code: Select all

#define GPIO_BASE 0x22000000
#define BLOCK_SIZE (4 * 1024)
bool PiGPIO::setupio()
{
    if((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) return false; // this succeeds when run as root

    gpio_map = (char *) mmap(
                             NULL,
                             BLOCK_SIZE,
                             PROT_READ | PROT_WRITE,
                             mem_fd,
                             GPIO_BASE); // always fails with errno 11 (EAGAIN -- Resource temporarily unavailable)
 // etc
}
I've looked at all getrlimit() and ulimit have to offer, but can find no reason there why the mmap call is failing.

Any help would be gratefully received.

Tony
Last edited by tonygrim on Tue Jul 02, 2013 10:59 pm, edited 1 time in total.

PiGraham
Posts: 3939
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: GPIO issues

Tue Jul 02, 2013 6:07 am

Does another process on your system access the GPIO memory?

I note you don't have MAP_SHARED. specified as it is here:
http://elinux.org/RPi_Low-level_periphe ... e_examples

EAGAIN The file to be mapped is already locked
using advisory or mandatory record locking.
See fcntl(2).
Is there another instance of your code running? (ps -all)

tonygrim
Posts: 6
Joined: Sun Jun 23, 2013 9:46 pm

Re: GPIO issues

Tue Jul 02, 2013 9:04 pm

PiGraham wrote:Does another process on your system access the GPIO memory?

I note you don't have MAP_SHARED. specified as it is here:
http://elinux.org/RPi_Low-level_periphe ... e_examples

EAGAIN The file to be mapped is already locked
using advisory or mandatory record locking.
See fcntl(2).
Is there another instance of your code running? (ps -all)
Sorry - MAP_SHARED is there in my app code. I inadvertently omitted it when I put the example code in my original post above.

There is no other instance of my code running, according to ps -all. That leaves me looking for something else that is locking me out, though I can't think what it might be. I'm using a largely unmodified "vanilla" OS, only having removed stuff I've no need of, such as web browsers, games, python and having installed wicd to get wireless networking happening.

User avatar
joan
Posts: 14936
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO issues

Tue Jul 02, 2013 9:16 pm

Try

Code: Select all

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

#define GPIO_BASE 0x20200000
#define GPIO_LEN  0xB4

#define GPLEV0    13
#define GPLEV1    14

static volatile uint32_t  * gpioReg = MAP_FAILED;

int gpioSetMode(unsigned gpio, unsigned mode)
{
   int reg, shift;

   reg   =  gpio/10;
   shift = (gpio%10) * 3;

   gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift);

   return 0;
}

int gpioGetMode(unsigned gpio)
{
   int reg, shift;

   reg   =  gpio/10;
   shift = (gpio%10) * 3;

   return (*(gpioReg + reg) >> shift) & 7;
}

uint32_t gpioRead_Bits_0_31(void) { return (*(gpioReg + GPLEV0)); }
uint32_t gpioRead_Bits_32_53(void) { return (*(gpioReg + GPLEV1)); }

main()
{
   int fd;

   fd = open("/dev/mem", O_RDWR | O_SYNC) ;

   gpioReg = mmap(0,
                  GPIO_LEN,
                  PROT_READ|PROT_WRITE|PROT_EXEC,
                  MAP_SHARED|MAP_LOCKED,
                  fd,
                  GPIO_BASE);

   close(fd);

   if (gpioReg != MAP_FAILED)
   {
      gpioSetMode(0,  0); /* mode value for input */
      gpioSetMode(1,  0); /* mode value for input */
      gpioSetMode(28, 4); /* mode value for alt0 */
      gpioSetMode(29, 4); /* mode value for alt0 */
   }
   else fprintf(stderr, "map failed\n");
}
Just tried on soft float (3.6.11+ #484) and it works.

tonygrim
Posts: 6
Joined: Sun Jun 23, 2013 9:46 pm

Re: [SOLVED]GPIO issues

Tue Jul 02, 2013 10:58 pm

Yep, that got it going - thanks!! :)

It's odd that it worked under the older OS. All I've effectively done is change the type of the gpio_map pointer returned by mmap from char* to volatile uint32* (previously this was done after the fact via a cast: gpio = (volatile unsigned long *) gpio_map).

Tony

Return to “Advanced users”