USB CDC + NIL osalThreadDequeueAllI assertion fail
Posted: Sat Aug 08, 2015 4:06 am
Hi,
I'm currently experimenting with using NIL + USB CDC on a STM32F042 for a customizable serial / USB adapter. I have encountered a strange intermittent failure that seems to appear (not quite sure) when stopping picocom (e.g., issue not specific to picocom) and restarting it without reconnecting the USB. The issue appears (i.e. assertion fails), when reattaching, not when stopping the terminal program. The issue is highly intermittent but I encountered it ~30 times. I'm using the current HAL from git. I have only tested on a Linux host (Ubuntu 14.04 x64)
Failed assertion:
In frame 1 (in osalThreadDequeueAllI):
In frame 2:
Note that cnt is NOT representative here because it is changed by osalThreadDequeueAllI. I have verified cnt to be -1 when entering the function.
Thread code (works besides this bug. Whoever wants to use it, may do so unter Apache License v2.0):
NIL_CFG_NUM_THREADS = 1.
I'm not really sure where to look for the underlying issue. In general I believe this might be an issue inside the USB CDC as I would consider repeated restarts of the terminal program a rarely tested circumstance. I can debug via GDB etc.
Any help would be appreciated.
Best regards, Uli
I'm currently experimenting with using NIL + USB CDC on a STM32F042 for a customizable serial / USB adapter. I have encountered a strange intermittent failure that seems to appear (not quite sure) when stopping picocom (e.g., issue not specific to picocom) and restarting it without reconnecting the USB. The issue appears (i.e. assertion fails), when reattaching, not when stopping the terminal program. The issue is highly intermittent but I encountered it ~30 times. I'm using the current HAL from git. I have only tested on a Linux host (Ubuntu 14.04 x64)
Code: Select all
chSysHalt (reason=reason@entry=0x80023e0 <__func__.4955> "osalThreadDequeueAllI") at /home/uli/dev/ChibiTest/ChibiOS/os/nil/src/nil.c:127
(gdb) bt
#0 chSysHalt (reason=reason@entry=0x80023e0 <__func__.4955> "osalThreadDequeueAllI") at /home/uli/dev/ChibiTest/ChibiOS/os/nil/src/nil.c:127
#1 0x0800076a in osalThreadDequeueAllI (tqp=tqp@entry=0x20000714 <SDU1+52>, msg=msg@entry=0x0) at /home/uli/dev/ChibiTest/ChibiOS/os/hal/osal/nil/osal.c:102
#2 0x08000814 in usb_packet_write_from_queue.lto_priv.30 (udp=<optimized out>, oqp=0x20000714 <SDU1+52>, n=<optimized out>) at /home/uli/dev/ChibiTest/ChibiOS/os/hal/ports/STM32/LLD/USBv1/us
b_lld.c:254
#3 0x080010b6 in usb_lld_prepare_transmit (usbp=<optimized out>, ep=<optimized out>) at /home/uli/dev/ChibiTest/ChibiOS/os/hal/ports/STM32/LLD/USBv1/usb_lld.c:719
#4 0x08001c0c in usbPrepareQueuedTransmit (usbp=<optimized out>, ep=<optimized out>, oqp=<optimized out>, n=<optimized out>) at /home/uli/dev/ChibiTest/ChibiOS/os/hal/src/usb.c:489
#5 0x080015fc in sduDataTransmitted (usbp=0x2000065c <USBD1>, ep=<optimized out>) at /home/uli/dev/ChibiTest/ChibiOS/os/hal/src/serial_usb.c:358
#6 0x08000b42 in VectorBC () at /home/uli/dev/ChibiTest/ChibiOS/os/hal/ports/STM32/LLD/USBv1/usb_lld.c:367
#7 <signal handler called>
#8 0x55555554 in ?? ()
Code: Select all
$4 = {
ctxp = 0x20001144 <serialThreadWA+492>,
state = 0x0,
u1 = {
msg = 0x0,
p = 0x0,
trp = 0x0,
semp = 0x0,
ewmask = 0x0
},
timeout = 0x0,
epmask = 0x0
}
Failed assertion:
Code: Select all
chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting");
In frame 1 (in osalThreadDequeueAllI):
Code: Select all
(gdb) i loc
sp = 0x20000714 <SDU1+52>
tr = 0x20000514 <nil+12>
__func__ = "osalThreadDequeueAllI"
In frame 2:
Code: Select all
(gdb) p oqp->q_waiting
$8 = {
sem = {
cnt = 0x0
}
}
Note that cnt is NOT representative here because it is changed by osalThreadDequeueAllI. I have verified cnt to be -1 when entering the function.
Thread code (works besides this bug. Whoever wants to use it, may do so unter Apache License v2.0):
Code: Select all
sdStart(&SD2, &serialCfg);
/*
* Initializes a serial-over-USB CDC driver.
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
usbDisconnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(200);
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(200);
while (true) {
if(USBD1.state == USB_ACTIVE) { //ep0next --> terminal conn'd
chSysLock();
size_t qsize = qSpaceI(&SD2.iqueue);
chSysUnlock();
if(qsize > 0) { //Queue not empty
msg_t read = sdReadTimeout(&SD2, (uint8_t*)rxBuf, qsize, MS2ST(1));
if(read != Q_TIMEOUT && read != Q_RESET && read > 0) {
sdWriteTimeout(&SDU1, (uint8_t*)rxBuf, read, MS2ST(1));
}
chThdSleepMicroseconds(500); //Wait for some data
} else {
chThdSleepMicroseconds(500); //Wait for some data
}
} else {
chThdSleepMilliseconds(1);
}
}
NIL_CFG_NUM_THREADS = 1.
I'm not really sure where to look for the underlying issue. In general I believe this might be an issue inside the USB CDC as I would consider repeated restarts of the terminal program a rarely tested circumstance. I can debug via GDB etc.
Any help would be appreciated.
Best regards, Uli