Author Topic: Linux, how to set the (uart) RTS to a default value?  (Read 1459 times)

0 Members and 1 Guest are viewing this topic.

Online DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Linux, how to set the (uart) RTS to a default value?
« on: March 23, 2021, 04:54:01 pm »
I am developing a board where the RS232's RTS signal is used to force a reset to the MPU in order to upload the code.

I am using a MAX232 chip for the { RX, TX, RTS} signals

RX_232 ---MAX232--- RX_TTL
TX_232 ---MAX232--- TX_TTL
RTS_232 ---MAX232--- RTS_TTL -----------> N-MOS ---> /Reset

Measuring the volt at the RTS_TTL pin, I see it's
0V during a Minicom session
5V on the Linux bash, before launching Minicom

So this causes the target to have unwanted resets.

I can hack Minicom and invert the logic, but I'd prefer to modify the Linux behavior in order to have the same behavior of Minicom for the RTS signal.

How to do it? Should I have to hack the RS232 kernel module? Or is there something I can do in user-space.


Thanks  :D


edit: mistake fixed
RTS and DTR are output pins,
DCD and CTS are input pins and can only be read.
« Last Edit: March 23, 2021, 04:59:28 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6173
  • Country: fi
    • My home page and email address
Re: Linux, how to set the (uart) RTS to a default value?
« Reply #1 on: March 23, 2021, 05:19:48 pm »
It's standard termios behaviour.

I'm not perfectly clear on the signal logic you need (RTS low or high), but hangup is often used for this:
    stty -F device speed 0
(see man 1 stty for the stty manual page).

If you need a particular pattern or way for request-to-send (RTS) to be de-asserted/low/negative, you might need to write a tiny C program that opens the serial device, sets proper termios settings (in particular, .c_iflag &= ~(IXON | IXOFF) and .c_cflag |= CRTSCTS), and calls tcflow(devfd, TCIOFF).

Either way, these can then be run at init time, or by udev when the device providing the port is connected (as opposed to a device being connected to the serial port).
 
The following users thanked this post: DiTBho

Online DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Linux, how to set the (uart) RTS to a default value?
« Reply #2 on: March 23, 2021, 05:25:42 pm »
Thanks!

I was a bit worried due to what is reported here  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Linux, how to set the (uart) RTS to a default value?
« Reply #3 on: March 23, 2021, 05:46:14 pm »
I have a second board where I am using the DTR signal.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6173
  • Country: fi
    • My home page and email address
Re: Linux, how to set the (uart) RTS to a default value?
« Reply #4 on: March 23, 2021, 07:25:29 pm »
If one wanted to patch this, a proper patch would add a device attribute (auto-DTR) and a driver attribute (default-DTR), so that a sysadmin can control this.  For example, for serial core, it would mean an added if check in drivers/tty/serial/serial_core.c:uart_dtr_rts().  For usb-serial, in drivers/usb/serial/usb-serial.c:serial_port_dtr_rts().

However, you can also use a simple C program I roughly described.  (Let me know if you want a real-world example; this is simple enough to make into a fully static binary using freestanding C.)  You may wish to use the TIOCMBIS/TIOCMIC tty ioctls, too.

Essentially, the Linux assert-DTR logic is based on the TTY_PORT_INITIALIZED bit (in the iflags member of the relevant struct tty_port structure); see drivers/tty/tty_port.c:tty_port_open().  It gets set on the first open() of the device, and is cleared on shutdown.  Shutdown occurs on system suspend, and whenever the last open descriptor to the device is closed; so, if that minimal helper program just keeps the descriptor open, it can completely control the serial port state.  Even the termios structure can be locked using TIOCSLCKTRMIOS ioctl.

So no, kernel modification is not necessary, although I admit that in this particular case making the behaviour tunable would be preferable.  If one wishes to construct such a patch and send it upstream to LKML, one should remember that the behaviour control bit should be in the TTY structure, whereas the default can be driver-specific.
 
The following users thanked this post: DiTBho

Online DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Linux, how to set the (uart) RTS to a default value?
« Reply #5 on: March 24, 2021, 10:32:37 am »
I didn't have more time than a long coffee break (30 min), so I wildly hacked the serial kernel module kernel-v2.6.39/drivers/tty/serial/serial_core.c and removed all the DTR and RTS handling.

Recompiled, not the kerenl doesn't touch the DTR and RTS signal, and everything is done in userspace. So my uploader took can correctly reset the target, send the firmware, and when Minicom is executed (without any flow-control) it doesn't force further (unwanted) resets.

A dirty job for now, but it works  :D

(I will move the patch to kernel v4.11, and I will clean it a bit)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf