From dcf1cdd5897c0ed692117ee547ae78993c2cb876 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 25 Apr 2021 16:11:20 +0200 Subject: [PATCH] Teensy 4.1 demo: start USB serial shell after control line state Without this change, the ChibiOS shell prompt does not show up reliably on Linux, and possibly other operating systems. For a detailed walk-through covering the individual problems and causes, see: https://michael.stapelberg.ch/posts/2021-04-27-linux-usb-virtual-serial-cdc-acm/ I verified that this approach works with: 1. Linux 5.10 2. Windows 10 3. macOS Big Sur on a MacBook Air M1 --- demos/MIMXRT1062/RT-TEENSY4_1/main.c | 10 ++++++++++ demos/MIMXRT1062/RT-TEENSY4_1/usbcfg.c | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/demos/MIMXRT1062/RT-TEENSY4_1/main.c b/demos/MIMXRT1062/RT-TEENSY4_1/main.c index 9dac38aa..0fec41d7 100644 --- a/demos/MIMXRT1062/RT-TEENSY4_1/main.c +++ b/demos/MIMXRT1062/RT-TEENSY4_1/main.c @@ -15,6 +15,7 @@ */ #include "ch.h" +#include "chthreads.h" #include "hal.h" #include "ch_test.h" #include "rt_test_root.h" @@ -92,6 +93,8 @@ void printf_debug(const char *format, ...) va_end(args); } +semaphore_t scls; + /* * Application entry point. */ @@ -107,6 +110,8 @@ int main(void) { halInit(); chSysInit(); + chSemObjectInit(&scls, 0); + /* * Activates MYSERIAL with 115200 baud. */ @@ -152,6 +157,11 @@ int main(void) { while (true) { if (SDU1.config->usbp->state == USB_ACTIVE) { + // Wait until sduRequestsHook CDC_SET_CONTROL_LINE_STATE happens, then + // sleep for a certain time to give the app a chance to configure flags. + chSemWait(&scls); + chThdSleepMilliseconds(100); + chprintf((BaseSequentialStream*)MYSERIAL, "Starting serial-over-USB CDC Shell\r\n"); thread_t *shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, "shell", NORMALPRIO + 1, shellThread, (void *)&shell_cfg1); chThdWait(shelltp); /* Waiting termination. */ diff --git a/demos/MIMXRT1062/RT-TEENSY4_1/usbcfg.c b/demos/MIMXRT1062/RT-TEENSY4_1/usbcfg.c index 0976533a..7544e4fc 100644 --- a/demos/MIMXRT1062/RT-TEENSY4_1/usbcfg.c +++ b/demos/MIMXRT1062/RT-TEENSY4_1/usbcfg.c @@ -316,13 +316,28 @@ static void sof_handler(USBDriver *usbp) { osalSysUnlockFromISR(); } +extern semaphore_t scls; + +bool requests_hook(USBDriver *usbp) { + const bool result = sduRequestsHook(usbp); + + if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS && + usbp->setup[1] == CDC_SET_CONTROL_LINE_STATE) { + osalSysLockFromISR(); + chSemResetI(&scls, 0); + osalSysUnlockFromISR(); + } + + return result; +} + /* * USB driver configuration. */ const USBConfig usbcfg = { usb_event, get_descriptor, - sduRequestsHook, + requests_hook, sof_handler };