Skip to content

modbus: serial: Allow custom stop-bit settings in server mode#87484

Merged
nashif merged 1 commit intozephyrproject-rtos:mainfrom
msalau:modbus-allow-stop-bits-configuration-in-server-mode
Jun 10, 2025
Merged

modbus: serial: Allow custom stop-bit settings in server mode#87484
nashif merged 1 commit intozephyrproject-rtos:mainfrom
msalau:modbus-allow-stop-bits-configuration-in-server-mode

Conversation

@msalau
Copy link
Contributor

@msalau msalau commented Mar 21, 2025

A Modbus server should be able to operate with the same settings as a client. Stop-bits -is the only setting not available in server mode.

The change makes it possible to override default stop-bits settings in backwards compatible way. The feature is disabled by default.

help
Enable function code 08 Diagnostic support

config MODBUS_STOP_BITS_IN_SERVER_MODE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Modbus server should be able to operate with the same settings as a
client.

Why should it?

Stop-bits -is the only setting not available in server mode.

Because the RTU format is always 11 bits. There is either parity + stop or stop + stop. The client only supports this to communicate with non-compliant server devices, introduced in #40558.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @jfischer-no
Thank you for feedback!
Yes, I'm fully aware that 8N1 is not compliant with the specification but there are devices on the market that use exactly this format.
Right now the Modbus subsystem can talk to a non-compliant server device as a client but can't act as a non-compliant server. So we can't create a server device that may be added to an existing non-compliant bus.
This is exactly my case: an existing bus that works at 9600 8N1 and I need to add another server to it without changing the communication format.

May be a better description of the config option is needed to highlight that this options is not compliant with the specification and should be used with caution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

understood, I am fine with

config MODBUS_NONCOMPLIANT_RTU_MODE
	bool "Non-compliant RTU server mode"
	depends on MODBUS_SERVER && MODBUS_SERIAL
	help
	  Allow non-compliant stop and parity bit settings.

depends on MODBUS_SERVER
depends on MODBUS_SERIAL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depends on MODBUS_SERVER && MODBUS_SERIAL

help
Enable function code 08 Diagnostic support

config MODBUS_STOP_BITS_IN_SERVER_MODE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

understood, I am fine with

config MODBUS_NONCOMPLIANT_RTU_MODE
	bool "Non-compliant RTU server mode"
	depends on MODBUS_SERVER && MODBUS_SERIAL
	help
	  Allow non-compliant stop and parity bit settings.

@msalau msalau force-pushed the modbus-allow-stop-bits-configuration-in-server-mode branch from 2ede2c7 to 5468698 Compare April 14, 2025 07:39
@msalau
Copy link
Contributor Author

msalau commented Apr 14, 2025

Hello @jfischer-no
Thank you for feedback. I've updated the change according to your comment.
I've renamed the option from MODBUS_NONCOMPLIANT_RTU_MODE to MODBUS_NONCOMPLIANT_SERIAL_SERVER_MODE since it affects not just RTU but ASCII also.

What about renaming struct modbus_serial_param::stop_bits_client into stop_bits and making non-compliant stop-bit configuration disabled by default for both clients and servers?
The current implementation allows non-compliant stop-bits configuration at all times for clients.

I.e.:
modbus/Kconfig:

config MODBUS_NONCOMPLIANT_SERIAL_MODE
	bool "Non-compliant serial mode"
	depends on MODBUS_SERIAL
	help
	  Allow non-compliant stop and parity bit settings.

modbus/modbus.h:

/**
 * @brief Modbus serial line parameter
 */
struct modbus_serial_param {
	/** Baudrate of the serial line */
	uint32_t baud;
	/** parity UART's parity setting:
	 *    UART_CFG_PARITY_NONE,
	 *    UART_CFG_PARITY_EVEN,
	 *    UART_CFG_PARITY_ODD
	 */
	enum uart_config_parity parity;
-	/** stop_bits_client UART's stop bits setting if in client mode:
+	/** stop_bits UART's stop bits setting:
	 *    UART_CFG_STOP_BITS_0_5,
	 *    UART_CFG_STOP_BITS_1,
	 *    UART_CFG_STOP_BITS_1_5,
	 *    UART_CFG_STOP_BITS_2,
	 */
-	enum uart_config_stop_bits stop_bits_client;
+	enum uart_config_stop_bits stop_bits;
};

modbus/modbus_serial.c:

-	if (ctx->client || IS_ENABLED(MODBUS_NONCOMPLIANT_SERIAL_SERVER_MODE)) {
+ 	if (IS_ENABLED(CONFIG_MODBUS_NONCOMPLIANT_SERIAL_MODE)) {
		/* Allow custom stop bit settings */
-		switch (param->serial.stop_bits_client) {
+		switch (param->serial.stop_bits) {
		case UART_CFG_STOP_BITS_0_5:
		case UART_CFG_STOP_BITS_1:
		case UART_CFG_STOP_BITS_1_5:
		case UART_CFG_STOP_BITS_2:
			uart_cfg.stop_bits = param->serial.stop_bits;
			break;
		default:
			return -EINVAL;
		}
	}

This will require some migration effort for existing applications but will explicitly enable non-compliant mode for both clients and servers.
For compile-time validation of applications the stop_bits field may be disabled using #ifdef..#endif

@msalau msalau force-pushed the modbus-allow-stop-bits-configuration-in-server-mode branch 2 times, most recently from 89a92d8 to 99e29e7 Compare April 14, 2025 08:20
@msalau msalau requested a review from jfischer-no April 14, 2025 10:31
@jfischer-no
Copy link
Contributor

Hello @jfischer-no Thank you for feedback. I've updated the change according to your comment. I've renamed the option from MODBUS_NONCOMPLIANT_RTU_MODE to MODBUS_NONCOMPLIANT_SERIAL_SERVER_MODE since it affects not just RTU but ASCII also.

What about renaming struct modbus_serial_param::stop_bits_client into stop_bits and making non-compliant stop-bit configuration disabled by default for both clients and servers? The current implementation allows non-compliant stop-bits configuration at all times for clients.

I.e.: modbus/Kconfig:

config MODBUS_NONCOMPLIANT_SERIAL_MODE
	bool "Non-compliant serial mode"
	depends on MODBUS_SERIAL
	help
	  Allow non-compliant stop and parity bit settings.

Yes, that is event better.

@msalau msalau force-pushed the modbus-allow-stop-bits-configuration-in-server-mode branch from 99e29e7 to 7479f2c Compare May 22, 2025 15:19
@github-actions github-actions bot added the area: Samples Samples label May 22, 2025
@github-actions github-actions bot requested review from kartben and nashif May 22, 2025 15:20
@msalau msalau force-pushed the modbus-allow-stop-bits-configuration-in-server-mode branch from 7479f2c to 086dde0 Compare May 22, 2025 15:21
The mode is activated by the CONFIG_MODBUS_NONCOMPLIANT_SERIAL_MODE option
and allows any stop-bit setting for the serial port.

Signed-off-by: Maksim Salau <msalau@iotecha.com>
@msalau msalau force-pushed the modbus-allow-stop-bits-configuration-in-server-mode branch from 086dde0 to eb289d3 Compare May 22, 2025 16:12
@github-actions github-actions bot added the area: Sensors Sensors label May 22, 2025
@sonarqubecloud
Copy link

Copy link
Contributor

@jfischer-no jfischer-no left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

@nashif nashif merged commit bdd9426 into zephyrproject-rtos:main Jun 10, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Comments