1

I am writing code to access /dev/mem on the raspberry pi 4. I'm using nodejs with the package rpio. Rpio uses a "C" language interface. I have modified the *.h file to reflect changes in the hardware address for pi3 to pi4. like so:

#define BCM2711_RPI4_PERI_BASE          0xFE000000

I am aware that root permissions are required. I am running nodejs but the part of the code that accesses hardware is "C".

The problem is that when called from the Javascript via nodejs, it crashes with:

Error: Could not initialize bcm2711 GPIO library

--please see code and output below--

I have printf statement to check the values of all parameters, as you can see.

Surprisingly, I am able to compile and run the C code which is found in the src directory in the rpio code. It executes without problem. So when called from the nodejs program it crashes but run perfect from the C code. Or so it seems.

So being called from a nodejs program makes it fail?

Note: This is puzzling because the C code has no way of knowing how it was called. I have written many tests in the effort and the only difference is that when calling C directly the fd (file descriptor) is equal to 3. When called from the nodejs program the fd is 20 consistently.

As the last note, if I run as user and open /dev/gpio (and change the offset). I have no problems but running root and opening /dev/mem problem.

Thanks in advance for any hints. Please let me know if anyone has any questions.

I have written many test programs mainly to set debug statement, check parameters and to attempt different fixes.

Errors and debug for unsuccessful run:

pi@raspberrypi:~/rpio4-last $ sudo node pin12.js 
Board rev is 12561
***nan_method:rpio_init calling  bcm2711_init 
***bcm2711_init***
Base address is: FE000000
geteuid = 0
Root access to dev mem open
File describitor = 20
bcm2711_peripherals_size = 1800000,bcm2711_peripherals_base = FE000000
mapmem: map size = 1800000
mapmem: offset = 0
mapmem: fd = 20
mapmem:***********after mmap call****************
mapmem: map size = 1800000
mapmem: offset = 0
mapmem: fd = 20
mapmem:  mem mmap failed: Invalid argument
bcm2711_init: Unable to open /dev/mem: Invalid argument
/home/pi/rpio4-last/node_modules/rpio4/lib/rpio4.js:106
    return bindfunc(optarg);
           ^

Code:

static void *mapmem(const char *msg, size_t size, int fd, off_t off)
{
    static int memfd;

    memfd = fd;
    if (fd < 0) {
        printf("mapmem: file descriptor is invalid\n");
        return MAP_FAILED ;
    }

    printf ("mapmem: map size = %X\n",size);
    printf ("mapmem: offset = %X\n",off);
    printf ("mapmem: fd = %d\n",memfd);
    void *map = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, memfd, off);
    if (map == MAP_FAILED) {
        printf ("mapmem:***********after mmap call****************\n");
        printf ("mapmem: map size = %X\n",size);
        printf ("mapmem: offset = %X\n",off);
        printf ("mapmem: fd = %d\n",memfd);
        printf("mapmem:  %s mmap failed: %s\n", msg, strerror(errno));
        }
    return map;
}



Unsuccessful run:
'''
Error: Could not initialize bcm2711 GPIO library
    at bindcall (/home/pi/rpio4-last/node_modules/rpio4/lib/rpio4.js:106:9)
    at EventEmitter.rpio4.init (/home/pi/rpio4-last/node_modules/rpio4/lib/rpio4.js:488:2)
    at rpio4.open (/home/pi/rpio4-last/node_modules/rpio4/lib/rpio4.js:498:19)
    at Object.<anonymous> (/home/pi/rpio4-last/pin12.js:6:6)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)

The bindcall occurred because of the fall thru of the C code error. When compiling just the C code and running successfully. the output is:

pi@raspberrypi:~/rpio4/src $ sudo ./test 
***bcm2711_init***
Base address is: FE000000
geteuid = 0
Root access to dev mem open
File describitor = 3
bcm2711_peripherals_size = 1800000,bcm2711_peripherals_base = FE000000
and the correct led blinks.
  • Are you sure the file descriptor coming from nodejs is open with O_RDWR? – Dmitry Grigoryev Sep 13 at 14:06
  • It looks to me like node cannot find the C library at runtime: Error: Could not initialize bcm2711 GPIO library. A path issue would be consistent with your finding that this works in C but not in node if they are looking in different places for the library. In other words, it may not be a problem with running the C code once you find it, but your programs may be looking in difference places for that code when they run. – Brick Sep 13 at 14:19
  • > Are you sure the file descriptor coming from nodejs is open with O_RDWR? Yes open with : O_RDWR | O_SYNC – Tony Sep 13 at 14:30
  • > It looks to me like node cannot find the C library at runtime < – Tony Sep 13 at 14:43
  • > It looks to me like node cannot find the C library at runtime < Well I'm thinking, this error is produced from my (and others) C code as a result from the failed call to mmap(). This code is found in bcm2711.c it is called by rpio4.js which is the nodejs entry point. All path information (/dev/mem in all cases) is only know in bcm2711.c (alias the bcm2711 GPIO library) . This code when called from nodejs fails on the mmap() call. – Tony Sep 13 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.