2010-04-29 6 views
2

우리는 USB HID 장치로 구성된 PIC 마이크로 컨트롤러에서 데이터를 읽는 다음 루틴을 사용합니다 (Linux에서는 libudev와 함께). 데이터는 PIC 마이크로 컨트롤러에 연결된 버튼을 눌렀거나 놓은 경우에만 전송됩니다.Linux에서 libudev를 사용하여 읽기를 차단할 때의 문제

루틴에 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

poll이 파일 설명자를 읽을 수 있다는 것을 계속 표시하는 이유는 결코 사용자가 read()이 아니기 때문입니다. ioctl()read()으로 계산되지 않습니다. 아마도 장치는 사용자 공간 프로세스를 깨우는 것이 단지 더미 값이라 할지라도 일부 데이터를 읽을 수있게합니다.

+0

감사합니다. 이것이 필요한 것입니다. –

+0

@SteveHawkins가 성공적으로 출력을 보내고 입력 보고서를 PIC로 수신 할 수 있습니다.이를 위해 특정 API를 사용하고 있습니까? – Raulp

관련 문제