Use of serial tool PicoCOM and time stamp display under Ubuntu

PICOCOM

The serial port software under Ubuntu, besides CuteCOM, screen, MiniCOM, there is also a PicoCOM which is very similar to MiniCOM. Recently, in the process of debugging the CH340C serial port, it was found that only the connection Reset of PicoCOM can work normally, so it is recorded separately.

Install

On Ubuntu directly through sudo apt install picocomthe installation, the version is 3.1

use

connect and disconnect

Use 115200 baud rate to connect serial device /dev/ttyUSB0

picocom -b115200 /dev/ttyUSB0

There are two ways to disconnect

  • Ctrl+A, Ctrl+Q 退出, NO RESET
  • Ctrl+A , Ctrl+X to exit, RESET

During serial port communication, RTS (Ready To Send) will be at low level, and if RESET is disconnected when the serial port is disconnected, it will return to high level, and RESET will be performed by default.

When debugging STC MCU, it is often connected with a serial port to USB device with automatic programming, and the automatic programming mechanism of this device is to trigger the MCU to power off and restart by pulling down the RTS. When using this RTS-triggered device When programming and debugging, it is necessary to use the RESET mechanism flexibly.

  • When debugging, we don't want to restart automatically every time we connect to the MCU, so we should avoid RESET when disconnecting the serial port, keep RTS at low level, and use Ctrl+A Ctrl+Q to exit when disconnecting, which can avoid RESET
  • When programming, if RTS is still at low level, pulling down RTS is invalid, resulting in the failure to restart the MCU. So when programming, disconnect the serial port to RESET, let RTS return to high level, use Ctrl+A Ctrl + X exit

PS: This function works normally on picocom, but it does not work properly on minicom. After using Ctrl+A, Q to exit once, no matter whether you use Ctrl+A, X, or Ctrl+A, Q can no longer trigger RESET

show binary

When debugging serial port communication, sometimes you need to observe the binary output of the serial port. At this time, you need to print out the data in hexadecimal. In picocom, you need to use --imapthe parameter multi-option that can distinguish different types of values ​​for conversion. .

--imap <map> (input mappings)
<map> is a comma-separated list of one or more of ...

For example

picocom --imap spchex,tabhex,crhex,lfhex,nrmhex,8bithex -b 19200 /dev/ttyS0

Description of each parameter

  • spchex (map special chars (< 0x20 || 0x7f), excl. CR, LF, and TAB to hex)
  • tabhex (map TAB to hex)
  • crhex (map CR to hex)
  • lfhex (map LF to hex)
  • 8bithex (map chars with 8th-bit set to hex)
  • nrmhex (map normal ascii chars (0x20 <= c < 0x7f) to hex)

Secondary development: add timestamp

Time stamps are often used when debugging serial ports, for example, to observe whether the delay is correct. Although this time stamp is not accurate, it is still very convenient as a rough time stamp. minicom already supports time stamp output in newer versions, But there is no such function on picocom yet.

The advantage of open source software is that you can change it yourself if you are not comfortable with it. It is not troublesome to add timestamp output on picocom.

First export the code through the project warehouse https://github.com/npat-efault/picocommake , and directly compile and verify whether the environment is correct. If the compilation fails, first solve the compilation environment problem.

Then modify the code, the main modified parts are in picocom.c

The header file introduces sys/time.h, because the time value function will be used

#include <sys/time.h>

Add definition, n/N This parameter is used to switch/select the timestamp format

#define KEY_TIMESTAMP CKEY('n') /* show timestamp */

Add a field in the structure struct { … } opts int timestamp;to record timestamp options

Add key hints in help display

    fd_printf(STO, "*** [C-%c] : Toggle display timestamp\r\n",
              KEYC(KEY_TIMESTAMP));

Increase the corresponding button processing

    case KEY_TIMESTAMP:
        opts.timestamp = (opts.timestamp + 1) % 4;
        fd_printf(STO, "\r\n*** display timestamp, format:%d ***\r\n",
                  opts.timestamp);

In the output section, add the generation method of the timestamp, here will generate 4 display methods, 0: no display, 1: minute: second, 2: hour: minute: second, 3: year-month-day hour: minute: second

/* print leading timestamp */
void print_lead_str(void)
{
    
    
    struct timeval tv;
    struct tm lt = {
    
    0};
    char buff[32], buff2[64];

    gettimeofday(&tv, NULL);
    localtime_r(&(tv.tv_sec), &lt);

    switch (opts.timestamp) {
    
    
    case 3:
        strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", &lt);
        sprintf(buff2, "%s.%03ld ", buff, tv.tv_usec / 1000);
        write(STO, buff2, 24);
        break;
    case 2:
        strftime(buff, sizeof(buff), "%H:%M:%S", &lt);
        sprintf(buff2, "%s.%03ld ", buff, tv.tv_usec / 1000);
        write(STO, buff2, 13);
        break;
    case 1:
        strftime(buff, sizeof(buff), "%M:%S", &lt);
        sprintf(buff2, "%s.%03ld ", buff, tv.tv_usec / 1000);
        write(STO, buff2, 10);
        break;
    default:
        break;
    }
}

Add call to display

        if ( FD_ISSET(tty_fd, &rdset) ) {
    
    

            char buff_rd[TTY_RD_SZ];
            char buff_map[TTY_RD_SZ * M_MAXMAP];

            /* read from port */

            do {
    
    
                n = read(tty_fd, &buff_rd, sizeof(buff_rd));
            } while (n < 0 && errno == EINTR);
            if (n == 0) {
    
    
                fatal("read zero bytes from port");
            } else if ( n < 0 ) {
    
    
                if ( errno != EAGAIN && errno != EWOULDBLOCK )
                    fatal("read from port failed: %s", strerror(errno));
            } else {
    
    
                print_lead_str();                       //<--- 输出时间戳
                int i;
                char *bmp = &buff_map[0];
                if ( opts.log_filename )
                    if ( writen_ni(log_fd, buff_rd, n) < n )
                        fatal("write to logfile failed: %s", strerror(errno));
                for (i = 0; i < n; i++) {
    
    
                    bmp += do_map(bmp, opts.imap, buff_rd[i]);
                }
                n = bmp - buff_map;
                if ( writen_ni(STO, buff_map, n) < n )
                    fatal("write to stdout failed: %s", strerror(errno));
            }
        }

For detailed code changes, please refer to

https://github.com/IOsetting/picocom

In addition to adding the -N parameter to display the timestamp function, it also modified the default communication baud rate, changing 9600 to 115200, because it is basically 115200 now. makeIt can be used directly after running and compiling.

During the communication process, press Ctrl+A Ctrl+N to switch between different display formats in turn, or you can specify it directly at startup, for example

./picocom --imap nrmhex,8bithex /dev/ttyUSB0 -N3

reference

  • https://kaisenlinux.org/manpages/picocom.html

Guess you like

Origin blog.csdn.net/michaelchain/article/details/130672629