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:
parent
d53c82a884
commit
dcf1cdd589
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
#include "chthreads.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "ch_test.h"
|
#include "ch_test.h"
|
||||||
#include "rt_test_root.h"
|
#include "rt_test_root.h"
|
||||||
|
@ -92,6 +93,8 @@ void printf_debug(const char *format, ...)
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
semaphore_t scls;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Application entry point.
|
* Application entry point.
|
||||||
*/
|
*/
|
||||||
|
@ -107,6 +110,8 @@ int main(void) {
|
||||||
halInit();
|
halInit();
|
||||||
chSysInit();
|
chSysInit();
|
||||||
|
|
||||||
|
chSemObjectInit(&scls, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Activates MYSERIAL with 115200 baud.
|
* Activates MYSERIAL with 115200 baud.
|
||||||
*/
|
*/
|
||||||
|
@ -152,6 +157,11 @@ int main(void) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (SDU1.config->usbp->state == USB_ACTIVE) {
|
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");
|
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);
|
thread_t *shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, "shell", NORMALPRIO + 1, shellThread, (void *)&shell_cfg1);
|
||||||
chThdWait(shelltp); /* Waiting termination. */
|
chThdWait(shelltp); /* Waiting termination. */
|
||||||
|
|
|
@ -316,13 +316,28 @@ static void sof_handler(USBDriver *usbp) {
|
||||||
osalSysUnlockFromISR();
|
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.
|
* USB driver configuration.
|
||||||
*/
|
*/
|
||||||
const USBConfig usbcfg = {
|
const USBConfig usbcfg = {
|
||||||
usb_event,
|
usb_event,
|
||||||
get_descriptor,
|
get_descriptor,
|
||||||
sduRequestsHook,
|
requests_hook,
|
||||||
sof_handler
|
sof_handler
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue