我正在编写代码来访问树莓派 4 上的 /dev/mem。我将 nodejs 与包 rpio 一起使用。Rpio 使用“C”语言界面。我修改了 *.h 文件以反映 pi3 到 pi4 的硬件地址的变化。像这样:
define BCM2711_RPI4_PERI_BASE 0xFE000000
我知道需要root权限。我正在运行 nodejs,但访问硬件的代码部分是“C”。
问题是,当通过 nodejs 从 Javascript 调用时,它会崩溃:
错误:无法初始化 bcm2711 GPIO 库
--请看下面的代码和输出--
如您所见,我有 printf 语句来检查所有参数的值。
令人惊讶的是,我能够编译和运行在 rpio 代码的 src 目录中找到的 C 代码。它执行没有问题。因此,当从 nodejs 程序调用时,它会崩溃,但可以从 C 代码中完美运行。或者看起来是这样。
那么从 nodejs 程序中调用会使其失败?
注意:这令人费解,因为 C 代码无法知道它是如何调用的。我已经编写了许多测试,唯一的区别是直接调用 C 时,fd(文件描述符)等于 3。从 nodejs 程序调用时,fd 始终为 20。
最后一点,如果我以用户身份运行并打开 /dev/gpio (并更改偏移量)。我没有问题,但运行 root 并打开 /dev/mem 问题。
提前感谢您的任何提示。如果有人有任何问题,请告诉我。
我编写了许多测试程序,主要是为了设置调试语句、检查参数和尝试不同的修复。
运行不成功的错误和调试:
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.
仅编译 C 代码并成功运行时。输出是:
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
并且正确的 LED 闪烁。