Raspberry Pi 3: crash with segfault when trying non-root access to GPIO, works as root

1,026 views
Skip to first unread message

Markus Rudolf

unread,
Apr 13, 2016, 7:37:55 AM4/13/16
to bcm2835
Hi,

I'm using V1.50 on Jessie and recently run into issues. My code was working when started as root with sudo. Then I read about the recently introduced /dev/gpiomem feature for running as non-root and found this great and wanted to give it a try.

Before adding my current user to the gpio group, the bcm2835_init() bailed out with "access denied", as expected.

I added my current user to the gpio group. Since then my application segfaults when calling bcm2835_init(). If I invoke it as root via sudo it works.

Relevant code snippet:

    // init bcm2835 lib (need this for DRDY polling)
   
if (!bcm2835_init())
   
{
        printf
("%s ERROR: bcm2835_init() failed!\n", __FUNCTION__);
       
return -1;
   
}
   
else
   
{
        printf
("%s INFO: BCM2835 Library Version %d successfully initialised.\n", __FUNCTION__, bcm2835_version());
   
};

   
// DRDY pin is input
    bcm2835_gpio_fsel
(DRDY, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud
(DRDY, BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel
(RST, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel
(SYNC, BCM2835_GPIO_FSEL_OUTP);


Console output when run with sudo:

ADS1256_Init INFO: BCM2835 Library Version 10050 successfully initialised.


When run as normal user (member of gpio group) I get a segfault.

strace output:
open("/proc/device-tree/soc/ranges", O_RDONLY) = 4
fstat64
(4, {st_mode=S_IFREG|0444, st_size=12, ...}) = 0
mmap2
(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76fbe000
_llseek
(4, 0, [0], SEEK_SET)            = 0
read
(4, "~\0\0\0", 4)                   = 4
read
(4, "?\0\0\0\1\0\0\0", 4096)        = 8
_llseek
(4, 12, [12], SEEK_SET)          = 0
close
(4)                                = 0
munmap
(0x76fbe000, 4096)                = 0
geteuid32
()                             = 1001
open
("/dev/gpiomem", O_RDWR|O_SYNC)     = 4
mmap2
(NULL, 16777216, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 0) = 0x75d70000
close
(4)                                = 0
write
(1, "ADS1256_Init INFO: BCM2835 Libra"..., 75ADS1256_Init INFO: BCM2835 Library Version 10050 successfully initialised.
) = 75
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x7} ---
+++ killed by SIGSEGV +++
Segmentation fault


Not sure whats happening there. Am I doing something terribly wrong? Don't think so because it works as root.

Markus




Markus Rudolf

unread,
Apr 13, 2016, 1:24:05 PM4/13/16
to bcm2835
When I call bcm2835_set_debug(1); before calling init, it works also without root access. Seems to be a timing issue.
ADS1256_Init INFO: BCM2835 Library Version 10050 successfully initialised.

bcm2835_peri_read  paddr
20200004
bcm2835_peri_write paddr
20200004, value 00000000
bcm2835_peri_write paddr
20200094, value 00000002
bcm2835_delayMicroseconds
10
bcm2835_peri_write paddr
20200098, value 00020000
bcm2835_delayMicroseconds
10
bcm2835_peri_write paddr
20200094, value 00000000
bcm2835_peri_write paddr
20200098, value 00000000
bcm2835_peri_read  paddr
20200004
bcm2835_peri_write paddr
20200004, value 01000000
bcm2835_peri_read  paddr
20200008
bcm2835_peri_write paddr
20200008, value 00200000

Why is there a delay before writing the (I assume) pullup control register? Can it be an issue? (with debug printfs it will introduce more delay).


Mike McCauley

unread,
Apr 13, 2016, 3:42:23 PM4/13/16
to bcm...@googlegroups.com
Hello,

hard to say why its crashing without seeing your code, but I suspect you are
accessing a non GPIO peripheral as non-root.

The delays are required as part of setting the PUD registers.

Cheers.
--
Mike McCauley VK4AMM mi...@airspayce.com
Airspayce Pty Ltd 9 Bulbul Place Currumbin Waters QLD 4223 Australia
http://www.airspayce.com
Phone +61 7 5598-7474

Markus Rudolf

unread,
Apr 14, 2016, 2:58:27 AM4/14/16
to bcm2835



Hello,

hard to say why its crashing without seeing your code, but I suspect you are
accessing a non GPIO peripheral as non-root.

I can upload the code if it helps. I'm only using the GPIO functions, for the SPI I use the two kernel-provided SPI devices via normal IOCTLs (not the BCM2835 lib).

The delays are required as part of setting the PUD registers.


Hmm OK. Why? Is there a manual for the GPIO peripheral of the CPU which states it is required to do so?
Does the GPIO access interfere with the Kernel SPI driver gegarding the two chipselect GPIOs?

Markus
 

Markus Rudolf

unread,
Apr 14, 2016, 11:43:33 AM4/14/16
to bcm2835

The delays are required as part of setting the PUD registers.



Hi Mike,

looks like I found the solution to the issue in another post. Somewhere in the documentation (changelog) it is written
"1.50 2016-02-28 Added support for running as non-root, permitting access to GPIO only."


My naive definition of "GPIO" is all functions that are prefixed with "bcm2835_gpio_xxxx".
 
In some other post you mention that the pullup settings for the GPIO (PUD) are not accessible when one is not root.

The 2nd instruction in my code is

bcm2835_gpio_set_pud(DRDY, BCM2835_GPIO_PUD_UP);

which bails out with a segfault. I assumed it's safe to use because its listed here: http://www.airspayce.com/mikem/bcm2835/group__gpio.html

You should put a clarification note at some prominent position in the documentation clarifying this, I would assume more people stumble across this.

Regards,

Markus

Mike McCauley

unread,
Apr 14, 2016, 8:51:43 PM4/14/16
to bcm...@googlegroups.com
Hello,


On Thursday, April 14, 2016 08:43:33 AM Markus Rudolf wrote:
> > The delays are required as part of setting the PUD registers.
>
> Hi Mike,
>
> looks like I found the solution to the issue in another post. Somewhere in
> the documentation (changelog) it is written
> *"1.50 2016-02-28 Added support for running as non-root, permitting access
> to GPIO only."*
>
> My naive definition of "GPIO" is all functions that are prefixed with
> "bcm2835_gpio_xxxx".
>
> In some other post you mention that the pullup settings for the GPIO (PUD)
> are not accessible when one is not root.
>
> The 2nd instruction in my code is
>
> bcm2835_gpio_set_pud(DRDY, BCM2835_GPIO_PUD_UP);
>
> which bails out with a segfault. I assumed it's safe to use because its
> listed here: http://www.airspayce.com/mikem/bcm2835/group__gpio.html

I would expect that if you are using the latest version of the library, in
this case you would not get a seg fault, but instead the PUD functions would
return without doing anything:

uint32_t bcm2835_gpio_pad(uint8_t group)
{
if (bcm2835_pads == MAP_FAILED)
return 0;
.....

>
> You should put a clarification note at some prominent position in the
> documentation clarifying this, I would assume more people stumble across
> this.

This has now been done for the next release.

>
> Regards,
>
> Markus

Markus Rudolf

unread,
Apr 15, 2016, 4:53:26 AM4/15/16
to bcm2835


On Friday, April 15, 2016 at 2:51:43 AM UTC+2, Mike McCauley wrote:

I would expect that if you are using the latest version of the library, in
this case you would not get a seg fault, but instead the PUD functions would
return without doing anything:

If 10050 respective 1.50 is the latest, then I'm indeed running the most recent version.
 

uint32_t bcm2835_gpio_pad(uint8_t group)
{
  if (bcm2835_pads == MAP_FAILED)
    return 0;
  .....


I don't know, the segfault is gone as soon as I don't use the
 
bcm2835_gpio_set_pud()

anymore

This has now been done for the next release.


Thanks! Any idea about a release date?

Markus
Reply all
Reply to author
Forward
0 new messages