STM32F103 USB + FreeRTOS question

Hi group I I’m new in this discussion forum and would like to introduce myself. I’m telecommunications and electronics engineer, graduated in 2012. Since some time ago I have been working with STM32 microcontrollers (F1 and F4) and I have a reasonable knowledge about the use of FreeRTOS. Currently I’m working in a project where I would like to use FreeRTOS and need to use USB peripheral in device mode. In the past I have dealt with the interaction between interrupts and tasks, first using semaphores and now using task notifications. My problem comes when I try to apply a principle similar to the handling of STM32F103 USB interrupts, synchronized to a handler task to deal with the USB protocol. The typical scheme delegates the interrupt handling to a task but in the case of this peripheral the interrupt keeps alive until you explicitly clear the causing bits,which I planed to do in the task. When I try to switch the execution to the handler task, the interrupt fires again and again. I tried to temporarily disable the USB interrupt, switch to the task and enable the interrupt again at the end of the task but it doesn’t work always, I guess because of timeouts in the USB protocol. Did someone faced this issue before? Any suggestions? Thanks in advance and sorry for the long post. Best regards.

It sounds like there is no way out of the interrupt until the source of the interrupt has been cleared. Its a while since I’ve done anything with USB so this might be a daft question - but are you able to gather all the information you need from inside the interrupt handler, clear the interrupt, then process the gathered data in the task?

Hi, thanks for your quick reply. Well, in the case of the USB peripheral you can read the interrupt status register but there is a bit, associated with the completion of transfers that functions like a FIFO, in this case you have to cycle reading until there’s no more pending transfers.

Maybe the best solution is to handle the interrupts as traditional and just delegate to task some part of the processing

All depends on how time critical things are. If you have timing requirements that need to be met then process the data within the interrupt handler. Otherwise just fill a buffer, clear the interrupt and defer the processing to a task.

Hi. I’m facing the exact same problem on STM32F103C8T6. Have you found any solution to it? Thanks in advance😀.

Can you describe your problem? The solution to the problem described above seems to be to clear the interrupt in the ISR and defer the processing to a task? Does the same not work for you?

No, it doesn’t.

When executing the PCD handler in the ISR (as follows), USB-MSC works fine.

void USB_LP_CAN1_RX0_IRQHandler(void)
{
	HAL_PCD_IRQHandler(&hpcd_USB_FS);
}

What I’m trying to do, and is not working, is to defer the PCD handler to an RTOS task (As follows):

void USB_LP_CAN1_RX0_IRQHandler(void)
{
	xSemaphoreGiveFromISR(xMySemphr, NULL);
	HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
}

void vHPT(void* pvParams)
{
	while(1)
	{
		xSemaphoreTake(xMySemphr, portMAX_DELAY);
		HAL_PCD_IRQHandler(&hpcd_USB_FS);
		HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
	}
}

Some peripherals implicitly clear the isr on the device level (not NVIC, those are different) when reading the data. If that is the case, then deferring the data processing outside the irq by definition is not an option. Have you checked with the reference manual what the exact sequence is supposed to be?

And use the FromISR API in ISRs like xSemaphoreGiveFromISR or as mentioned FreeRTOS notifications, which are a bit faster/more lean.

Update:

I could not adapt the USB-device library provided by ST to work with FreeRTOS (Due to my low knowledge on USB peripheral HW functionality). Therefore, I used TinyUSB as a USB stack middleware. It has more capabilities than ST’s, most importantly for me right now is deferring USB handling to an RTOS task.

Thanks to you all for your help.

Thank you for reporting back!