From owner-freebsd-hackers@FreeBSD.ORG Sat Aug 14 17:30:58 2010 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E1E47106566B for ; Sat, 14 Aug 2010 17:30:58 +0000 (UTC) (envelope-from prt@prt.org) Received: from smtp5.uk.umis.net (smtp5.uk.umis.net [217.65.166.40]) by mx1.freebsd.org (Postfix) with ESMTP id ACA968FC12 for ; Sat, 14 Aug 2010 17:30:58 +0000 (UTC) Received: from kate.prtsystems.ltd.uk ([217.65.165.35]) by smtp5.uk.umis.net with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.63 (FreeBSD)) (envelope-from ) id 1OkKZN-000ISz-4p for freebsd-hackers@freebsd.org; Sat, 14 Aug 2010 17:30:57 +0000 Message-ID: <4C66D2CF.9040408@prt.org> Date: Sat, 14 Aug 2010 18:30:55 +0100 From: Paul Thornton User-Agent: Thunderbird 2.0.0.24 (Windows/20100228) MIME-Version: 1.0 To: freebsd-hackers@freebsd.org X-Enigmail-Version: 0.96.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Problem detecting and reacting to serial break X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Aug 2010 17:30:59 -0000 Hi, I'm working on a small piece of code that reads a data stream from the serial port, putting it into a buffer for processing later - for those interested, it is receiving DMX512 lighting control data - but I'm having trouble with the detection of a break condition on the serial line. I'd appreciate any suggestions from anyone. I'm using 8.0-RELEASE with uftdi and ucom driving the serial port. The format of this data is very simple - a break is sent, followed by 513 bytes of useful information; then after some arbitrary delay another break, and the next 513 bytes. So, I think, easy to do this - just wait for a break and read away. My problem is that despite setting the port up (as I think) correctly, the break seems to be ignored at a driver level and it appears as data byte of 0x00 (what I'd expect to see if IGNBRK was set). This is no good as I have no way to know where I am in the chunk of 513 bytes of data, so can't synchronize at all. I have the following code setting up my serial port: tcgetattr(fd, &options); printf("before: c_iflag=%x c_oflag=%x c_cflag=%x c_lflag=%x\n", options.c_iflag, options.c_oflag, options.c_cflag, options.c_lflag); options.c_iflag = (BRKINT | IGNPAR); options.c_oflag = 0; options.c_cflag = (CLOCAL | CREAD | CS8 | CSTOPB); options.c_lflag = 0; options.c_cc[VMIN] = 513; options.c_cc[VTIME] = 0; if (cfsetispeed(&options, BAUDRATE) < 0) { perror("cfsetispeed"); exit(1); } if (cfsetospeed(&options, BAUDRATE) < 0) { perror("cfsetospeed"); exit(1); } if (tcsetattr(fd, TCSANOW, &options) < 0) { perror("tcsetattr"); exit(1); } /* debug test - did anything change? */ tcgetattr(fd, &options); printf("after: c_iflag=%x c_oflag=%x c_cflag=%x c_lflag=%x\n", options.c_iflag, options.c_oflag, options.c_cflag, options.c_lflag); The debug output shows my set is doing what I expect it to: before: c_iflag=2005 c_oflag=3 c_cflag=cf00 c_lflag=443 after: c_iflag=6 c_oflag=0 c_cflag=8f00 c_lflag=0 So according to the documentation, the effect of the break should be to flush the input and output buffers, and send a SIGINT to my process. The buffer doesn't seem to get flushed, and I don't get sent the SIGINT. The data I'm getting in my buffer is valid, apart from the fact that I can't tell where byte 1 is - and every time I run the test program the location of byte 1 changes arbitrarily depending on what was in the receive buffer. Have I missed something here, or is there any other way that I can detect the presence of the break out-of-band? I cannot make any assumptions about the 513 bytes that I'm receiving and any combination of data may be present in there. Many thanks, Paul.