Estoy intentando hacer una clase con la funcionalidad básica (abrir,cerrar,leer,escribir) para manejar el puerto serie.
Esto es debido a que el puerto serie que tengo que usar lo genera "virtualmente" un programa y la clase SerialPort del .NET Framework no consigue ni abrirlo. (Pregunté en foros de microsof (msdn) y me dijeron que tenía que hacerlo con la WINAPI).
Tras hacer la clase y probarla, he conseguido abrir el puerto y cerrarlo bien. El problema es que no consigo leer ni escribir. En ambas operaciones, si hago "GetLastError()" el error resultante es 997, que según microsoft es: ERROR_IO_PENDING - Overlapped I/O operation is in progress.
(http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx)
NOTA: si llamo a las funciones de lectura / escritura con el parámetro LPOVERLAPPED como NULL, el código de error (GetLastError) es 87 (el parámetro es incorrecto), el mismo error que tuve cuando traté de usar la clase Net Framework SerialPort.
EDITO: Lo que me da problemas es el overlapped, si lo quito, todo va bien. Entonces mi problema es que no se usar el overlapped bien, que hago mal?
Adjunto el código de la clase (solo el cpp, el .h no lo veo necesario):
Código:
Y aquí el main:#include "StdAfx.h" #include "SerialPort_WINAPI.h" /*** Atributos constantes definidos en el .h ***/ const wchar_t *const SerialPort_WINAPI::DEFAULT_PORT_NAME = L"COM6"; static const wchar_t *const DEFAULT_PORT_NAME; //Inicializado en el cpp. static const DWORD BAUD_RATE = 9600; static const BYTE STOP_BITS = 1; static const BYTE PARITY = 0; //0==None static const BYTE DATA_BITS = 8; static const DWORD HANDSHAKE = 0x00; SerialPort_WINAPI::SerialPort_WINAPI(void){ } SerialPort_WINAPI::~SerialPort_WINAPI(void){ } SerialPortErr SerialPort_WINAPI::openConnection(){ port = CreateFile(SerialPort_WINAPI::DEFAULT_PORT_NAME, //\\\\.\\COM4" GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // default security attributes OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); if (port == INVALID_HANDLE_VALUE) return Create_File_Err; if (GetCommState(port, &portConfig) == 0){ closeConnection(); return Get_Comm_State_Err; } initData(); if (SetCommState(port, &portConfig) == 0){ closeConnection(); return Set_Comm_State_Err; } if (SetCommMask(port, EV_DSR) == 0){ //EV_CTS | EV_DSR closeConnection(); return Set_Comm_Mask_Err; } initOverlapped(); portEvents.hEvent = CreateEvent( NULL, // default security attributes TRUE, // manual-reset event FALSE, // not signaled NULL // no name ); return Exit_Success; }; void SerialPort_WINAPI::initData(){ portConfig.BaudRate = BAUD_RATE; portConfig.fRtsControl = HANDSHAKE; portConfig.Parity = PARITY; portConfig.ByteSize = DATA_BITS; portConfig.StopBits = STOP_BITS; }; void SerialPort_WINAPI::initOverlapped(){ portEvents.Internal = 0; portEvents.InternalHigh = 0; portEvents.Offset = 0; portEvents.OffsetHigh = 0; }; SerialPortErr SerialPort_WINAPI::closeConnection(){ SetCommMask(port,0); if (CloseHandle(port) == 0) return Close_Err; return Exit_Success; }; SerialPortErr SerialPort_WINAPI::read(char *buffer,int length,LPDWORD read){ if(!ReadFile(this->port,buffer,length,read,&this->portEvents)){ return Read_Err; } } SerialPortErr SerialPort_WINAPI::write(char *buffer,int nBytesToWrite,LPDWORD write){ if(!WriteFile(this->port,buffer,nBytesToWrite,write,&this->portEvents)){ return Write_Err; } }
Código:
He estado intentando aprender a usar esta API para el puerto serie, pero aunque he leído algunos ejemplos etc. hay muchas cosas que no entiendo.int main(){ SerialPort_WINAPI sp; char buff[20]; DWORD bW; char readBuffer[128]; DWORD read; char writeBuffer[10]; DWORD write; for(int i=0;i<10;i++) writeBuffer[i]='a'; SerialPortErr err=sp.openConnection(); if(err!=Exit_Success){ cout<<"open: "<<(int)err<<endl; return -1; }else{ cout<<"Openned..."<<endl; } err=sp.write(writeBuffer,10,&write); if(err!=Exit_Success){ cout<<"write: "<<GetLastError()<<endl; } err=sp.read(readBuffer,128,&read); if(err!=Exit_Success){ cout<<"read: "<<GetLastError()<<endl; } err=sp.closeConnection(); cout<<"close: "<<(int)err<<endl; return 0; }
Por ej. : ¿OVERLAPPED sirve para añadir funciones de callback a distintos eventos del puerto serie, como leer o escribir?
Gracias y saludos.