2

次のルーチン(Linuxではlibudevを使用)を使用して、USBHIDデバイスとして構成されたPICマイクロコントローラーからデータを読み取ります。データは、PICマイクロコントローラに接続されているボタンが押されたとき、または離されたときにのみ送信されます。

ルーチンにPICコントローラーからのメッセージがありません。これは、以下のポーリングの呼び出しが正常に動作していないことが原因であると思われます。

ポーリングの呼び出しは、最初のメッセージが読み取られると、1秒間確実にブロックされます。最初のメッセージが読み取られるとすぐに、ポーリングの呼び出しは、本来のように1秒間(1000ミリ秒)ブロックするのではなく、すぐに戻ります。

読み取りのたびにデバイスを閉じてから再度開くことで、この問題を回避しました。これにより、ポーリングは正しく動作しますが、デバイスを閉じて再度開くことがメッセージが失われる原因である可能性があると思います。

bool PicIo::Receive (unsigned char* picData, const size_t picDataSize) {

    static hiddev_report_info     hidReportInfo;
    static hiddev_usage_ref_multi hidUsageRef;

    if (-1 == PicDeviceDescriptor()) {
        return false;
    }

    // Determine whether or not there is data available to be read
    pollfd pollFd;

    pollFd.fd = PicDeviceDescriptor();
    pollFd.events = POLLIN;

    int dataPending = poll (&pollFd, 1, 1000);

    if (dataPending <= 0) {
        return false;
    }  


    // Initialize the HID Report structure for an input report
    hidReportInfo.report_type = HID_REPORT_TYPE_INPUT;
    hidReportInfo.report_id   = 0;
    hidReportInfo.num_fields  = 64;

    if (-1 == ioctl(PicDeviceDescriptor(), HIDIOCGREPORT, &hidReportInfo)) {
        return false;
    }

    // Initizlize the HID Usage Reference for an Input report
    hidUsageRef.uref.report_type = HID_REPORT_TYPE_INPUT;
    hidUsageRef.uref.report_id   = 0;
    hidUsageRef.uref.field_index = 0;
    hidUsageRef.uref.usage_index = 0;
    hidUsageRef.num_values       = 64;

    if (-1 == ioctl(PicDeviceDescriptor(), HIDIOCGUSAGES, &hidUsageRef)) {
        return false;
    }

    // Transfer bytes from the usage report into the return value.
    for (size_t idx=0; (idx < 64) && (idx < picDataSize); ++idx) {
        picData[idx] = hidUsageRef.values[idx];
    }

    return true;
}

関数PicDeviceDescriptor()は、デバイスが存在することを確認するためにデバイスをチェックします。PicDeviceDescriptor関数の関連する詳細は、デバイスがどのように開かれるかを示しています。

int PicIo::PicDeviceDescriptor(int command) {

    struct stat     statInfo;
    static int      picDeviceDescriptor = -1;
    string          picDevicePath       = "/dev/usb/hiddev0";

    if ((-1 != picDeviceDescriptor) && (CLOSE == command)) {
        close (picDeviceDescriptor);
        picDeviceDescriptor = -1;
    } else if ((-1 != picDeviceDescriptor) && (-1 == fstat(picDeviceDescriptor, &statInfo))) {
        // Handle the case where the PIC device had previously been detected, and
        // is now disconnected.
        close (picDeviceDescriptor);
        picDeviceDescriptor = -1;
    } else if ((-1 == picDeviceDescriptor) && (m_picDevice.IsConnected())) {
        // Create the PIC device descriptor if the PIC device is present (i.e. its 
        // device node is present) and if the descriptor does not already exist
        picDeviceDescriptor = open (picDevicePath.c_str(), O_RDONLY);
    }

    return picDeviceDescriptor;
}

私は何か間違ったことをしていると確信していますが、私はその問題をグーグルで検索し、関連する答えを見つけることができないようです。どんな助けでも大歓迎です-Thx。

4

1 に答える 1

4

pollファイル記述子が読み取り可能であることを示し続けている理由は、ファイル記述子read()から決して取得できないためです。 ioctl()としてカウントされませんread()。おそらく、デバイスは、ユーザースペースプロセスをウェイクアップするためのダミー値にすぎない場合でも、一部のデータを読み取れるようにします。

于 2010-04-29T02:56:37.990 に答える