以下に非同期シリアル通信の概要を示します。 メインプログラムとは別にシリアル通信用にスレッドを用意して、 内部で通信イベントを待たせます。イベントの通知は、 Windowsが提供するイベントオブジェクトを介して行われます。 イベントはWaitForMultipleObjects()関数で待ち合わせができます。 具体的には、必要な数イベントハンドルを用意して、 WaitForMultipleObjects関数を呼び出すことで待ち状態に入ります。 いずれかのイベントハンドルがセットされると、WaitForMultipleObjects関数は、 セットされたイベントハンドルの番号を返して、待ち状態から戻ってきます。 イベントハンドルは手動でセットすることもできますが、 送信完了時や、データ受信時にOSにセットしてもらうこともできます。
受信データは、あらかじめシリアル通信クラスに呼び出される関数を登録しておき、 イベント発生時に登録した関数に引数としてわたします。 メインスレッドとの同期は、TThreadに用意されているSynchronizeメソッドを介して 関数を呼び出すことによって行われます。
Windows上でシリアルポートを扱う場合、 ファイルと同様にCreateFile()でポートを開いて、WriteFile()、ReadFile()関数で読み書きを行います。 また、CreateFile()関数にFILE_FLAG_OVERLAPPEDを指定することで非同期通信を実現することができます。 CreateFileで開くパスはポート番号が9以下ならCOMn、10以上なら\\.\COMnとなります。
//パスの作成
stringstream path;
if ( FChPort>9 ) {
path << "\\\\.\\COM" << FChPort;
}
else {
path << "COM" << FChPort;
}
//ポートのオープン
hCom = CreateFile(
path.str().c_str(), // ファイル名
GENERIC_READ | GENERIC_WRITE, // アクセスモード
0, // 共有モード
NULL, // セキュリティ記述子
OPEN_EXISTING, // 作成方法
FILE_FLAG_OVERLAPPED, // ファイル属性
NULL // テンプレートファイルのハンドル
);
if ( hCom==INVALID_HANDLE_VALUE ) return false;
//定数の定義 #define WAIT_COMM WAIT_OBJECT_0 #define WAIT_ESC (WAIT_OBJECT_0+1) const int COMM_EVENT = 0; const int ESC_FUNC = 1;
//イベントオブジェクトの生成 hEventObjects[COMM_EVENT] = CreateEvent(NULL, TRUE, FALSE, NULL); hEventObjects[ESC_FUNC] = CreateEvent(NULL, TRUE, FALSE, NULL); //OVERLAPPED構造体の初期化 //OVERLAPPED fOverLapped; ZeroMemory(&fOverLapped, sizeof(OVERLAPPED)); fOverLapped.Offset = 0; fOverLapped.OffsetHigh = 0; fOverLapped.hEvent = hEventObject[COMM_EVENT]; //イベントマスクを設定して通信イベントを待ちます。 SetCommMask(hCom, EV_TXEMPTY | EV_RXCHAR | fEventMask); WaitCommEvent(hCom, &fEvent, &fOverLapped);
//えくすきゅーと
void __fastcall TCommPort::Execute()
{
DWORD Result;
// TODO : スレッドとして実行したいコードを以下に記述 */
while ( !Terminated ) {
//ここでイベント待ちブロック
Result = WaitForMultipleObjects(2, hEventObjects, FALSE, 500);
//イベント分岐
switch ( Result ) {
//通信イベント
case WAIT_COMM:
Synchronize((TThreadMethod)&comm_event);
break;
//RTSリクエスト
case WAIT_ESC:
Synchronize((TThreadMethod)&esc_func);
break;
}
}
}
//---------------------------------------------------------------------------