From owner-freebsd-questions@FreeBSD.ORG Sat Sep 16 10:38:28 2006 Return-Path: X-Original-To: freebsd-questions@freebsd.org Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A958D16A407 for ; Sat, 16 Sep 2006 10:38:28 +0000 (UTC) (envelope-from bug2bug@bug2bug.tk) Received: from ns.vega-int.ru (ns.vega-int.ru [62.148.228.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id BBB0E43D45 for ; Sat, 16 Sep 2006 10:38:27 +0000 (GMT) (envelope-from bug2bug@bug2bug.tk) Received: from localhost (localhost.localdomain [127.0.0.1]) by ns.vega-int.ru (Postfix) with ESMTP id 519A110004F for ; Sat, 16 Sep 2006 16:38:25 +0600 (YEKST) Received: from ns.vega-int.ru ([127.0.0.1]) by localhost (ns [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 08647-02 for ; Sat, 16 Sep 2006 16:38:21 +0600 (YEKST) Received: from [172.23.12.179] (unknown [172.23.12.179]) by ns.vega-int.ru (Postfix) with ESMTP id 4EA4E10004E for ; Sat, 16 Sep 2006 16:38:21 +0600 (YEKST) From: =?koi8-r?b?88XSx8XKIPPPwsvP?= To: freebsd-questions@freebsd.org Date: Sat, 16 Sep 2006 16:40:22 +0600 User-Agent: KMail/1.9.1 MIME-Version: 1.0 Content-Type: text/plain; charset="koi8-r" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200609161640.22782.bug2bug@bug2bug.tk> X-Virus-Scanned: by amavisd-new at vega-int.ru Subject: A question about programming RS-232 X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: bug2bug@bug2bug.tk List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 10:38:28 -0000 Andrew Falanga wrote: > I am by no means the worlds best serial programmer, but recently I have > done some work on this subject and I noticed one thing in the code sample > above that should be avoided. However, I'll give you what I saw in-line: > > > #include > > > #include > > #include > > #include > > > > int main(void) { > > int t = 0, num = 10, fd, iOut; char *ch; > > struct termios my_termios; > > ch = (char *)malloc(6); > > memset(ch, 250, 6); > > fd = open("/dev/cuad0", O_RDWR | O_NONBLOCK); > > Ok, great, we've opened our serial device. Unless you need this to be a > controlling terminal, you should open with open( "/dev/cuad0", O_RDWR | > O_NONBLOCK | O_NOCTTY ); Check with the open man page to make sure I've > given you the correct constant for opening as a non-controlling terminal. > > > printf("Opened com port\n"); > > > if(fd < 0) return 0; > > // tcflush(fd, TCIFLUSH); > > my_termios.c_cflag = CS8 | CLOCAL; > > if(cfsetspeed(&my_termios, B9600) < 0) return 0; > > if(tcsetattr(fd, TCSANOW, &my_termios) < 0) return 0; > > You've set the attributes you want to use in the structure you defined, > my_termios. However, you should call tcgetattr() before changing what you > want to change (and make sure you always turn things on as you have done > above with bitwise or). So, your code should look something like, > > // assume an open file descriptor named fd > struct termios my_termios; > > if( tcgetattr( fd, &my_termios ) < 0 ) { > fprintf( stderr, "error in getting termios properties\n" ); > return AN_ERROR; > } > > // turn on what you want > my_termios.c_cflag = CS8 | CLOCAL; > > if( tcsetattr( fd, &my_termios ) < 0 } { > fprintf( stderr, "error in setting new properties to serial port\n" ); > return AN_ERROR; > } > > > I don't know if this will solve your problems but I do know I read that you > should always get the current settings because the serial driver may use > certain bits and you don't want to turn them off. Also, if you're going to > return the port settings to the state before you took hold of it, make two > termios structures and stuff the original settings away to be restored upon > exit or close of the port. > > Lastly, here is a link to a serial programming guide that I found quite > helpful. The info is probably dated to some degree, but it is non the less > useful. > > http://www.easysw.com/~mike/serial/serial.html > > Andy I have corrected, what you say, but it doesn't work at all! The code I tryed: #include #include #include #include int main(void) { int t = 0, num = 10, fd, i, iOut; char *ch; struct termios my_termios; ch = (char *)malloc(6); memset(ch, 50, 6); fd = open("/dev/cuad0", O_RDWR | O_NOCTTY | O_NDELAY); fcntl(fd, F_SETFL, 0); printf("Opened com port\n"); if(fd < 0) return 0; if(tcgetattr(fd, &my_termios) < 0) return 0; printf("Got my_termios struct\n"); if(cfsetspeed(&my_termios, B9600) < 0) return 0; printf("Set speed B9600\n"); my_termios.c_cflag &= ~PARENB; my_termios.c_cflag &= ~CSTOPB; my_termios.c_cflag &= ~CSIZE; my_termios.c_cflag |= CS8; my_termios.c_cflag |= CLOCAL; my_termios.c_cflag |= CREAD; my_termios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); my_termios.c_oflag &= ~OPOST; if(tcsetattr(fd, TCSANOW, &my_termios) < 0) return 0; printf("Setting my_termios attr\n"); iOut = write(fd, ch, 6); if(iOut < 0) return 0; printf("Number of bytes = %d\n", iOut); printf("Writed %s!\n", ch); close(fd); printf("Closed!\n"); return 0; } After executing it writes: Opened com port Got my_termios struct Set speed B9600 Setting my_termios attr Number of bytes = 6 Writed 222222! Closed! But! No effect ;( I'm in shock! How can it work under Windows if it doesn't work in UNIX? May be I'm a lamer or I'm doing stupid things? But such code in Delphi using component TComPort works perfectly: library cportio; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses SysUtils, Classes, CPort, Forms, Windows, IniFiles; var Com: TComPort; const crlf: String = #10 + #13; const Name: String = 'Com'; const xPort: String = 'COM1'; const xDataBits: TDataBits = dbEight; const xStopBits: TStopBits = sbOneStopBit; const xParityBits: TParityBits = prNone; const xFlowControl: TFlowControl = fcNone; const xBaudRate: TBaudRate = br9600; {$R *.res} function WriteComPort(xData: Integer): Integer; stdcall; begin Com := TComPort.Create(Application); Com.Port := xPort; Com.DataBits := xDataBits; Com.StopBits := xStopBits; Com.Parity.Bits := xParityBits; Com.FlowControl.FlowControl := xFlowControl; Com.BaudRate := xBaudRate; Com.Open; Com.WriteStr(chr(xData)); Com.Close; Com.Free; WriteComPort := 1; end; exports WriteComPort; begin end.