STM32F407 and USB / UART goes into idle thread forever

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

kb1gtt
Posts: 41
Joined: Sat Jul 09, 2016 11:29 am
Has thanked: 11 times
Been thanked: 2 times

STM32F407 and USB / UART goes into idle thread forever

Post by kb1gtt »

I have a working USB chprintf environment. However if I disconnect putty, after a buffer becomes full, it goes into a forever idle thread. Can I get the USB com port to discard data if putty is not there to take it? I would like to connect putty, see data scroll by, then disconnect putty and have the STM32 keep operating like normal.

Here is a simplified snippet of my code as it stands now. The function "ProcessSerial" will transfer data back and forth between 2x SPI channels and an USART channel. The USB printf is just for debugging purposes. My program functions as expected as long as a terminal is connected via the USB.

Code: Select all

// Make printf more normal.
#define printf(...)  chprintf((BaseSequentialStream *)&SDU1, __VA_ARGS__)

...
int main(void) {

halInit();
chSysInit();

// Activates the USB serial driver and then the USB bus pull-up on D+.
// Note, a delay is inserted in order to not have to disconnect the cable after a reset.
sduObjectInit(&SDU1); // Clear the buffer to prevent old data from propagating.
sduStart(&SDU1, &serusbcfg);
usbDisconnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(2500);
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(2500);

printf("Just booted Version 1\r\n");

while (true) {
...
   ProcessSerial((unsigned char*)buffer); //  <<<< Several printf's happen in this sub routine.
...
} // while true

I have debug enabled, and I stepped through chprintf. However it is written at a higher level than I was able to understand. So I was not able to identify if I could some how prevent the full buffer.

Perhaps I can change a parameter in usbcfg.c or similar to disable the handshake and prevent the full buffer. I'm OK with discarding extra data.

This is ChibiOS 20.3 with GCC 7.0
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by Giovanni »

Hi,

The USB device is not aware of applications on the host side, the only thing it can check is if the host enumerated and activated it or not, you may check the USB state before sending data.

(usbGetDriverStateI(sdup->config->usbp) == USB_ACTIVE

Giovanni
kb1gtt
Posts: 41
Joined: Sat Jul 09, 2016 11:29 am
Has thanked: 11 times
Been thanked: 2 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by kb1gtt »

I changed my printf as noted below. However when I disconnect the terminal, it still goes to the endless idle thread. It acts the same as it did with out checking USB_ACTIVE, if the terminal is connected it will print in the terminal and operate as expected. However it goes idle when the terminal is disconnected.

Code: Select all

if (usbGetDriverStateI(SDU1.config->usbp) == USB_ACTIVE) printf("ProcessSerial");

I verified that when in the idle state, it claims states of USB_ACTIVE and SDU_READY. My chicken bones and voodoo makes me think the USB port is emulating RTS and CTS signals which then prevents the STM from sending and buffer becomes full.
kb1gtt
Posts: 41
Joined: Sat Jul 09, 2016 11:29 am
Has thanked: 11 times
Been thanked: 2 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by kb1gtt »

Could usbStallTransmitI be used to block printf and prevent from going idle?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by Giovanni »

kb1gtt wrote:Could usbStallTransmitI be used to block printf and prevent from going idle?


I am not sure it is a good idea.

Giovanni
User avatar
FXCoder
Posts: 403
Joined: Sun Jun 12, 2016 4:10 am
Has thanked: 188 times
Been thanked: 134 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by FXCoder »

Hi,
The preferred method would be to have an event listener in your output thread which is attached to SDU and listening for channel disconnect/connect events.
Then disable/enable your print stream accordingly.
--
Bob
kb1gtt
Posts: 41
Joined: Sat Jul 09, 2016 11:29 am
Has thanked: 11 times
Been thanked: 2 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by kb1gtt »

Can I block the chprintf if the buffer is already partly full? The below attempt = fail. Can I trigger this off of something under SDU1?

Code: Select all

if (SDU1.obqueue.buffers == 0) printf("ProcessSerial"); // Print if buffer is empty
if (SDU1.obqueue.ptr < SDU1.obqueue.top) printf("ProcessSerial"); // hacked from code snippet found stepping through print

USB is not connected or disconnected. It's always connected. I think Bob connect or disconnect events would be the USB ACTIVE or SDU READY flags. Those do not change in this situation.
kb1gtt
Posts: 41
Joined: Sat Jul 09, 2016 11:29 am
Has thanked: 11 times
Been thanked: 2 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by kb1gtt »

Bob, can you better detail how the event listener would detect channel disconnect/connect events? I'm still trying to figure out how to detect the issue.

I see in halconf.h I define #define SERIAL_USB_BUFFERS_SIZE 256

I'm currently trying to find a way to know what the live SERIAL_USB_BUFFERS_SIZE is. If I could know the current buffer size then I could use that to trigger an event listener, etc. I have been looking at pieces of data under areas like *SDU1.obqueue.buffers. However I have not managed to find an indication of the current buffer size. It appears that *SDU1.obqueue.buffers is 1 char, not the full buffer. I'm currently trying to analyze (*SDU1.obqueue.ptr - *SDU1.obqueue.top) to see if that is an indicator of the buffer.
kb1gtt
Posts: 41
Joined: Sat Jul 09, 2016 11:29 am
Has thanked: 11 times
Been thanked: 2 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by kb1gtt »

This seems to be working. Any suggestions on how I could do this better?

Code: Select all

if (SDU1.obqueue.ptr == 0) printf("ProcessSerial\r\n");

It appears that ptr contains the size of the pointer to the buffer. If the size of the buffer is 0 then it will allow a new print. If I disconnect the terminal the STM32 it will accept one printf and then it will prevent other printf statements from being processed. By preventing additional printf commands it prevents the infinite idle condition.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 and USB / UART goes into idle thread forever

Post by Giovanni »

You could use a timeout when writing, that would make the write terminate on buffer full after the specified time.

Giovanni
Post Reply