|
タイトル通り、スレッドを使ったシリアル通信プログラムを作っているのですが、行き詰っています。
Visual Studio.netで開発していて、Win32 コンソールプロジェクトで作っています。Windows上に、新しくウインドウを作ったりするのではありません。
以下が、途中まで作っているプログラムです。
スレッドでは、常に読み込みをしてリングバッファに書き込みをしていくプログラムにしようと思っています。
わからない点は、
スレッド(ReadThread)の中でReadFileでシリアルポートからデータを読み込んだときに、リングバッファへの書き込みをするためのプログラムの書き方がわかりません。
○ポートからデータを読む
○リングバッファ更新するため排他をかける
○リングバッファにデータを書き込む
○排他を解除に、またポートからデータを読む
というスレッドにしたいのです。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#define BUFFSIZE 256 //バッファサイズ
#define TRUE 1
#define FALSE 0
HANDLE hCom; //シリアルポートのハンドラ
HANDLE hthread; //スレッドのハンドル
int run; //スレッドの実行フラグ(実行中か否か)
int stopped; //スレッド停止フラグ(停止したかどうか)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void init()
{
hCom = INVALID_HANDLE_VALUE;
hthread = NULL;
run = FALSE;
stopped = TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//受信スレッド
static void ReadThread(void* lpvoid)
{
static unsigned long Readsize; //読み取ったバイト数
static struct _OVERLAPPED Overlapped; //オーバーラップ構造体のバッファ
static unsigned char ReadBuf[BUFFSIZE]; // 受信データ
long dataBuf[BUFFSIZE]; //リングバッファ
if(!ReadFile(hCom, ReadBuf, 8, &Readsize, &Overlapped) || Readsize == 0)
{
}
Sleep(10);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ポートオープン
// CString PortName[] = {"COM1","COM2","COM3","COM4"}
int Com_Open(void)
{
hCom = CreateFile("COM1", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(hCom == INVALID_HANDLE_VALUE){
printf("★ポートをオープンできませんでした。\n");
return FALSE;
}else printf("☆ポートをオープンしました。\n");
//通信設定 19200, 8BIT, 偶数パリティ, STOP1に固定
DCB dcb; // DCB構造体
if(!GetCommState(hCom, &dcb)){
printf("★通信設定失敗しました。\n");
return(FALSE);
}else printf("☆通信デバイスの設定を制御ブロックに格納しました。\n");
dcb.BaudRate = 19200;
dcb.ByteSize = 8;
dcb.Parity = EVENPARITY;
dcb.StopBits = ONESTOPBIT;
if(!SetCommState(hCom, &dcb)){//通信デバイス構成の初期化
printf("★通信デバイス構成の初期化に失敗しました。\n");
return(FALSE);
}else printf("☆伝送方法を設定しました。\n");
// タイマー設定 : 受信待ち無制限、送信待ち100ms + 1文字10ms
COMMTIMEOUTS Timeout; // タイムアウト構造体
Timeout.ReadIntervalTimeout = 0;
Timeout.ReadTotalTimeoutMultiplier = 0;
Timeout.ReadTotalTimeoutConstant = 0;//タイムアウト時間
Timeout.WriteTotalTimeoutMultiplier = 10;
Timeout.WriteTotalTimeoutConstant = 100;
if(!GetCommTimeouts(hCom, &Timeout)){
printf("★タイムアウト失敗\n");
return(FALSE);
}else printf("☆タイムアウト成功 \n");
return(TRUE);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int open()
{
//すでにコネクションが張られているなら何もしない
if(hCom != INVALID_HANDLE_VALUE)
return(FALSE);
//シリアルポートのオープン
if(Com_Open() == FALSE)
return(FALSE);
//スレッドを走らせる
run = TRUE;
stopped = FALSE;
if((unsigned long)(hthread = (HANDLE)_beginthread(ReadThread, 0, hCom)) == -1){
CloseHandle(hCom);
hCom = INVALID_HANDLE_VALUE;
run = FALSE;
stopped = TRUE;
return(FALSE);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int serial_close(void)
{
if(run == TRUE){
run = FALSE;
while(stopped == FALSE)
Sleep(10);
CloseHandle(hCom);
hCom = INVALID_HANDLE_VALUE;
hthread = NULL;
}
return (TRUE);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
init();
open();
serial_close();
}
|