4

D2XXドライバーを使用してシリアルポートデバイスと通信する、Raspberry Piで実行されるCで簡単なアプリケーションを作成しています。私は多くのオンライン チュートリアルとリファレンス ガイドに従って動作させ、カスタム udev ルールを設定してドライバーが正しく読み込まれるようにするなどの手順を実行しました。共有ライブラリをインストールするために FTDI のビルド手順に従いました。コンパイル時にライブラリにリンクする gcc の引数を指定し、ドライバーが適切にアクセスできるように-lC プログラムを実行します。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 メソッドを実行する機会すらありません。フォークされたプロセスで実行している間、そもそもメソッドが見つからないかのようです。

4

1 に答える 1