1
0
mirror of https://github.com/UzixLS/picocom.git synced 2025-07-19 07:21:18 +03:00

Merge branch 'master' into rfc2217

(Disable custom-baudrate support at runtime for Linux)
This commit is contained in:
Nick Patavalis
2018-02-20 16:14:32 +02:00
11 changed files with 180 additions and 27 deletions

View File

@ -54,7 +54,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)
@ -64,6 +64,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 $<
@ -95,7 +96,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 tn2217.o
rm -f *~
rm -f \#*\#

View File

@ -326,3 +326,47 @@ 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 x86 and
x86_64, modern Intel Macs, and some 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
(or you can comment in or out the respective lines in the Makefile)
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 systems or some serial devices may not accept these new ioctl's
(though they should). In order to be able to use picocom even in this
case, 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
View 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:
*/

View File

@ -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 */
/**************************************************************************/

View File

@ -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);
}

View File

@ -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);
/***************************************************************************/

View File

@ -1635,6 +1635,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
#ifdef USE_RFC2217
printf(" USE_RFC2217 is enabled\n");

37
term.c
View File

@ -445,11 +445,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
@ -964,7 +963,11 @@ tios_set_baudrate (struct termios *tios, int baudrate)
/* ispeed = 0, means same as ospeed */
cfsetispeed(&ttios, B0);
} else {
#ifdef USE_CUSTOM_BAUD
if ( ! use_custom_baud() ) {
term_errno = TERM_EBAUD;
rval = -1;
break;
}
r = cfsetospeed_custom(&ttios, baudrate);
if ( r < 0 ) {
term_errno = TERM_ESETOSPEED;
@ -973,11 +976,6 @@ tios_set_baudrate (struct termios *tios, int baudrate)
}
/* ispeed = 0, means same as ospeed (see POSIX) */
cfsetispeed(&ttios, B0);
#else /* ! defined USE_CUSTOM_BAUD */
term_errno = TERM_EBAUD;
rval = -1;
break;
#endif /* of USE_CUSTOM_BAUD */
}
*tios = ttios;
} while (0);
@ -1023,23 +1021,24 @@ tios_get_baudrate(const struct termios *tios, int *ispeed)
if ( ispeed ) {
code = cfgetispeed(tios);
*ispeed = Bspeed(code);
#ifdef USE_CUSTOM_BAUD
if ( *ispeed < 0 ) {
*ispeed = cfgetispeed_custom(tios);
if ( use_custom_baud() ) {
if ( *ispeed < 0 ) {
*ispeed = cfgetispeed_custom(tios);
}
}
#endif
}
code = cfgetospeed(tios);
ospeed = Bspeed(code);
if ( ospeed < 0 ) {
#ifdef USE_CUSTOM_BAUD
if ( ! use_custom_baud() ) {
term_errno = TERM_EGETSPEED;
return ospeed;
}
ospeed = cfgetospeed_custom(tios);
if ( ospeed < 0 ) {
term_errno = TERM_EGETSPEED;
return ospeed;
}
#else
term_errno = TERM_EGETSPEED;
#endif
}
return ospeed;

View File

@ -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;
@ -141,6 +147,8 @@ cf2setispeed(struct termios *tios, speed_t speed)
speed_t
cf2getispeed(const struct termios *tios)
{
if ( ! use_custom_baud() ) return cfgetispeed(tios);
return (tios->c_cflag >> IBSHIFT) & (CBAUD | CBAUDEX);
}
@ -150,6 +158,8 @@ cf2getispeed(const 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;

View File

@ -55,7 +55,7 @@ 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). */

View File

@ -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