POSIX SerialPorts: Local Echo?
-
Hi everyone
Seit einer Weile schon schlage ich mich nun mit der POSIX-Schnittstelle für Serielle Ports herum, was bisher eigentlich auch ganz gut klappt. Das einzige Problem ist, dass ich alle Zeichen, die ich sende, sogleich auch in meinem Empfangspuffer habe und beim nächsten read empfange.
Das ist realtiv lästig und ich würde dieses Verhalten gerne abschalten. Gibt es dazu ein spezielles Flag, das ich setzen bzw. löschen müsste?
Besten Dank für eure Hilfe und greeetz
Kessi
-
Ich mach's so:
#include <unistd.h> #include <memory.h> #include <errno.h> #include <termio.h> #include <sys/time.h> #include <sys/fcntl.h> #include <sys/ioctl.h> #include <linux/serial.h> #include "ComTools.h" #include <linux/version.h> #if LINUX_VERSION_CODE < 0x020400 #warning "LINUX Version NOT OK" #endif typedef struct { unsigned long iBaud; speed_t iCode; }TcSpeed; static TcSpeed aTcSpeeds[] = { #ifdef B300 {300, B300}, #endif #ifdef B600 {600, B600}, #endif #ifdef B1200 {1200, B1200}, #endif #ifdef B1800 {1800, B1800}, #endif #ifdef B2400 {2400, B2400}, #endif #ifdef B4800 {4800, B4800}, #endif #ifdef B9600 {9600, B9600}, #endif #ifdef B19200 {19200, B19200}, #endif #ifdef B38400 {38400, B38400}, #endif #ifdef B57600 {57600, B57600}, #endif #ifdef B115200 {115200, B115200}, #endif }; #define MAX_SPEED (sizeof(aTcSpeeds)/sizeof(aTcSpeeds[0])) #define MAX_COM_PORTS 8 static int iComFile[MAX_COM_PORTS]; static char cIsOpen [MAX_COM_PORTS]; int iProtocolHandle=-1; #define P_NONE 0 // 0 = kein Parity Bit #define P_EVEN 1 // 1 = gerade #define P_ODD 2 // 2 = ungerade #define P_SPACE 3 // 3 = immer 0 #define P_MARK 4 // 4 = immer 1 #define D_7BIT 0 // 7-Databits #define D_8BIT 1 // 8-Databits #define S_1BIT 0 // 1 Stopbit #define S_1_5BIT 1 // 1.5 Stopbits #define S_2BIT 2 // 2 Stopbits //***************************************************************************** //* //* ComInit //* //***************************************************************************** int ComInit() { return 1; } //***************************************************************************** //* //* ComExit //* //***************************************************************************** int ComExit() { int i; for(i=0;i<MAX_COM_PORTS;i++) { if(!cIsOpen[i])continue; ComClose(i); } return 1; } //***************************************************************************** //* //* ComOpen //* //***************************************************************************** // Öffnet eine serielle Verbindung // uNr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...) // iBaud : Ist die Bautrate // iParity : 0 = kein iParity Bit (P_NONE) // 1 = gerade (P_EVEN) // 2 = ungerade (P_ODD) // 3 = immer 0 (P_SPACE) // 4 = immer 1 (P_MARK) // iStopbits : 0 = Ein Stopbit (S_1BIT) // 1 = Zwei iStopbits (S_2BIT) // Bits : 0 = 8 Datenbits // 1 = 7 Datenbits // 7 = 7 Datenbits (D_7BIT) // 8 = 8 Datenbits (D_8BIT) // Ergibt 1 wenn eine Schnittstelle geöffnet wurde int ComOpen(unsigned uNr,int iBaud,int iParity,int iStopbits,int iDatabits,int iRs485) { struct serial_struct sData; struct termios sPortInfo; char cName[]="/dev/ttyS0"; int iHandle,i; if(uNr>=MAX_COM_PORTS)return 0; cName[0]+=uNr; iHandle=open(cName,O_RDWR|O_NONBLOCK|O_NOCTTY); // Device oeffnen if(iHandle<0)return 0; tcgetattr(iHandle, &sPortInfo); cfmakeraw(&sPortInfo); sPortInfo.c_cc[VMIN] = 0; sPortInfo.c_cc[VTIME]= 0; if(iStopbits) // Stopbits einstellen sPortInfo.c_cflag |= CSTOPB; else sPortInfo.c_cflag &= ~CSTOPB; sPortInfo.c_cflag &= ~CSIZE; // Datenbits einstellen sPortInfo.c_cflag |= (iDatabits&1)? CS7:CS8; switch(iParity) // Parity-Bits einstellen { case P_NONE: sPortInfo.c_cflag = sPortInfo.c_cflag & ~PARENB; break; case P_ODD : sPortInfo.c_cflag = sPortInfo.c_cflag | PARENB | PARODD; break; case P_EVEN: sPortInfo.c_cflag = (sPortInfo.c_cflag | PARENB) & ~PARODD; break; default: close(iHandle); return 0; } tcsetattr(iHandle,TCSANOW,&sPortInfo); for(i=0;i<MAX_SPEED;i++) { if(aTcSpeeds[i].iBaud==iBaud)break; } if(iBaud<MAX_SPEED) { errno=-EFAULT; close(iHandle); return 0; } ioctl(iHandle,TIOCGSERIAL,&sData); // Spezial-Baudraten löschen sData.flags &= ~ASYNC_SPD_MASK; ioctl(iHandle,TIOCSSERIAL,&sData); iBaud=aTcSpeeds[i].iCode; tcgetattr(iHandle,&sPortInfo); cfsetospeed(&sPortInfo, iBaud); cfsetispeed(&sPortInfo, iBaud); tcsetattr(iHandle,TCSANOW,&sPortInfo); i = TIOCM_RTS|TIOCM_DTR; // RTS DTR setzen ioctl(iHandle, TIOCMBIS,&i); iComHandle[uNr] = iHandle; cIsOpen [uNr] = 1; return 1; }