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

View File

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

View File

@ -348,19 +348,23 @@ void cmd_sd_write_binary(BaseSequentialStream* chp, int argc, char* argv[]) {
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);
uint8_t buffer;
uint8_t buffer[USB_BULK_BUFFER_SIZE];
for (long i = 0; i < size; i++) {
if (chSequentialStreamRead(chp, &buffer, 1) == 0)
do {
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;
auto error = shell_file->write(&buffer, 1);
auto error = shell_file->write(&buffer[0], bytes_read);
if (report_on_error(chp, error)) return;
}
size -= bytes_read;
} while (size > 0);
chprintf(chp, "ok\r\n");
}