D2XXドライバーを使用してシリアルポートデバイスと通信する、Raspberry Piで実行されるCで簡単なアプリケーションを作成しています。私は多くのオンライン チュートリアルとリファレンス ガイドに従って動作させ、カスタム udev ルールを設定してドライバーが正しく読み込まれるようにするなどの手順を実行しました。共有ライブラリをインストールするために FTDI のビルド手順に従いました。コンパイル時にライブラリにリンクする gcc の引数を指定し、ドライバーが適切にアクセスできるように-l
C プログラムを実行します。sudo
そしてそれは成功しました!プログラムは意図したとおりに動作します。
今、単純なプログラムを init.d スクリプト (a la ) で制御できるデーモン プロセスに変換しようとしていますがservice start
、問題が発生しました。
簡単にするために、動作する私の C プログラムの骨抜きバージョンを次に示します。
myprog.c:
#include <stdlib.h>
#include "ftd2xx.h"
int main(int argc, char *argv[])
{
DWORD i, iNumDevs = 0;
char *serialNumber = malloc(64);
FT_STATUS ftStatus = FT_CreateDeviceInfoList(&iNumDevs);
for (i = 0; i < iNumDevs; i++) {
ftStatus = FT_ListDevices((PVOID)i, serialNumber, FT_LIST_BY_INDEX|FT_OPEN_BY_SERIAL_NUMBER);
if (FT_OK == ftStatus) {
break;
}
}
// more code here...
return EXIT_SUCCESS;
}
私はそれを でコンパイルしてgcc -lftd2xx -o myprog myprog.c
から で実行sudo ./myprog
します。しかし、この同じコードをデーモンに作り直そうとしているので、他のオンライン チュートリアルに従っています。上記のコードは、より似たものに変換されています。現在、これは機能しません:
mydaemon.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "ftd2xx.h"
int main(int argc, char *argv[])
{
pid_t pid, sid;
pid = fork();
if (pid < 0) {
return EXIT_FAILURE;
}
if (pid > 0) {
return EXIT_SUCCESS;
}
umask(0);
openlog("mydaemon", LOG_PID|LOG_CONS, LOG_USER);
sid = setsid();
if (sid < 0) {
syslog(LOG_ERR, "Failed to set session ID on child process");
return EXIT_FAILURE;
}
if ((chdir("/")) < 0) {
syslog(LOG_ERR, "Failed to change working directory");
return EXIT_FAILURE;
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
while (1) {
DWORD i, iNumDevs = 0;
char *serialNumber = malloc(64);
syslog(LOG_INFO, "I get to this line");
FT_STATUS ftStatus = FT_CreateDeviceInfoList(&iNumDevs);
syslog(LOG_INFO, "I do not get to this line :( ");
// more code here...
sleep(10);
}
return EXIT_SUCCESS;
}
そのプログラムをまったく同じ方法でコンパイルしますgcc -lftd2xx -o mydaemon mydaemon.c
。私は同じように実行します:sudo ./mydaemon
が、残念ながら動作しません。別のコンソール ウィンドウで/var/log/messages
ファイルを追跡しています。最初のログ メッセージ (つまり、"I can get to this line") に達したことをはっきりと確認できますが、その直後にファイルが死んでしまいます。2 番目のログ メッセージは表示されません。実際、その時点で、プログラムは完全に応答しなくなります。そのプロセス ID を見つけて強制終了する必要があります。
つまり、フォークされたプロセスで D2XX ドライバーを呼び出そうとするとすぐに失敗します。私は何を間違っていますか?最初の例でコードが機能することは既に説明しましたが、デーモンとして実行すると完全に機能しなくなるのはなぜでしょうか? 私が知る限り、問題の D2XX メソッドを実行する機会すらありません。フォークされたプロセスで実行している間、そもそもメソッドが見つからないかのようです。