Usb serial fix queue full crash (#1763)

* fixed usb serial queue crashing

* fixed usb input buffer handling

* fixed black screen issue
This commit is contained in:
Bernd Herzog 2024-01-12 21:49:10 +01:00 committed by GitHub
parent 0a8194fa10
commit 409242507c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 15 deletions

View File

@ -40,15 +40,19 @@
SerialUSBDriver SUSBD1; SerialUSBDriver SUSBD1;
uint8_t usbBulkBuffer[USBSERIAL_BUFFERS_SIZE]; uint8_t usb_bulk_buffer[USB_BULK_BUFFER_SIZE];
void bulk_out_receive(void) { void bulk_out_receive(void) {
int ret; int ret;
while (chIQGetEmptyI(&SUSBD1.iqueue) < USB_BULK_BUFFER_SIZE)
chThdSleepMilliseconds(1); // wait for shell thread when buffer is full
do { do {
ret = usb_transfer_schedule( ret = usb_transfer_schedule(
&usb_endpoint_bulk_out, &usb_endpoint_bulk_out,
&usbBulkBuffer[0], &usb_bulk_buffer[0],
USBSERIAL_BUFFERS_SIZE, USB_BULK_BUFFER_SIZE,
serial_bulk_transfer_complete, serial_bulk_transfer_complete,
NULL); NULL);
@ -58,18 +62,19 @@ void bulk_out_receive(void) {
void serial_bulk_transfer_complete(void* user_data, unsigned int bytes_transferred) { void serial_bulk_transfer_complete(void* user_data, unsigned int bytes_transferred) {
(void)user_data; (void)user_data;
chSysLockFromIsr();
for (unsigned int i = 0; i < bytes_transferred; i++) { for (unsigned int i = 0; i < bytes_transferred; i++) {
msg_t ret; msg_t ret;
do { do {
chSysLockFromIsr(); ret = chIQPutI(&SUSBD1.iqueue, usb_bulk_buffer[i]);
ret = chIQPutI(&SUSBD1.iqueue, usbBulkBuffer[i]);
chSysUnlockFromIsr();
if (ret == Q_FULL) { if (ret == Q_FULL) {
chThdYield(); chDbgPanic("USB iqueue buffer full");
} }
} while (ret == Q_FULL); } while (ret == Q_FULL);
} }
chSysUnlockFromIsr();
} }
static void onotify(GenericQueue* qp) { static void onotify(GenericQueue* qp) {
@ -93,7 +98,7 @@ static void onotify(GenericQueue* qp) {
NULL); NULL);
if (ret == -1) if (ret == -1)
chThdYield(); chThdSleepMilliseconds(1);
} while (ret == -1); } while (ret == -1);
chSysLock(); chSysLock();

View File

@ -24,8 +24,10 @@
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#define USB_BULK_BUFFER_SIZE 64
#ifndef USBSERIAL_BUFFERS_SIZE #ifndef USBSERIAL_BUFFERS_SIZE
#define USBSERIAL_BUFFERS_SIZE 400 #define USBSERIAL_BUFFERS_SIZE 128
#endif #endif
struct SerialUSBDriverVMT { struct SerialUSBDriverVMT {

View File

@ -348,19 +348,23 @@ void cmd_sd_write_binary(BaseSequentialStream* chp, int argc, char* argv[]) {
return; return;
} }
long size = (int)strtol(argv[0], NULL, 10); size_t size = (size_t)strtol(argv[0], NULL, 10);
chprintf(chp, "send %d bytes\r\n", size); chprintf(chp, "send %d bytes\r\n", size);
uint8_t buffer; uint8_t buffer[USB_BULK_BUFFER_SIZE];
for (long i = 0; i < size; i++) { do {
if (chSequentialStreamRead(chp, &buffer, 1) == 0) size_t bytes_to_read = size > USB_BULK_BUFFER_SIZE ? USB_BULK_BUFFER_SIZE : size;
size_t bytes_read = chSequentialStreamRead(chp, &buffer[0], bytes_to_read);
if (bytes_read != bytes_to_read)
return; return;
auto error = shell_file->write(&buffer, 1); auto error = shell_file->write(&buffer[0], bytes_read);
if (report_on_error(chp, error)) return; if (report_on_error(chp, error)) return;
}
size -= bytes_read;
} while (size > 0);
chprintf(chp, "ok\r\n"); chprintf(chp, "ok\r\n");
} }