espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.74k stars 7.43k forks source link

HWCDC sometimes failed to `write` bytes data at once if length larger than 64. #10212

Open adadaadadade opened 3 months ago

adadaadadade commented 3 months ago

Board

YD-ESP32-S3

Device Description

YD-ESP32-S3 http://vcc-gnd.cn/vcc_gnd/YD-ESP32-S3

Hardware Configuration

USB and Serial0 connected to pc.

Version

v3.0.3

IDE Name

Arduino IDE

Operating System

Windows 10

Flash frequency

80Hz

PSRAM enabled

no

Upload speed

115200

Description

HWCDC failed to write 64 bytes data at once, It didn't send it immediately, the data still in buffer. If the data is smaller than 64 bytes, It also failed randomly, but I haven't find a way to repeat it.

Sketch

#define TEST_BUFFER_SIZE (8192)

static uint8_t test_buffer[TEST_BUFFER_SIZE];

void setup()
{
  Serial0.begin(115200);
  HWCDCSerial.begin();
  Serial0.print("setup done");
}

void loop()
{
  static int sent_size = 0;
  int avaliable = HWCDCSerial.available();
  if (avaliable <= 0) {
    delay(3);
    return;
  }

  avaliable = min(avaliable, TEST_BUFFER_SIZE);
  HWCDCSerial.readBytes(test_buffer, avaliable);
  sent_size += HWCDCSerial.write(test_buffer, avaliable);
  Serial0.printf("sent_size: %d\n", sent_size);
}
import serial
import argparse

def echo_client(ser:serial.Serial, block_size=64):
    received_len = 0
    tx_data = b"H" * block_size
    # while True:
    for i in range(1000):
        ser.write(tx_data)
        rx_data = ser.read(len(tx_data))
        received_len += len(rx_data)
        if rx_data == tx_data:
            print("OK")
        else:
            raise Exception(f"NG, len(rx_data)={len(rx_data)}, received_len={received_len}, rx_data={rx_data}")

def main():
    parser = argparse.ArgumentParser(description="Serial echo")
    parser.add_argument("port", help="Serial port")
    parser.add_argument("--baudrate", help="Baudrate", type=int, default=115200)
    parser.add_argument("--dtr", help="DTR", action="store_true")
    parser.add_argument("--rts", help="RTS", action="store_true")
    parser.add_argument("--timeout", help="Timeout", type=float, default=5.0)
    parser.add_argument("--block_size", help="Block size", type=int, default=64)

    args = parser.parse_args()
    print(args)

    ser = serial.Serial(None)
    ser.port = args.port
    ser.baudrate = args.baudrate
    ser.dtr = args.dtr
    ser.rts = args.rts
    ser.timeout = args.timeout
    ser.open()

    echo_client(ser, args.block_size)

if __name__ == "__main__":
    main()

Debug Message

serial0 output

setup done
sent_size: 64

python stdout

PS D:\repo\python-utils> python .\serial_echo_client.py COM15 --block_size 64
Namespace(port='COM15', baudrate=115200, dtr=False, rts=False, timeout=5.0, block_size=64)      
Traceback (most recent call last):
  File "D:\repo\python-utils\serial_echo_client.py", line 41, in <module>
    main()
  File "D:\repo\python-utils\serial_echo_client.py", line 38, in main
    echo_client(ser, args.block_size)
  File "D:\repo\python-utils\serial_echo_client.py", line 15, in echo_client
    raise Exception(f"NG, len(rx_data)={len(rx_data)}, received_len={received_len}, rx_data={rx_data}")
Exception: NG, len(rx_data)=0, received_len=0, rx_data=b''

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

adadaadadade commented 3 months ago

I fixed it by my custom implement. fkhwcdc.zip