在Linux上的FT_SetEventNotification

问题描述

我有三个不同的Java线程打开三个串行设备。我只是想知道是否必须为读取函数内部的每个线程(局部变量)创建EVENT_HANDLE eh,或者仅为读取数据函数外部的全局变量创建EVENT_HANDLE eh。根据下面的示例,pthread_cond_wait(&eh.eCondVar,&eh.eMutex);是关键部分,在Linux操作系统的链接https://www.ftdichip.com/Support/Knowledgebase/index.html?ft_seteventnotification.htm中提供。我试图了解是否必须执行相同的锁定机制,因为我一次只能从每个Java线程读取一次。请提供一些输入。

FT_HANDLE ftHandle; 
FT_STATUS ftStatus;
EVENT_HANDLE eh;
DWORD EventMask;

ftStatus = FT_Open(0,&ftHandle);
if(ftStatus != FT_OK) {
   // FT_Open Failed
   return;
}

pthread_mutex_init(&eh.eMutex,NULL);
pthread_cond_init(&eh.eCondVar,NULL);

EventMask = FT_EVENT_RXCHAR | FT_EVENT_MODEM_STATUS;
ftStatus = FT_SetEventNotification(ftHandle,EventMask,(PVOID)&eh);

pthread_mutex_lock(&eh.eMutex);
pthread_cond_wait(&eh.eCondVar,&eh.eMutex);
pthread_mutex_unlock(&eh.eMutex);

DWORD EventDWord;
DWORD RxBytes;
DWORD TxBytes;
DWORD Status;
FT_GetStatus(ftHandle,&RxBytes,&TxBytes,&EventDWord);
if (EventDWord & FT_EVENT_MODEM_STATUS) {
    // modem status event detected,so get current modem status
    FT_GetModemStatus(ftHandle,&Status);
    if (Status & 0x00000010) {
          // CTS is high
    }
    else {
          // CTS is low
    }
    if (Status & 0x00000020) {
          // DSR is high
    }
    else {
          // DSR is low
    }
}
if (RxBytes > 0) {
    // call FT_Read() to get received data from device
}

FT_Close(ftHandle);

解决方法

我的代码是使用d2xx驱动程序的c#,但希望对您有所帮助。您必须为打开的每个FTDI设备创建一个EVENT_HANDLE。在打开设备时创建EventHandle,在关闭设备时销毁它。同时听事件。

在不同设备之间共享的全局句柄将产生混淆来自设备的事件通知的效果。不太好。

    public FTDISerialPortDevice(string serialNumber)
    {
        _serialNumber = serialNumber
        _ftdi = new FTDI(); // This is the ftdi device
        _bytesReceivedEvent = new AutoResetEvent(false);
    }
    
    public void Open()
    {
        if (_ftdi.IsOpen)
            throw new InvalidOperationException($"Access to the device '{_serialNumber}' is denied.");
    
        if (_ftdi.OpenBySerialNumber(_serialNumber ) != FTDI.FT_STATUS.FT_OK)
            throw new InvalidOperationException($"Access to the device '{_serialNumber }' is denied.");
    
         // Do device configuration stuff ....

        _ftdi.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR,_bytesReceivedEvent);
    
    }


    public int Receive(byte[] readBuffer,int offset)
    {
       // listen to event and do reads
    }