← index #11713PR #12725
Likely Duplicate · high · value 1.812
QUERY · ISSUE

/ports/esp32/usb_serial_jtag.c usb_serial_jtag_isr_handler bug

openby youkebingopened 2023-06-06updated 2023-06-06
bug

`static void usb_serial_jtag_isr_handler(void *arg) {
uint32_t flags = usb_serial_jtag_ll_get_intsts_mask();

if (flags & USB_SERIAL_JTAG_INTR_SOF) {       
    usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF);        
}   

if (flags & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) {       
    usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
    /*  
     The commented part has bugs.  
     Assume the PC sends data very fast, such as 500 bytes (can be simulated by pasting),
     After multiple interrupts, stdin_ringbuf will be full, that is, req_len = 0 below.  
     Since the interrupt has been cleared, the USB buffer cannot be read out, 
     interrupts will never happen again, causing the USB to fail and the link to eventually break. 
     Simply changing to  
     usb_serial_jtag_ll_read_rxfifo(rx_buf, USB_SERIAL_JTAG_BUF_SIZE)  
     can ensure normal operation. Of course, poll and other methods can also be used to fix this bug.
    */
    //size_t req_len = ringbuf_free(&stdin_ringbuf);        
    //if (req_len > USB_SERIAL_JTAG_BUF_SIZE) {         
    //    req_len = USB_SERIAL_JTAG_BUF_SIZE;         
    //}         
    //size_t len = usb_serial_jtag_ll_read_rxfifo(rx_buf, req_len);         
    size_t len = usb_serial_jtag_ll_read_rxfifo(rx_buf, USB_SERIAL_JTAG_BUF_SIZE);         
    for (size_t i = 0; i < len; ++i) {             
        if (rx_buf[i] == mp_interrupt_char) {                 
        mp_sched_keyboard_interrupt();             
        } else {                 
            ringbuf_put(&stdin_ringbuf, rx_buf[i]);             
        }         
    }          
    mp_hal_wake_main_task_from_isr();     
}  

}
`

CANDIDATE · PULL REQUEST

ports/esp32: Poll serial/JTAG for unread data to prevent blocking.

mergedby DvdGiessenopened 2023-10-18updated 2023-10-31
port-esp32

If data is pushed over serial/JTAG too fast we may fill up stdin_ringbuf and not be able to read all the data out of the serial/JTAG buffer. Thus we need to explicitly poll and read the serial/JTAG RX buffer to prevent blocking (since if the serial/JTAG buffer is already filled, we will not get another interrupt to transfer it to the stdin ringbuffer).

This fixed pasting large amounts of text over the serial/JTAG console for me.

EDIT: Reworked based on feedback; previous iteration is here.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied