jperkin/node-rpio

gpio mmap failing due to invalid argument on Pi 4

EthyMoney opened this issue · 15 comments

Hi there,

I have a raspberry pi 4 model B with node 12.11.1 and the the current rpio 1.3 installed. I'm having an issue attempting to set up rpio using access to /dev/mem for i2c support. When I attempt to run the init() function with with /dev/mem support, I receive the following error:

bcm2835_init: gpio mmap failed: Invalid argument
/home/pi/Desktop/Projects/DevControl/node_modules/rpio/lib/rpio.js:104
	return bindfunc(optarg);
	       ^

Error: Could not initialize bcm2835 GPIO library
    at bindcall (/home/pi/Desktop/Projects/RelayControl/node_modules/rpio/lib/rpio.js:104:9)
    at rpio.init (/home/pi/Desktop/Projects/RelayControl/node_modules/rpio/lib/rpio.js:506:2)

I get this error even when running as root. I really can't see what may be wrong here so I'm checking in with you on this. When using the gpio mem it works fine, this only happened with the /dev/mem.

Here's my code that I'm using to call init() where it's failing:

var rpio = require('rpio');

var options = {
        gpiomem: false,
        mapping: 'gpio',
        mock: false,
}
rpio.init(options);  // Failing here

Is there something I'm missing or a potential bug with my configuration? Thanks in advance!

Yeh there's nothing wrong with your code, this is internal to the bcm2835 code which for whatever reason isn't able to open the RPi4 memory range. I don't yet have an RPi4 on which to test, according to the bcm2835 group it should work but I wonder if there are still some incompatibilities lingering.

If you wanted to do some debugging then adding a bunch of debug printfs in bcm_init() would be helpful, especially in the section where it opens BMC2835_RPI2_DT_FILENAME, so we can see what it thinks the base address and size are.

Also just pasting the output of this command would be helpful:

$ xxd < /proc/device-tree/soc/ranges

Also could you confirm which model RPi4 you have? I wonder if the values differ depending on whether you have the 1GB, 2GB, or 4GB model.

Sorry the delay getting back to you. I had some time to play with it tonight.

Forgot to mention it, but this Pi4 is the 2GB version.

Here's the output of the command you gave:

00000000: 7e00 0000 0000 0000 fe00 0000 0180 0000  ~...............
00000010: 7c00 0000 0000 0000 fc00 0000 0200 0000  |...............
00000020: 4000 0000 0000 0000 ff80 0000 0080 0000  @...............

I also got the base_address and peri_size printed from bcm2835_init(). Here's that output:

Base Address: 
-33554432
Size: 
25165824

Let me know if there's anything else I can get for you. I'm more than happy to help where I can :)

Thanks! I'm trying to collate information in this gist: https://gist.github.com/jperkin/c37a574379ef71e339361954be96be12

It includes a quick script to run, could you paste the output of that? It'll contain a lot of what you already posted but will include a bit more information that will be useful for other ways to improve the library.

Done! I just posted it in the comments over there for ya. For the sake of this issue I'll go ahead and put it here as well.

Here's what I got for my 2GB Pi4:

cpuinfo:      b03111
dtmodel:      Raspberry Pi 4 Model B Rev 1.1
socranges:    7e000000 00000000 fe000000
os:           10

One more here... Pi 4 2GB as well... there's a warning, not sure if it makes sense.. I've stumbled upon this while was searching for an answer... it seems like they think it should work but it doesn't — https://groups.google.com/forum/#!topic/bcm2835/BwZXVsDRtwI

Any way I can help somehow?

cpuinfo:	b03111
./test.sh: line 6: warning: command substitution: ignored null byte in input
dtmodel:	Raspberry Pi 4 Model B Rev 1.1
socranges:	7e000000 00000000 fe000000
os:		10

Here too, with Pi 4 4GB.

There are some warnings when installing the npm package from node-gyp, maybe this helps..:

$ npm i rpio

> rpio@1.3.0 install /home/pi/rentainer/node_modules/rpio
> node-gyp rebuild

make: Entering directory '/home/pi/rentainer/node_modules/rpio/build'
  CC(target) Release/obj.target/rpio/src/bcm2835.o
../src/bcm2835.c: In function ‘bcm2835_gpio_pad’:
../src/bcm2835.c:487:3: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
   if (bcm2835_pads == MAP_FAILED)
   ^~
../src/bcm2835.c:490:5: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
     volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group;
     ^~~~~~~~
../src/bcm2835.c: In function ‘bcm2835_gpio_set_pad’:
../src/bcm2835.c:500:3: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
   if (bcm2835_pads == MAP_FAILED)
   ^~
../src/bcm2835.c:503:5: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
     volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group;
     ^~~~~~~~
../src/bcm2835.c: In function ‘bcm2835_init’:
../src/bcm2835.c:1816:77: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
       bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, (off_t)bcm2835_peripherals_base);
                                                                             ^
../src/bcm2835.c:1849:77: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
       bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, (off_t)bcm2835_peripherals_base);
                                                                             ^
  CXX(target) Release/obj.target/rpio/src/rpio.o
In file included from ../src/rpio.cc:17:
../../nan/nan.h: In function ‘void Nan::AsyncQueueWorker(Nan::AsyncWorker*)’:
../../nan/nan.h:2298:62: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
     , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
                                                              ^
In file included from ../../nan/nan.h:54,
                 from ../src/rpio.cc:17:
../src/rpio.cc: At global scope:
/home/pi/.cache/node-gyp/12.13.1/include/node/node.h:566:43: warning: cast between incompatible function types from  void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
       (node::addon_register_func) (regfunc),                          \
                                           ^
/home/pi/.cache/node-gyp/12.13.1/include/node/node.h:600:3: note: in expansion of macro ‘NODE_MODULE_X’
   NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
   ^~~~~~~~~~~~~
../src/rpio.cc:460:1: note: in expansion of macro ‘NODE_MODULE’
 NODE_MODULE(rpio, setup)
 ^~~~~~~~~~~
In file included from /home/pi/.cache/node-gyp/12.13.1/include/node/node.h:63,
                 from ../../nan/nan.h:54,
                 from ../src/rpio.cc:17:
/home/pi/.cache/node-gyp/12.13.1/include/node/v8.h: In instantiation of ‘void v8::PersistentBase<T>::SetWeak(P*, typename v8::WeakCallbackInfo<P>::Callback, v8::WeakCallbackType) [with P = node::ObjectWrap; T = v8::Object; typename v8::WeakCallbackInfo<P>::Callback = void (*)(const v8::WeakCallbackInfo<node::ObjectWrap>&)]’:
/home/pi/.cache/node-gyp/12.13.1/include/node/node_object_wrap.h:84:78:   required from here
/home/pi/.cache/node-gyp/12.13.1/include/node/v8.h:10004:16: warning: cast between incompatible function types from  v8::WeakCallbackInfo<node::ObjectWrap>::Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<node::ObjectWrap>&)’} to ‘Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<void>&)’} [-Wcast-function-type]
                reinterpret_cast<Callback>(callback), type);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pi/.cache/node-gyp/12.13.1/include/node/v8.h: In instantiation of ‘void v8::PersistentBase<T>::SetWeak(P*, typename v8::WeakCallbackInfo<P>::Callback, v8::WeakCallbackType) [with P = Nan::ObjectWrap; T = v8::Object; typename v8::WeakCallbackInfo<P>::Callback = void (*)(const v8::WeakCallbackInfo<Nan::ObjectWrap>&)]’:
../../nan/nan_object_wrap.h:65:61:   required from here
/home/pi/.cache/node-gyp/12.13.1/include/node/v8.h:10004:16: warning: cast between incompatible function types from  v8::WeakCallbackInfo<Nan::ObjectWrap>::Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<Nan::ObjectWrap>&)’} to ‘Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<void>&)’} [-Wcast-function-type]
  SOLINK_MODULE(target) Release/obj.target/rpio.node
  COPY Release/rpio.node
make: Leaving directory '/home/pi/rentainer/node_modules/rpio/build'
npm WARN rentainer@1.0.0 No description
npm WARN rentainer@1.0.0 No repository field.

+ rpio@1.3.0
updated 1 package and audited 258 packages in 8.397s
found 0 vulnerabilities

Also not working for me. RPi 4 4GB.
Here's the output:

cpuinfo: c03111
./script.sh: line 6: warning: command substitution: ignored null byte in input
dtmodel: Raspberry Pi 4 Model B Rev 1.1
socranges: 7e000000 00000000 fe000000
os: 10

Is there any update about this issue? The BCM library doesn't have any updates for the RPi4 except version 1.6. I checked the library version in the RPIO package and that is the right version. Is there anything i can do to help solve this?

I bought myself a RPi4 for Christmas so will be looking at this issue shortly.

I bought myself a RPi4 for Christmas so will be looking at this issue shortly.

That's a nice gift for yourself. And I'm glad you could take a look, thanks!

Ok I found the issue, this should be fixed with f073a12 and the 1.4.0 release, at least it now works correctly on my Pi3 and Pi4.

It works!! Thank you very much!