The MCU model I am using is STM32G0B1 (with M0+ core). I generated the Hal library code using CubeMX, and then plan to port the latest FreeRTOS. The following problem occurred:
Currently, if no external interrupt is used and only multiple tasks are executed, with the task content being just GPIO toggling, it can already run.
However, if a semaphore is set up and the task is switched in the receiving interrupt callback function of the USB peripheral, it will enter the hardware fault handling function when the prvCheckTasksWaitingTermination() function is executed.
The receiving interrupt callback function is as follows:
if(User_Flag_USB_RX_Once_Complete ! = NULL)
{
BaseType_t xHigher_Priority_Task_Worken = pdFALSE;
xSemaphoreGiveFromISR(User_Flag_USB_RX_Once_Complete,&xHigher_Priority_Task_Worken);
portYIELD_FROM_ISR(xHigher_Priority_Task_Worken);
}
Currently, thepreempting priority of all programmable peripheral interrupts in CubeMX has been set to 3 (the least priority. G0 only has 2 bits, with priority levels ranging from 0 to 3).
#define configKERNEL_INTERRUPT_PRIORITY 3 (the least priority)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 2
#define configMAX_API_CALL_INTERRUPT_PRIORITY 2
Those AI all said it was a matter of priority. However, the priority of the RTOS is opposite to that of the NVIC of the MCU. It is also unclear which logic these three macros follow.
Task initialization and functions: void Function_USB_Revice_Handler(void * pvParameters)
{
while(1)
{
if(
xSemaphoreTake(User_Flag_USB_RX_Once_Complete,portMAX_DELAY) == pdTRUE
)
{
void * *arr = (void * *)pvParameters; // Since the variables are located in different and discontinuous positions, the data is passed in through an array of pointers.
uint32_t RX_Count = *(uint32_t *)arr[0];
uint8_t *buffer = arr[1];
//CDC_Transmit_FS(buffer,RX_Count);
}
}
}
Initialization of FreeRTOS tasks:
void RTOS_Tasks_Init(void)
{
User_Flag_USB_RX_Once_Complete = xSemaphoreCreateBinary();
xTaskCreate(Function_USB_Revice_Handler,“USB_R”,256,USB_RX_Buffer_Info_Addr,10,NULL);
xTaskCreate(Function_Task_P2_LED1,“P2 LED1”,256,NULL,10,&Task_P2_LED1);
xTaskCreate(Function_Task_P2_LED2,“P2 LED2”,256,NULL,10,&Task_P2_LED2);
xTaskCreate(Function_Task_P2_LED3,“P2 LED3”,256,NULL,10,&Task_P2_LED3);
vTaskStartScheduler();
}
The port file uses the M0 core.
This article was written using translation software.