mirror of
https://github.com/UzixLS/picocom.git
synced 2025-07-19 07:21:18 +03:00
Disable custom baudrate support at runtime (Linux)
If picocom is compiled *with* custom-baudrate support (USE_CUSTOM_BAUD) for Linux, then it uses a new set of ioctl's (TCGETS2 vs TCGETS, etc) to access the serial ports. This patch allows the custom baudrate support to be disabled at runtime (without recompiling), and picocom to switch to using the old ioctl's. To disable custom baudrate support (and switch back to the "old" ioctls) simply define the environment variable NO_CUSTOM_BAUD, before starting picocom. This applies only to Linux and, obviously, only when picocom has been compiled with custom baudrate support (USE_CUSTOM_BAUD).
This commit is contained in:
5
Makefile
5
Makefile
@ -49,7 +49,7 @@ linenoise-1.0/linenoise.o : linenoise-1.0/linenoise.c linenoise-1.0/linenoise.h
|
||||
#CPPFLAGS += -DNO_HELP
|
||||
|
||||
|
||||
OBJS += picocom.o term.o fdio.o split.o termios2.o custbaud_bsd.o
|
||||
OBJS += picocom.o term.o fdio.o split.o custbaud.o termios2.o custbaud_bsd.o
|
||||
picocom : $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
@ -59,6 +59,7 @@ split.o : split.c split.h
|
||||
fdio.o : fdio.c fdio.h
|
||||
termios2.o : termios2.c termios2.h termbits2.h custbaud.h
|
||||
custbaud_bsd.o : custbaud_bsd.c custbaud_bsd.h custbaud.h
|
||||
custbaud.o : custbaud.c custbaud.h
|
||||
|
||||
.c.o :
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
|
||||
@ -90,7 +91,7 @@ picocom.1.pdf : picocom.1
|
||||
clean:
|
||||
rm -f picocom.o term.o fdio.o split.o
|
||||
rm -f linenoise-1.0/linenoise.o
|
||||
rm -f termios2.o custbaud_bsd.o
|
||||
rm -f custbaud.o termios2.o custbaud_bsd.o
|
||||
rm -f *~
|
||||
rm -f \#*\#
|
||||
|
||||
|
42
README.md
42
README.md
@ -326,3 +326,45 @@ Some interesting points:
|
||||
|
||||
Again, this is only *one* possible setup. There are countless other
|
||||
variations and elaborations you can try. Be creative!
|
||||
|
||||
## Some notes on custom baudrate support
|
||||
|
||||
Custom baudrate support gives you the ability to set arbitrary
|
||||
baudrate values (like 1234, or 42000, etc) to a serial port, provided
|
||||
that the underlying driver can handle this. Since release 2.0, picocom
|
||||
can be compiled with custom baudrate support for some systems. Since
|
||||
release 3.1 picocom is compiled with custom baudrate support enabled
|
||||
by default on some systems (like Linux, kernels > 2.6, on ix86 and
|
||||
ix86_64, modern intel macs, and some other BSDs). In any case, you can
|
||||
explicitly ask for custom baudrate support to be enabled by compiling
|
||||
picocom like this:
|
||||
|
||||
CPPFLAGS=-DUSE_CUSTOM_BAUD make clean
|
||||
CPPFLAGS=-DUSE_CUSTOM_BAUD make
|
||||
|
||||
If custom baudrate support is not available for your system, the
|
||||
compilation will fail. Similarly, you can ask for custom baudrate
|
||||
support to be disabled by compiling like:
|
||||
|
||||
CPPFLAGS=-DNO_CUSTOM_BAUD make clean
|
||||
CPPFLAGS=-DNO_CUSTOM_BAUD make
|
||||
|
||||
When picocom is compiled with custom baudrate support on Linux, it
|
||||
uses a new set of ioctl's (TCGETS2, TCSETSF2 vs TCGETS, TCSETSF, etc)
|
||||
to access the serial ports. It is not impossible that some serial
|
||||
devices may not accept these new ioctl's (though they should). In
|
||||
order to be able to use picocom even with such devices, and without
|
||||
recompiling it, you can disable the custom baudrate support at
|
||||
runtime, and force picocom to use the "old" ioctls. To do this
|
||||
(starting with release 3.2) just define the environment variable
|
||||
`NO_CUSTOM_BAUD` before running picocom. Something like this:
|
||||
|
||||
NO_CUSTOM_BAUD=1 picocom ...
|
||||
|
||||
This only applies to Linux, and to picocom binaries that have been
|
||||
compiled with custom baudrate support.
|
||||
|
||||
To see if your binary has been compiled with custom baudrate support,
|
||||
and / or if it has detected the `NO_CUSTOM_BAUD` variable, run it with
|
||||
the **--help** option, and take a look at the first few lines of
|
||||
output.
|
||||
|
62
custbaud.c
Normal file
62
custbaud.c
Normal file
@ -0,0 +1,62 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* custbaud.c
|
||||
*
|
||||
* by Nick Patavalis (npat@efault.net)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "custbaud.h"
|
||||
|
||||
#ifndef USE_CUSTOM_BAUD
|
||||
|
||||
int use_custom_baud() { return 0; }
|
||||
|
||||
int cfsetispeed_custom(struct termios *tios, int speed) { errno = EINVAL; return -1; }
|
||||
int cfsetospeed_custom(struct termios *tios, int speed) { errno = EINVAL; return -1; }
|
||||
int cfgetispeed_custom(const struct termios *tios) { errno = EINVAL; return -1; }
|
||||
int cfgetospeed_custom(const struct termios *tios) { errno = EINVAL; return -1; }
|
||||
|
||||
#else /* USE_CUSTOM_BAUD */
|
||||
|
||||
int
|
||||
use_custom_baud()
|
||||
{
|
||||
#ifdef __linux__
|
||||
static int use = -1;
|
||||
if ( use < 0 )
|
||||
use = getenv("NO_CUSTOM_BAUD") ? 0 : 1;
|
||||
return use;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* of ndef USE_CUSTOM_BAUD */
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
@ -87,6 +87,14 @@
|
||||
|
||||
#endif /* of ndef NO_CUSTOM_BAUD else */
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
int use_custom_baud();
|
||||
int cfsetispeed_custom(struct termios *tios, int speed);
|
||||
int cfsetospeed_custom(struct termios *tios, int speed);
|
||||
int cfgetispeed_custom(const struct termios *tios);
|
||||
int cfgetospeed_custom(const struct termios *tios);
|
||||
|
||||
#endif /* CUSTBAUD_H */
|
||||
|
||||
/**************************************************************************/
|
||||
|
@ -71,11 +71,11 @@ int cfsetispeed_custom(struct termios *tiop, int speed) {
|
||||
return cfsetispeed(tiop, speed);
|
||||
}
|
||||
|
||||
int cfgetospeed_custom(struct termios *tiop) {
|
||||
int cfgetospeed_custom(const struct termios *tiop) {
|
||||
return cfgetospeed(tiop);
|
||||
}
|
||||
|
||||
int cfgetispeed_custom(struct termios *tiop) {
|
||||
int cfgetispeed_custom(const struct termios *tiop) {
|
||||
return cfgetispeed(tiop);
|
||||
}
|
||||
|
||||
|
@ -87,8 +87,8 @@
|
||||
|
||||
int cfsetospeed_custom(struct termios *tiop, int speed);
|
||||
int cfsetispeed_custom(struct termios *tiop, int speed);
|
||||
int cfgetospeed_custom(struct termios *tiop);
|
||||
int cfgetispeed_custom(struct termios *tiop);
|
||||
int cfgetospeed_custom(const struct termios *tiop);
|
||||
int cfgetispeed_custom(const struct termios *tiop);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -1626,6 +1626,8 @@ show_usage(char *name)
|
||||
#endif
|
||||
#ifdef USE_CUSTOM_BAUD
|
||||
printf(" USE_CUSTOM_BAUD is enabled\n");
|
||||
if ( ! use_custom_baud() )
|
||||
printf(" NO_CUSTOM_BAUD is set\n");
|
||||
#endif
|
||||
|
||||
printf("\nUsage is: %s [options] <tty port device>\n", s);
|
||||
|
36
term.c
36
term.c
@ -312,11 +312,10 @@ Bspeed(speed_t code)
|
||||
int
|
||||
term_baud_ok(int baud)
|
||||
{
|
||||
#ifndef USE_CUSTOM_BAUD
|
||||
return (Bcode(baud) != BNONE) ? 1 : 0;
|
||||
#else
|
||||
return (baud >= 0);
|
||||
#endif
|
||||
if ( use_custom_baud() )
|
||||
return (baud >= 0);
|
||||
else
|
||||
return (Bcode(baud) != BNONE) ? 1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
@ -817,7 +816,11 @@ term_set_baudrate (int fd, int baudrate)
|
||||
/* ispeed = 0, means same as ospeed (see POSIX) */
|
||||
cfsetispeed(&tio, B0);
|
||||
} else {
|
||||
#ifdef USE_CUSTOM_BAUD
|
||||
if ( ! use_custom_baud() ) {
|
||||
term_errno = TERM_EBAUD;
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
r = cfsetospeed_custom(&tio, baudrate);
|
||||
if ( r < 0 ) {
|
||||
term_errno = TERM_ESETOSPEED;
|
||||
@ -826,11 +829,6 @@ term_set_baudrate (int fd, int baudrate)
|
||||
}
|
||||
/* ispeed = 0, means same as ospeed (see POSIX) */
|
||||
cfsetispeed(&tio, B0);
|
||||
#else /* ! defined USE_CUSTOM_BAUD */
|
||||
term_errno = TERM_EBAUD;
|
||||
rval = -1;
|
||||
break;
|
||||
#endif /* of USE_CUSTOM_BAUD */
|
||||
}
|
||||
|
||||
term.nexttermios[i] = tio;
|
||||
@ -857,23 +855,23 @@ term_get_baudrate (int fd, int *ispeed)
|
||||
if ( ispeed ) {
|
||||
code = cfgetispeed(&term.currtermios[i]);
|
||||
*ispeed = Bspeed(code);
|
||||
#ifdef USE_CUSTOM_BAUD
|
||||
if ( *ispeed < 0 ) {
|
||||
*ispeed = cfgetispeed_custom(&term.currtermios[i]);
|
||||
if ( use_custom_baud() ) {
|
||||
if ( *ispeed < 0 ) {
|
||||
*ispeed = cfgetispeed_custom(&term.currtermios[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
code = cfgetospeed(&term.currtermios[i]);
|
||||
ospeed = Bspeed(code);
|
||||
if ( ospeed < 0 ) {
|
||||
#ifdef USE_CUSTOM_BAUD
|
||||
if ( ! use_custom_baud() ) {
|
||||
term_errno = TERM_EGETSPEED;
|
||||
break;
|
||||
}
|
||||
ospeed = cfgetospeed_custom(&term.currtermios[i]);
|
||||
if ( ospeed < 0 ) {
|
||||
term_errno = TERM_EGETSPEED;
|
||||
}
|
||||
#else
|
||||
term_errno = TERM_EGETSPEED;
|
||||
#endif
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
14
termios2.c
14
termios2.c
@ -59,6 +59,8 @@ tc2setattr(int fd, int optional_actions, const struct termios *tios)
|
||||
struct termios2 t2;
|
||||
int cmd;
|
||||
|
||||
if ( ! use_custom_baud() ) return tcsetattr(fd, optional_actions, tios);
|
||||
|
||||
switch (optional_actions) {
|
||||
case TCSANOW:
|
||||
cmd = IOCTL_SETS;
|
||||
@ -93,6 +95,8 @@ tc2getattr(int fd, struct termios *tios)
|
||||
size_t i;
|
||||
int r;
|
||||
|
||||
if ( ! use_custom_baud() ) return tcgetattr(fd, tios);
|
||||
|
||||
r = ioctl(fd, IOCTL_GETS, &t2);
|
||||
if (r < 0) return r;
|
||||
|
||||
@ -126,6 +130,8 @@ tc2getattr(int fd, struct termios *tios)
|
||||
int
|
||||
cf2setispeed(struct termios *tios, speed_t speed)
|
||||
{
|
||||
if ( ! use_custom_baud() ) return cfsetispeed(tios, speed);
|
||||
|
||||
if ( (speed & ~CBAUD) != 0
|
||||
&& (speed < B57600 || speed > __MAX_BAUD) ) {
|
||||
errno = EINVAL;
|
||||
@ -139,8 +145,10 @@ cf2setispeed(struct termios *tios, speed_t speed)
|
||||
}
|
||||
|
||||
speed_t
|
||||
cf2getispeed(struct termios *tios)
|
||||
cf2getispeed(const struct termios *tios)
|
||||
{
|
||||
if ( ! use_custom_baud() ) return cfgetispeed(tios);
|
||||
|
||||
return (tios->c_cflag >> IBSHIFT) & (CBAUD | CBAUDEX);
|
||||
}
|
||||
|
||||
@ -150,6 +158,8 @@ cf2getispeed(struct termios *tios)
|
||||
int
|
||||
cf2setospeed_custom(struct termios *tios, int speed)
|
||||
{
|
||||
if ( ! use_custom_baud() ) { errno = EINVAL; return -1; }
|
||||
|
||||
if ( speed <= 0 ) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@ -164,6 +174,8 @@ cf2setospeed_custom(struct termios *tios, int speed)
|
||||
int
|
||||
cf2setispeed_custom(struct termios *tios, int speed)
|
||||
{
|
||||
if ( ! use_custom_baud() ) { errno = EINVAL; return -1; }
|
||||
|
||||
if ( speed < 0 ) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
@ -55,12 +55,12 @@ int tc2getattr(int fd, struct termios *tios);
|
||||
* old one, supports different input and output speeds for a
|
||||
* device. The "speed" argument must be (and the return value will be)
|
||||
* one of the standard "Bxxxx" macros. If cf2getispeed() or
|
||||
* cfgetospeed(3) return CBAUDEX, then the respective baudrate is a
|
||||
* cfgetospeed(3) return BOTHER, then the respective baudrate is a
|
||||
* custom one. Read the "termios.c_ispeed" / "termios.c_ospeed" fields
|
||||
* to get the custom value (as a numeric speed). */
|
||||
|
||||
int cf2setispeed(struct termios *tios, speed_t speed);
|
||||
speed_t cf2getispeed(struct termios *tios);
|
||||
speed_t cf2getispeed(const struct termios *tios);
|
||||
|
||||
/* Use these to set *custom* input and output baudrates for a
|
||||
* device. The "speed" argument must be a numeric baudrate value
|
||||
|
27
termios2.txt
27
termios2.txt
@ -72,7 +72,8 @@ called: "the CIBAUD field"), together with field "c_ispeed" control
|
||||
the input baudrate.
|
||||
|
||||
BTW: Usually CBAUD & CBAUDEX == CBAUD. That is, CBAUDEX *is*
|
||||
one of the CBAUD bits.
|
||||
one of the CBAUD bits. See end of this file for more on the usual
|
||||
relationship of CBAUD, CBAUDEX, BOTHER
|
||||
|
||||
When issuing one of the TCSETS*2 ioctls, everything contained in the
|
||||
"termios2" structure is copied to a kernel-resident structure and the
|
||||
@ -147,3 +148,27 @@ baudrate values supplied by the serial drivers can be seen in file
|
||||
"tty_termios_encode_baud_rate()" which is what the serial drivers call
|
||||
to notify the kernel about the effective baudrate.
|
||||
|
||||
|
||||
Baud-codes, CBAUD, CBAUDEX, and BOTHER
|
||||
--------------------------------------
|
||||
|
||||
CBAUD = 0010017 ---> 0001 0000 0000 1111 mask
|
||||
CBUADEX = 0010000 ---> 0001 0000 0000 0000 extender bit
|
||||
BOTHER = 0010000 ---> 0001 0000 0000 0000 a reserved code
|
||||
|
||||
Usually CBAUD includes CBAUDEX. In any case the mask is always CBAUD &
|
||||
CBAUDEX (which is usually == CBAUD)
|
||||
|
||||
Basic codes (Bxxx & CBAUDEX == 0)
|
||||
|
||||
B0 > ---0 ---- ---- 0000
|
||||
B50 > ---0 ---- ---- 0001
|
||||
... 16 in total ...
|
||||
B38400 > ---0 ---- ---- 1111
|
||||
|
||||
Extended codes (Bxxx & CBAUDEX == 1)
|
||||
|
||||
CBAUDEX / BOTHER > ---1 ---- ---- 0000
|
||||
B57600 > ---1 ---- ---- 0001
|
||||
... 16 in total ...
|
||||
B4000000 > ---1 ---- ---- 1111
|
||||
|
Reference in New Issue
Block a user