linux-serial-test: add patch to fix serial setup handling

Add patch that restores user intent in serial setup handling. Upstream
commit 77320571e63c ignores user input when RS485 was pre-configured,
breaking loopback and flow-control tests.

This patch ensures RS485 can be explicitly controlled while still
respecting pre-existing configurations when appropriate.

Signed-off-by: Vitor Soares <vitor.soares@toradex.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
This commit is contained in:
Vitor Soares 2025-10-31 15:56:13 +00:00 committed by Khem Raj
parent 8d4b8287b8
commit f514bc1e89
2 changed files with 134 additions and 0 deletions

View File

@ -0,0 +1,133 @@
From 8d4f9a1a77f59eb3ed79267f58fac949835aebfc Mon Sep 17 00:00:00 2001
From: Vitor Soares <vitor.soares@toradex.com>
Date: Thu, 30 Oct 2025 14:52:57 +0000
Subject: [PATCH] Fix serial setup handling to respect user intent
Commit 77320571e63c ("Check if rs485 is already configured on the port")
attempted to respect RS485 settings already configured on the port (e.g.
via Device Tree). However, it unintentionally ignored user input,
causing issues such as:
- Inability to change delay settings
- Failure to explicitly disable RS485
- Broken UART loopback and RTS/CTS flow-control tests when RS485 was
pre-enabled
The original intent was valid for existing configurations (bare -q), but
the tool should prioritize user intent, especially in testing scenarios.
This update restores predictable, user-driven behavior:
- RS485 can be explicitly enabled, disabled, or reconfigured
- Current configurations are respected when appropriate
Upstream-Status: Submitted [https://github.com/cbrake/linux-serial-test/pull/68]
Fixes: 77320571e63c ("Check if rs485 is already configured on the port")
Signed-off-by: Vitor Soares <vitor.soares@toradex.com>
---
linux-serial-test.c | 48 ++++++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/linux-serial-test.c b/linux-serial-test.c
index 294f53882570..119bf58e663d 100644
--- a/linux-serial-test.c
+++ b/linux-serial-test.c
@@ -60,6 +60,7 @@ int _cl_no_tx_param = 0;
int _cl_rx_delay = 0;
int _cl_tx_delay = 0;
int _cl_tx_bytes = 0;
+int _cl_rs485 = 0;
int _cl_rs485_after_delay = -1;
int _cl_rs485_before_delay = 0;
int _cl_rs485_rts_after_send = 0;
@@ -315,7 +316,9 @@ static void display_help(void)
" -q, --rs485 Enable RS485 direction control on port, and set delay from when TX is\n"
" finished and RS485 driver enable is de-asserted. Delay is specified in\n"
" bit times. To optionally specify a delay from when the driver is enabled\n"
- " to start of TX use 'after_delay.before_delay' (-q 1.1)\n"
+ " to start of TX use 'after_delay.before_delay' (-q 1.1). If no value is\n"
+ " given, delay defaults to 0. Existing RS485 configuration is respected if\n"
+ " already enabled.\n"
" -Q, --rs485_rts Deassert RTS on send, assert after send. Omitting -Q inverts this logic.\n"
" -m, --no-modem Do not clobber against any modem lines.\n"
" -o, --tx-time Number of seconds to transmit for (defaults to 0, meaning no limit)\n"
@@ -335,7 +338,7 @@ static void process_options(int argc, char * argv[])
{
for (;;) {
int option_index = 0;
- static const char *short_options = "hb:p:d:D:TRsSy:z:cBertq:Qml:a:w:o:i:P:kKAI:O:W:Znf";
+ static const char *short_options = "hb:p:d:D:TRsSy:z:cBertq::Qml:a:w:o:i:P:kKAI:O:W:Znf";
static const struct option long_options[] = {
{"help", no_argument, 0, 0},
{"baud", required_argument, 0, 'b'},
@@ -359,7 +362,7 @@ static void process_options(int argc, char * argv[])
{"rx-delay", required_argument, 0, 'l'},
{"tx-delay", required_argument, 0, 'a'},
{"tx-bytes", required_argument, 0, 'w'},
- {"rs485", required_argument, 0, 'q'},
+ {"rs485", optional_argument, 0, 'q'},
{"rs485_rts", no_argument, 0, 'Q'},
{"no-modem", no_argument, 0, 'm'},
{"tx-time", required_argument, 0, 'o'},
@@ -467,8 +470,12 @@ static void process_options(int argc, char * argv[])
}
case 'q': {
char *endptr;
- _cl_rs485_after_delay = strtol(optarg, &endptr, 0);
- _cl_rs485_before_delay = strtol(endptr+1, &endptr, 0);
+ _cl_rs485 = 1;
+
+ if (optarg) {
+ _cl_rs485_after_delay = strtol(optarg, &endptr, 0);
+ _cl_rs485_before_delay = strtol(endptr+1, &endptr, 0);
+ }
break;
}
case 'Q':
@@ -707,15 +714,20 @@ static void setup_serial_port(int baud)
/* enable/disable rs485 direction control, first check if RS485 is supported */
if(ioctl(_fd, TIOCGRS485, &rs485) < 0) {
- if (_cl_rs485_after_delay >= 0) {
+ if (_cl_rs485) {
/* error could be because hardware is missing rs485 support so only print when actually trying to activate it */
perror("Error getting RS-485 mode");
}
} else {
- if (rs485.flags & SER_RS485_ENABLED) {
- printf("RS485 already enabled on port, ignoring delays if set\n");
- } else {
- if (_cl_rs485_after_delay >= 0) {
+ if (_cl_rs485) {
+ /* Skip reconfiguration if already enabled with default delays */
+ if ((_cl_rs485_after_delay < 0) && (rs485.flags & SER_RS485_ENABLED)) {
+ printf("RS485 already enabled on port with default settings\n");
+ } else {
+ /* Default to 0 if not specified */
+ if (_cl_rs485_after_delay < 0) {
+ _cl_rs485_after_delay = 0;
+ }
/* enable RS485 */
rs485.flags |= SER_RS485_ENABLED | SER_RS485_RX_DURING_TX |
(_cl_rs485_rts_after_send ? SER_RS485_RTS_AFTER_SEND : SER_RS485_RTS_ON_SEND);
@@ -725,14 +737,14 @@ static void setup_serial_port(int baud)
if(ioctl(_fd, TIOCSRS485, &rs485) < 0) {
perror("Error setting RS-485 mode");
}
- } else {
- /* disable RS485 */
- rs485.flags &= ~(SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND);
- rs485.delay_rts_after_send = 0;
- rs485.delay_rts_before_send = 0;
- if(ioctl(_fd, TIOCSRS485, &rs485) < 0) {
- perror("Error setting RS-232 mode");
- }
+ }
+ } else {
+ /* disable RS485 */
+ rs485.flags &= ~(SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND);
+ rs485.delay_rts_after_send = 0;
+ rs485.delay_rts_before_send = 0;
+ if(ioctl(_fd, TIOCSRS485, &rs485) < 0) {
+ perror("Error setting RS-232 mode");
}
}
}

View File

@ -6,6 +6,7 @@ LIC_FILES_CHKSUM = "file://LICENSES/MIT;md5=544799d0b492f119fa04641d1b8868ed"
SRC_URI = "git://github.com/cbrake/linux-serial-test.git;protocol=https;branch=master \
file://0001-linux-serial-test.c-fix-returned-error-code.patch \
file://0002-linux-serial-test.c-fix-potential-hang-in-while-loop.patch \
file://0001-Fix-serial-setup-handling-to-respect-user-intent.patch \
"
PV = "0+git"
SRCREV = "1a81f3c7be086ee01a9be8589a606426276c86d5"