FT2232H USB/RS232 コンバーター経由でデバイスと通信するアプリケーションを作成しています。通信には、FTDI Web サイトの FTD2XX_NET.dll ライブラリを使用しています。
私は2つのスレッドを使用しています:
です。レシーバーのスレッドの実行中にデバイスにデータを書き込もうとすると、問題が発生します。メイン スレッドは単に ftdiDevice.Write 関数でハングアップします。
同時に 1 つのスレッドのみが読み取り/書き込み機能を使用できるように、両方のスレッドを同期しようとしましたが、役に立ちませんでした。
以下のコードは、通信を担当します。以下の関数は FtdiPort クラスのメソッドであることに注意してください。
受信者のスレッド
private void receiverLoop()
{
if (this.DataReceivedHandler == null)
{
throw new BackendException("dataReceived delegate is not set");
}
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
byte[] readBytes = new byte[this.ReadBufferSize];
while (true)
{
lock (FtdiPort.threadLocker)
{
UInt32 numBytesRead = 0;
ftStatus = ftdiDevice.Read(readBytes, this.ReadBufferSize, ref numBytesRead);
if (ftStatus == FTDI.FT_STATUS.FT_OK)
{
this.DataReceivedHandler(readBytes, numBytesRead);
}
else
{
Trace.WriteLine(String.Format("Couldn't read data from ftdi: status {0}", ftStatus));
Thread.Sleep(10);
}
}
Thread.Sleep(this.RXThreadDelay);
}
}
メインスレッドから呼び出された書き込み関数
public void Write(byte[] data, int length)
{
if (this.IsOpened)
{
uint i = 0;
lock (FtdiPort.threadLocker)
{
this.ftdiDevice.Write(data, length, ref i);
}
Thread.Sleep(1);
if (i != (int)length)
{
throw new BackendException("Couldnt send all data");
}
}
else
{
throw new BackendException("Port is closed");
}
}
2 つのスレッドの同期に使用されるオブジェクト
static Object threadLocker = new Object();
受信者のスレッドを開始するメソッド
private void startReceiver()
{
if (this.DataReceivedHandler == null)
{
return;
}
if (this.IsOpened == false)
{
throw new BackendException("Trying to start listening for raw data while disconnected");
}
this.receiverThread = new Thread(this.receiverLoop);
//this.receiverThread.Name = "protocolListener";
this.receiverThread.IsBackground = true;
this.receiverThread.Start();
}
次の行にコメントすると、ftdiDevice.Write 関数はハングアップしません。
ftStatus = ftdiDevice.Read(readBytes, this.ReadBufferSize, ref numBytesRead);