Serial port /dev/cuau0 setup problems

Hi,

Am working on a project using serial line comms to remote control a radio receiver. That has an rs232 interface at 4800 bauds. Have written some code to drive it, but neither the cfsetispeed or cfsetospeed are setting the baud rate. Using an old protocol analyser, can see that the code is working, sending, receiving, no errors, with a loopback tx to rx on the interface cable, but at the default 9600 bauds, not 4800. Digging around a bit, the Bxxxx baud rate definitions would normally be in termios.h, but are not, and it's not clear where they are defined. The /dev/cuau0 serial port had a lock file, deleted, thinking that it may have an effect, but the default 9600 baud rate stubbornly remains. Can show the code, if that helps, but not flagging up any errors from the various system calls within the open function.. Any ideas appreciated, with thanks ?.
 
Do what covacat says. From uart(4):
Code:
Special Devices
     The uart driver also supports an initial-state and a lock-state control
     device for each of the callin and the callout "data" devices.  The
     termios settings of a data device are copied from those of the
     corresponding initial-state device on first opens and are not inherited
     from previous opens.  Use stty(1) in the normal way on the initial-state
     devices to program initial termios states suitable for your setup.
...
FILES
     /dev/ttyu?       for callin ports
     /dev/ttyu?.init
     /dev/ttyu?.lock  corresponding callin initial-state and lock-state
                      devices

     /dev/cuau?       for callout ports
     /dev/cuau?.init
     /dev/cuau?.lock  corresponding callout initial-state and lock-state
                      devices
 
Also, in case the OP is using a usb serial adapter instead of the built in serial port, the device files have an 'U' instead of 'u' before the number.
Like so
Code:
root@kg-core2:~ # ll /dev/*U?
crw-rw----  1 uucp dialer 0x22e Oct  5 20:14 /dev/cuaU0
crw-------  1 root wheel  0x22b Oct  4 19:20 /dev/ttyU0
 
Thanks, tried minicom, terminal emulator, and that could set the baud rate to other than 9600, and checked out ok. Then, played with stty, which reports 9600. Ran minicom again after that, and it now thinks it has a baud rate of zero. Will accept baud rate changes, but still reports zero on the status line. Code fails to work now as well, probably also has the zero baud rate for some reason.

Not using usb serial adapter, real serial port at /dev/cuau0, which normally works fine with minicom.

Seems to be conflicting setups, perhaps a config file somewhere that i'm not aware of ?.

Chris
 
Just tried this:

stty -f /dev/cuau0 speed 9600
stty -f /dev/cuau0.init speed 9600

Minicom still reports 0 baud rate, so it looks like the serial port is not being setup at all, though minicom would setup and verify 4800 earlier. Work with minicom is normally at 9600, perhaps the default, so that did work ok.

Machine is a dl380 G8, but perhaps I need to try a different platform, with different serial port hardware, as this is not working ?.

Chris
 
Thanks, that reports 9600, but isn't. Don't want to reboot the system, but is there a process for the serial prt, that can be restarted to reinit ?.
 
covecat

Here's the output from stty -a -f /dev/cuau0

speed 9600 baud; 0 rows; 0 columns;
lflags: -icanon -isig -iexten -echo echoe -echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo
-extproc
iflags: -istrip -icrnl -inlcr -igncr -ixon -ixoff ixany imaxbel -ignbrk
-brkint -inpck -ignpar -parmrk iutf8
oflags: -opost onlcr -ocrnl tab0 -onocr -onlret
cflags: cread cs5 parenb parodd hupcl clocal cstopb crtscts dsrflow
dtrflow mdmbuf -rtsdtr
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
eol2 = <undef>; erase = ^?; erase2 = ^H; intr = ^C; kill = ^U;
lnext = ^V; min = 0; quit = ^\; reprint = ^R; start = ^Q;
status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;

Also on a laptop with freebsd 15, what looks like the same message content, but minicom shows a baud rate of 9600, which is correct, as far as I can see. Somethng broken in one of the layers. Wonder if there are any systemctl parameters that affect that.

Phishfry

Thanks, Will give that a read through.
 
this looks set to hardware flow control
my cflags look like this (a not connected port on a dl380 g7)
cflags: cread cs8 -parenb -parodd hupcl clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
"modern" serial adapters like the usb ones have no flowcontrol only rx / tx and ground.
anyway cs5 is unusual
 
cs5 does look odd, 5 bits ?. So where does the system pick up and set the cuau0 default parameters on boot ?. Has to be a file somewhere that defines that.
 
try this
it's the output of stty -ag on my box
sh:
stty gfmt1:cflag=cb00:iflag=2b02:lflag=5cb:oflag=3:discard=f:dsusp=19:eof=4:eol=ff:eol2=ff:erase=7f:erase2=8:intr=3:kill=15:lnext=16:min=1:quit=1c:reprint=12:start=11:status=14:stop=13:susp=1a:time=0:werase=17:ispeed=4800:ospeed=4800 < /dev/cuau0.init
 
So where does the system pick up and set the cuau0 default parameters on boot ?. Has to be a file somewhere that defines that.
AFAIK nothing - or whatever the device driver does initially. All the persistent settings you want can be set via (for example) "stty -f /etc/cuau0.init ..."
 
Found elsewhere, make line sane:

stty -f "/dev/cuau0" 9600 cs8 -cstopb -parenb -ixon -ixoff -crtscts

Which did not report an error.

Then tried the stty -ag, and get this:

gfmt1:cflag=4b00:iflag=6b02:lflag=5cb:oflag=3:discard=f:dsusp=19:eof=4:eol=ff:eol2=ff:erase=7f:erase2=8:intr=3:kill=15:lnext=16:min=1:quit=1c:reprint=12:start=11:status=14:stop=13:susp=1a:time=0:werase=17:ispeed=9600:ospeed=9600

Minicom still reports a baud rate of zero, 0

Looks like something seriously wrong with the serial device code somewhere, as nothing works as expected. Have an old Sun Sparc system running FreeBsd 11, and will try to fire that up later, build the code there, and see if that works. Only other option is to try it on Linux, ughh, but will seem like sleeping with the enemy :-).
 
The Bxxxx definitions are indeed found in termios.h via sys/_termios.h. What do the following commands return?

Code:
grep console /boot/loader.conf
grep ^ttyu /etc/ttys
fstat /dev/cuau0 /dev/ttyu0
stty -a < /dev/cuau0.init

And seeing the code could be useful.
 
Here's the code that does the open:-

/* Open tty Line */
/* ------------- */
STATUS eTtyOpen (TTY_INFO *psTtyInfo) { /* Open in raw mode, not cannonical */

STATUS eStatus = FAIL;
psTtyInfo -> TtyStatus = TTY_OK;

struct termios sTerm;

if ((psTtyInfo -> s16DevHandle = open ((char *) psTtyInfo -> pu8TtyId, O_RDWR | O_NONBLOCK | O_FSYNC)) < 0) { /* Open for r/w */
psTtyInfo -> TtyStatus = TTY_OPNFAL; /* Fail */
}
else if (tcgetattr (psTtyInfo -> s16DevHandle, &sTerm) < 0) { /* Get current attributes */
psTtyInfo -> TtyStatus = TTY_GETATT; /* Fail */
}
else if (cfsetispeed (&sTerm, psTtyInfo -> stBaudRate) < 0) { /* Set tx baud rate, eg: B9600 */
psTtyInfo -> TtyStatus = TTY_SETTXB;
}
else if (cfsetospeed (&sTerm, psTtyInfo -> stBaudRate) < 0) { /* and rx baud rate */
psTtyInfo -> TtyStatus = TTY_SETRXB;
}
else {
sTerm.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); /* Echo, canonical, processing, signal, all off */

sTerm.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); /* Break, cr2nl, parity, strip bit 8, all off */

sTerm.c_cflag &= ~(CSIZE | PARENB);
sTerm.c_cflag |= ~(CREAD | HUPCL | CLOCAL | CS8); /* Enable rx, lower on close, local line, 8 bit char */

sTerm.c_oflag &= ~(OPOST); /* Post processing off */

sTerm.c_cc[VMIN] = 0;
sTerm.c_cc[VTIME] = 0;

if (tcsetattr (psTtyInfo -> s16DevHandle, TCSANOW, &sTerm) < 0) { /* Set attributes */
psTtyInfo -> TtyStatus = TTY_SETATT; /* Fail */
}
}

if (psTtyInfo -> TtyStatus == TTY_OK) { /* If no errors */
eStatus = OK;
}

return eStatus;
}

and the interface structure for that module:-

typedef struct {
U8 *pu8TtyId; /* Path and id string eg: "/dev/tty0" */
speed_t stBaudRate; /* Baud rate, common for tx and rx */
U8 *pu8TxBuffer; /* Transmit buffer */
U16 u16TxLength; /* Tx buffer size */
U8 *pu8RxBuffer; /* Receive buffer */
U16 u16RxLength; /* Receive buffer size */
U16 u16RxSize; /* Returned number of bytes */
TTY_CMD eTtyCommand; /* Command, open, write, read, close etc */
U16 u16PollCount; /* Poll for data, count * 10mS, timeout */
S16 s16DevHandle; /* Opened device handle */
TTY_STAT TtyStatus; /* Returned fault status */
} TTY_INFO;

Formatting lost...
 
C:
    sTerm.c_cflag |= ~(CREAD | HUPCL | CLOCAL | CS8);
should be
C:
    sTerm.c_cflag |= (CREAD | HUPCL | CLOCAL | CS8);
Also check the speed actually applied after the call to tcsetattr(3), as it may return 0 even if some of the changes are not applied.
In my experience, Linux is more forgiving when it comes to serial port programming. I have seen incorrect code that worked on Linux but not on FreeBSD or macOS.
 
Back
Top