STM32F407 and USB / UART goes into idle thread forever

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

Moderators: RoccoMarco, barthess

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

Postby kb1gtt » Tue Feb 02, 2021 6:49 pm

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: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

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

Postby Giovanni » Tue Feb 02, 2021 7:01 pm

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

Postby kb1gtt » Tue Feb 02, 2021 7:40 pm

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

Postby kb1gtt » Tue Feb 02, 2021 8:43 pm

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

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

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

Postby Giovanni » Tue Feb 02, 2021 9:33 pm

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: 384
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 180 times
Been thanked: 130 times

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

Postby FXCoder » Tue Feb 02, 2021 10:20 pm

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

Postby kb1gtt » Tue Feb 02, 2021 11:23 pm

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

Postby kb1gtt » Wed Feb 03, 2021 4:57 pm

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

Postby kb1gtt » Wed Feb 03, 2021 9:10 pm

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: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

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

Postby Giovanni » Wed Feb 03, 2021 9:19 pm

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

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 12 guests