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.
6
  • Are you sure the file descriptor coming from nodejs is open with O_RDWR? Commented Sep 13, 2019 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
    Commented Sep 13, 2019 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
    Commented Sep 13, 2019 at 14:30
  • > It looks to me like node cannot find the C library at runtime <
    – Tony
    Commented Sep 13, 2019 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
    Commented Sep 13, 2019 at 14:58

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.