-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Truncated UART packets when BREAK_ERROR occours #10578
Comments
From the comments in https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/HardwareSerial.h
What is the value of |
Could it be a memory allocation issue? |
|
These are standard modbus messages |
OK. I can't relate UART interrupts to flash accessing / httpd task. Could you please provide a minimum sketch that can be built using Arduino Core standard |
What is the value of |
Could it be an issue with flash access / httpd tasks? #ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY
#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES - 1)
#endif You can also change the ESP32-WROVER CPU that is running the UART event Loop with #ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1
#endif Or change the Task Stack size with #ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE
#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048
#endif |
About stack size... |
#define MBUS_BAUD 115200
#define PACKET_TRIGGER_ONLY_ON_TIMEOUT true
#define MBUS_RX_TIMEOUT 1
#define MAX_MBUS_DATA_LENGTH 256
#define MAX_RX_BUFFER_SIZE 80
This is from my sdkconfig.
I can increase the event stack size for testing and also the rx buffer size.
I will create one for sure because I want to get to the bottom of this. |
Here is my whole sdkconfig: https://pastebin.com/w4wPRxDK |
It can't be lower than 129. From HardwareSerial Source Code: // minimum total RX Buffer size is the UART FIFO space (128 bytes for most SoC) + 1. IDF imposition.
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
if (_uart) {
log_e("RX Buffer can't be resized when Serial is already running. Set it before calling begin().");
return 0;
}
if (new_size <= SOC_UART_FIFO_LEN) {
log_w("RX Buffer set to minimum value: %d.", SOC_UART_FIFO_LEN + 1); // ESP32, S2, S3 and C3 means higher than 128
new_size = SOC_UART_FIFO_LEN + 1;
}
_rxBufferSize = new_size;
return _rxBufferSize;
} |
Well, I see that it changes the value back. |
Firstly
I couldn't see shit so decreased debug back to info. I (117321) System: Getting task info
E (117329) Modbus: CRC error in response packet: 0x00
E (117329) Modbus: Invalid packet. Can't process it.
Raw Packet: 00
E (117334) HardwareHandler: Packet error code: 1
E (117339) Modbus: CRC error in response packet: 0x14
E (117345) Modbus: Invalid packet. Can't process it.
Raw Packet: 14 00 00 ed 85
E (117353) HardwareHandler: Packet error code: 1 The packet also has missing bytes and it is splitted. uart_event_task is priority 24 I can increase the arduino_events task further hovewer. ( I want to try these things before I go write a reproduction example because it will probably involve http requests. ) |
For some strange reason, in the menuconfig under Arduino configuration the Serial Event task priority shows up as 24 but when I do a check with |
Does |
No. It is a separated task and settings: arduino-esp32/cores/esp32/HardwareSerial.cpp Lines 14 to 24 in 0d5d50e
arduino-esp32/cores/esp32/HardwareSerial.cpp Lines 123 to 132 in 0d5d50e
|
So the What does |
It is a general Event Loop that catches most of internal Arduino Core events. |
@hitecSmartHome - I have marked this issue as |
Yeah, sorry Iam thinking and testing what could cause this. At first I tought that it is general flash access but it is triggered on other http requests too. I also put a lot of critical things into iram like flash functions and rtos functions as well as uart interrupts. I can definitely trigger it with http requests but iam not sure about what operation does it exactly. Sometimes it is easily triggered with some request other times the same request does nothing even with multiple tries. |
We can keep this issue open for longer. |
Thank you very much |
There is definietly something to do with the rx buffer size. It doesn't matter how much I increase the |
Can this be? I added 1ms wait after my callback called but before I read the serial data and it seems to work reliably. I can read huge amounts of data and I also uncommented Serial1.onReceive(
std::bind(&Modbus::handlePacket, this),
PACKET_TRIGGER_ONLY_ON_TIMEOUT
);
void Modbus::handlePacket() {
delayMicroseconds(1000); // Added 1ms wait
int available = Serial1.available();
uint8_t rawPacket[available] = {0};
int readBytes = Serial1.readBytes(rawPacket, available);
//uart_flush_input(UART_NUM_1);
if (!isPacketValid(rawPacket, readBytes)) {
return;
}
} Further testing required... |
The data packet is sent in a single flow? What if the RX Timeout is set to the maximum allowed by the protocol? |
It may not be "so simple as that". It will require a lot of data analysis and checking the logs. |
This is consistent with a BREAK received in the beginning of the packet transmission. Unfortunatelly, disabling BREAK INT doesn't fix this extra 0x00. |
Fixing it would require some sort of combination of detecting the BREAK and ignoring any "extra 0x00"... The output below considers a FIFO Full as 120 bytes.
|
That is.... funny. Break is not an error in this case. It should be there after every message since there is a packet timeout. But why don't i get this extra byte every single time? And why is the uart acting and placing random bytes into the buffer in my behalf? Even on cases where it is an error, ( like streams ) it should not alter the buffer... |
So In my testing void Modbus::handleReceiveError(hardwareSerial_error_t error) {
if (error == UART_NO_ERROR) { return; }
ESP_LOGE(MBUS_DEBUG_TAG, "Packet error code: %d", error);
ESP_LOGE(MBUS_DEBUG_TAG, "Packet error description: %s", uartErrorStrings[error]);
if( error == UART_BREAK_ERROR ){ return; }
translateUartError(error);
callErrorCb(lastPacketError);
} I get a BREAK_ERROR after every message.
This is consistent and comes after every packet and there are no |
Previously I had this error handler like this void Modbus::handleReceiveError(hardwareSerial_error_t error) {
if (error == UART_NO_ERROR || error == UART_BREAK_ERROR) { return; }
ESP_LOGE(MBUS_DEBUG_TAG, "Packet error code: %d", error);
ESP_LOGE(MBUS_DEBUG_TAG, "Packet error description: %s", uartErrorStrings[error]);
translateUartError(error);
callErrorCb(lastPacketError);
} So I ignored the |
What is the purpose of the |
From this void Modbus::handlePacket() {
int available = Serial1.available();
uint8_t rawPacket[available] = {0};
int readBytes = Serial1.readBytes(rawPacket, available);
if (!isPacketValid(rawPacket, readBytes)) {
ESP_LOGE(MBUS_DEBUG_TAG, "Invalid packet. Can't process it.");
utils.printRawPacket("MODBUS INVALID PACKET", rawPacket, readBytes);
callErrorCb(rawPacket[0]);
return;
}
parseScanPacket(rawPacket, readBytes);
if (packetCallback && !isScanning) {
packetCallback(rawPacket, readBytes);
}
} I can workaround the 0x00 issue like this void Modbus::handlePacket() {
int available = Serial1.available();
if (available <= 0) { return; }
uint8_t rawPacket[available] = {0};
int readBytes = Serial1.readBytes(rawPacket, available);
// Check and remove 0x00 at the start
int startIdx = 0;
if (rawPacket[0] == 0x00) {
ESP_LOGW(MBUS_DEBUG_TAG, "Detected 0x00 at start - removing.");
startIdx = 1; // Skip the first byte
}
// Check and remove 0x00 at the end
int endIdx = readBytes;
if (rawPacket[readBytes - 1] == 0x00) {
ESP_LOGW(MBUS_DEBUG_TAG, "Detected 0x00 at end - removing.");
endIdx = readBytes - 1; // Ignore the last byte
}
// Calculate the new length after trimming
int trimmedLength = endIdx - startIdx;
if (trimmedLength <= 0) {
ESP_LOGW(MBUS_DEBUG_TAG, "Packet length is zero after trimming - ignoring packet.");
return;
}
// Create a trimmed packet array if necessary
uint8_t trimmedPacket[trimmedLength];
memcpy(trimmedPacket, rawPacket + startIdx, trimmedLength);
if (!isPacketValid(trimmedPacket, trimmedLength)) {
ESP_LOGE(MBUS_DEBUG_TAG, "Invalid packet. Can't process it.");
utils.printRawPacket("MODBUS INVALID PACKET", trimmedPacket, trimmedLength);
callErrorCb(trimmedPacket[0]);
return;
}
parseScanPacket(trimmedPacket, trimmedLength);
if (packetCallback && !isScanning) {
packetCallback(trimmedPacket, trimmedLength);
}
} This way I can detect single 0x00 or at the start or end but I still got truncated packets like this E (11162) Modbus: CRC error in response packet: 0x03
CRC error raw packet: : 0x03 0x03 0x20 0x00 0x05 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x02 0x00 0x00 0xfe
E (11175) Modbus: Invalid packet. Can't process it.
MODBUS INVALID PACKET: 0x03 0x03 0x20 0x00 0x05 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x02 0x00 0x00 0xfe
E (11198) HardwareHandler: Packet error code: 1
E (11216) Modbus: CRC error in response packet: 0x89
CRC error raw packet: : 0x89
E (11219) Modbus: Invalid packet. Can't process it.
MODBUS INVALID PACKET: 0x89
E (11227) HardwareHandler: Packet error code: 1 The driver cuts the last byte of the frame and makes an other frame with it with an other callback... |
This frame does not even overflow the buffer. This is 37 bytes and cuts the last byte.
|
I must switch to interrupts handling and process the incoming bytes myself... |
As you say, It may be usefull with Don't bother if BREAK is called error. This is just a denomination. |
Thank you for your response and your help.
What application would need a truncated/clipped frame provider callback?
Why? |
Anyway, regarding the initial topic of this issue, there is no relationship between HTTP / Flash Accessing Tasks and the truncated UART packets. |
Other possible application: an UART console.
This is a question for the Espressif Digital Design team... I have no answer. |
@hitecSmartHome - thinking about the BREAK = received 0x00: What if used Parity is ODD instead of EVEN? But if Parity is ODD, Parity Bit should be 1 instead of 0. Just guessing... |
It doesn't help... I've just tested it using the Another possible way would be using some SoftwareSerial Library to deal with UART. Just a suggestion. |
Well... as final testing: |
Yes, that is true. |
httpd
task
Technically the single 0x00 byte "packet" callback happens because of the uart driver puts it when BREAK happens. |
just to see if I understand correctly:
|
Well, interestingly the application wrote a file automatically meanwhile and I got this on the serial I (10830070) DataBase: Writing json: /saves/users.json
W (10830075) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830092) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830103) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830111) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830125) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830130) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830132) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830138) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830146) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830152) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830171) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830173) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830179) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830199) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830201) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830209) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830217) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830222) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830228) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830236) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830242) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830247) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830253) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830260) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830267) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830280) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830294) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830299) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830301) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830307) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830315) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830329) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830341) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830347) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830349) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830353) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830360) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830369) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830374) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830387) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830389) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830395) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830402) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830409) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830417) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830424) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830436) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830441) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830445) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830452) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830467) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830473) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830477) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830481) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830487) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830494) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830504) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830508) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830516) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830525) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830575) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830586) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830602) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830605) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830611) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830614) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830621) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830628) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830635) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830653) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830656) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830661) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830665) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830674) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830693) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830695) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830706) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830712) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830716) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830733) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830741) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830743) Modbus: Detected single byte frame: 0x00. Ignoring it...
W (10830749) Modbus: Detected single byte frame: 0x00. Ignoring it...
I (10830774) UserHandler: Saved 1 users to file: /saves/users.json |
As you can see, it started writing |
god help us |
I have tested sending this sequence using the It adds the 0x00 because of the BREAK (at the end or beginning of the package), but that's all. Could it be a problem with the Line? Bad impedance or parasitic capacitance? |
Yes, correct! |
This has been an excellent issue report. |
Yes, it can be line problem or the slave itself. Iam testing it meanwhile and so far it occoures on the same slave over and over again. Requires further testing. |
But it seems flash write also triggers uart break. Hehe |
Will test this as well |
Board
esp32 wrover
Device Description
psram, eth, flash etc..
Hardware Configuration
psram, eth, flash etc..
Version
latest master (checkout manually)
IDE Name
PlatformIO
Operating System
Windows 10
Flash frequency
80
PSRAM enabled
yes
Upload speed
115200
Description
I often get truncated packets on uart when accessing either the flash with LittleFS wrapper or when making an http call from client to esp32. The way I test this is that I get an interrupt from
Serial1.onReceive()
with0x00
data in it when I save something to flash or when making an http request. http server uses the IDF server implementation as well as the arduino Serial wrapper.I expect the
onReceive
function to call my cb only when the set timeout is triggered. It isUART_SYMBOL_TIMEOUT 1
in this case.The problem is triggered every time when I write to flash. I can access menuconfig so I made sure that the UART functions and variables are in
IRAM
and interrupts too.Sketch
Debug Message
Other Steps to Reproduce
Give repeated modbus packets to your esp, wait for them and access the flash meanwhile.
I have checked existing issues, online documentation and the Troubleshooting Guide
The text was updated successfully, but these errors were encountered: