modbus: serial: Ignore received data when reception is disabled#87482
Conversation
|
I think the pull-request should fix #42366 |
A byte received when reception has been disabled corrupts internal state of the server (e.g. during transmission of a reply in server mode). The reponse packet is corrupted and its transmission is aborted and the data in the buffer is treated by the server as a new incoming packet. Since the buffer is corrupted CRC doesn't match and the following log message is printed: <wrn> modbus_serial: Calculated CRC does not match received CRC This condition happens when uart_irq_rx_ready() returns true if there is a new byte in the receive FIFO even with disabled RX interrupt. The issue has been discovered on a nucleo_u083rc board with a RS485 transceiver with the RI signal floating (a pull-down gives more stable reproduction). The pull-down ensures that RI is low during transmission which is seen as byte 0 with a framing error by the receiver. The byte is received by the MCU and corrupts the response. Similar effect can be achieved by not disabling the receiver during transmission (i.e. nRE is driven by the MCU and is fixed low). The fix discards any data received when reception has been disabled. Signed-off-by: Maksim Salau <msalau@iotecha.com>
013b103 to
54da380
Compare
|
Hello @jfischer-no It seems I found a proper way to drain the RX FIFO before enabling reception. Tested the change in 2 modes:
Both modes were tested using an stm32 board. For the second one static int uart_stm32_irq_rx_ready(const struct device *dev)
{
const struct uart_stm32_config *config = dev->config;
/*
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
* the uart_err_check function call (on errors flags clearing)
*/
- return LL_USART_IsActiveFlag_RXNE(config->usart);
+ return LL_USART_IsActiveFlag_RXNE(config->usart) && LL_USART_IsEnabledIT_RXNE_RXFNE(config->usart);
} |
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a bug where stale UART data corrupts the response packet when reception is disabled. Key changes include adding a function to drain the RX FIFO, updating RX enabling/disabling logic with atomic state tracking, and updating internal definitions to support the new state.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| subsys/modbus/modbus_serial.c | Added a FIFO drain function and updated RX on/off and TX handlers |
| subsys/modbus/modbus_internal.h | Defined MODBUS_STATE_RX_ENABLED to track reception state |
54da380 to
c7abbc7
Compare
And in what world is that calling for using such language? |
That's fine in any world that values concise and honest communication. You seem to have a problem with this, please work on it.
It is a line change between my reviews, which I am pretty sure is very easy to figure out. Also, before you blame me further, note that it was your actions that caused me to request changes. |
I suggested that maybe the comment was valid, @msalau, who is in a position to actually test things, thought so too, how does that make either of us "humans blindly following the suggestions"? |
I guess I was simply hoping you would comment on the why it is wrong, since it's apparently so obvious to you the change is "trash" and yet it is not necessarily the case for at least 2 of the people involved in this PR who could maybe learn something for the future (plus anyone else stumbling open this PR in the future). |
|
Hello @jfischer-no I don't think that the change is unreasonable. Unfortunately I see discrepancies between documentation and actual behavior regularly and tend to be over-cautious in such cases. The change decreases performance by making one additional syscall to confirm that FIFO is empty. I thought this is not a big deal. I'll revert the change. Thanks and regards |
c7abbc7 to
54da380
Compare
|
It clearly is, no doubts. It does not matter what capabilities specific UART controller/driver has, the change was incorrect, not overcautious. |




A byte received when reception has been disabled
corrupts internal state of the server
(e.g. during transmission of a reply in server mode). The reponse packet is corrupted and its transmission is aborted and the data in the buffer is treated by the server as a new incoming packet. Since the buffer is corrupted CRC doesn't match and the following log message is printed:
modbus_serial: Calculated CRC does not match received CRC
This condition happens when uart_irq_rx_ready() returns true if there is a new byte in the receive FIFO even with disabled RX interrupt.
The issue has been discovered on a nucleo_u083rc board with a RS485 transceiver with the RI signal floating (a pull-down gives more stable reproduction). The pull-down ensures that RI is low during transmission which is seen as byte 0 with a framing error by the receiver. The byte is received by the MCU and corrupts the response. Similar effect can be achieved by not disabling the receiver during transmission (i.e. nRE is driven by the MCU and is fixed low).
The fix discards any data received when reception has been disabled.