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
This commit is contained in:
Michael Stapelberg 2021-04-25 16:11:20 +02:00
parent d53c82a884
commit dcf1cdd589
2 changed files with 26 additions and 1 deletions

View File

@ -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. */

View File

@ -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
};