raspberry pi 4 で /dev/mem にアクセスするコードを書いています。パッケージ rpio で nodejs を使用しています。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 を開く (そしてオフセットを変更する) とします。問題はありませんが、ルートを実行して /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 が点滅します。