I have previously encountered a breakpoint. During the USB initialization process, an interrupt will occur, but the program will not proceed to this point. Only when a USB packet is received will it enter the callback function for the receiving interrupt.
Again, enabled device interrupts before the OS is started can cause all kinds of problems. Very likely your root cause. Could be a follow up issue on a timer interrupt (or another device interrupt) also firing.
Currently, all my peripheral interrupts are at the lowest level, which is the same as the interrupt levels in the FreeRTOS system. Logically speaking, interrupts of the same level should not mutually preempt each other; instead, they would queue up.
And why would enabling and triggering the peripheral interrupt before the system scheduler starts cause an anomaly? They shouldn’t have conflicts either, should they?
please query this forum for more information, this has been discussed many times before. Not related to priorities. The Systick timer interrupt, for example, may attempt to schedule a task which must not happen before the scheduler has started.
Currently, my FreeRTOS program is not completely unable to run. Instead, when the FreeRTOS components are called within the interrupt callback, the program will crash. However, if we ignore other external signal inputs and only run the GPIO level switching, it is still possible to operate normally.
If it’s because of the reason you mentioned, then it should definitely not be able to run at all.
Wrong conclusion. Due to the concurrent control flow, a sequence that leads to a crash may be completly unpredictable and irreproducable.
All I’m doing is pointing you to a very likely root cause of your crash. You may choose to ignore it, fine. Best of luck with your bug hunt!
I am extremely grateful for your presenting new possibilities to my question. Of course, I will also take a look at the concurrent control process of MCU later.
I would like to add some additional phenomena here: When the FreeRTOS release semaphore function (Form_ISR) is called within the interrupt callback, if we step through the code continuously, we will find that there is an infinite loop between prvCheckTasksWaitingTermination and listCURRENT_LIST_LENGTH. Eventually, it will lead to a hardware failure.
Which likely indicates corruption of the list via a wild write, or some ISR calling a function at too “high” a priority (numerically too low)
Currently, the priority of all external device interrupts is set to level 3 (the lowest level). Then, systick and pendsv will be set to the lowest priority by the program before the scheduler is started. It should not be possible for any other higher-priority ISRs to preempt them. As for “calling a function”, it seems too general.
Then RAc said it might be caused by concurrent interrupts. Then I went to check the reference manual of the M0+ core. When the interrupt levels are the same, they are executed in ascending order of Exception number. If pendsv and systic tick occur concurrently, pendsv will be executed first and then systic tick. However, as long as the portNVIC_INT_CTRL_REG register is set, only the pendsv flag bit is set to 1, so there shouldn’t be a problem.
Then my engineering files have also been uploaded to GitHub. Do you have a reproduction method on your side?
My operation process is to plug in the USB, then use the serial port debugging assistant to send strings, and executing the USB receive interrupt callback function with “From_ISR” will reproduce the issue.
Your problem is exactly what @RAc mentioned. The following is the call chain which enables interrupt before starting the scheduler:
main --> MX_USB_Device_Init --> USBD_Start --> USBD_LL_Start --> HAL_PCD_Start --> __HAL_PCD_ENABLE --> USB_EnableGlobalInt
Please move the call to MX_USB_Device_Init after the scheduler is started. You may consider using Daemon Task Startup Hook for calling MX_USB_Device_Init.
I called MX_USB_Device_Init in the task, but the result remained the same - it was still in a loop. Then there was a hardware failure. Is it possible for you to make this change and have it run normally?
void Function_USB_Revice_Handler(void * pvParameters)
{
MX_USB_Device_Init();
while(1)
{
if(
xSemaphoreTake(User_Flag_USB_RX_Once_Complete,portMAX_DELAY) == pdTRUE
)
{
HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
}
}
}
Hello, the improvement method you currently think is effective doesn’t work for me. Could you tell me if it works for you?
Are there any other solutions?
If you need any assistance, please feel free to let me know.
For me, FreeRTOS is just a black box. I have no idea what operations might affect the system.
Is your USB interrupt still firing before the scheduler is started?
Are you using any dev board or is it your custom hardware?
I am in vTaskStartScheduler(); Breakpoints were set at both the beginning and the end. A breakpoint was added at the entry point of the USB_UCPD1_2_IRQHandler function, and also in the MX_USB_Device_Init(); A breakpoint has been set. There are a total of 4 breakpoints. The triggering sequence is: vTaskStartScheduler() first → MX_USB_Device_Init(); → Entry point of USB_UCPD1_2_IRQHandler function, vTaskStartScheduler(); The subsequent breakpoints do not trigger, which basically indicates that the scheduler is started first, followed by the interruption.
When the scheduler is started, there is a priority 3 (the lowest) TIM6 which is used as the time base for the HAL library, and it is intended for initializing timeout monitoring. This will trigger an interrupt. This is to separate the HAL timing base and the RTOS timing base independently. Will this have any impact? Actually, I’m also curious - is it really impossible to trigger any interruption before starting the scheduler? And if it is triggered, it can also enable some parts of the FreeRTOS system to operate normally.
vTaskStartScheduler never returns under normal conditions, so if you reach a bp there, something went very wrong to begin with.
You need to check the return values of all FreeRTOS functions, among others xTaskCreate(). Possibly your heap management is broken, and you have problems much more fundamental.
That said, don’t rely on sw breakpoints on Cortex. Use inline bkpt instructions instead.
So it is vTaskStartScheduler(); The previous breakpoint can be triggered, and then vTaskStartScheduler(); The subsequent breakpoints cannot be triggered. I’m not sure if it’s because the translation software distorted my original meaning.
yes, I would recommend a better translation solution. I find it very hard to decipher what your problem is in detail.
那我就用中文母语了,就是断点触发顺序为vTaskStartScheduler()之前的断点->MX_USB_Device_Init()->USB_UCPD1_2_IRQHandler函数入口,vTaskStartScheduler()之后的断点不触发,可以说USB的中断顺序应该是没问题的,然后你们在之前觉得高优先级的中断会有影响,然后我使用的HAL库的时基用的是TIM6,和FreeRTOS的systick相互独立(如果共用一个,我MCU用外部晶振时钟初始化失败,独立后,就没有这问题了),是会产生一个优先级为3(最低,和PendSV、Systick同级)的定时器中断,这个会有影响吗?
在开启调度器前,不能触发任何中断吗?
请问还有其他可能性或者其他办法吗?FreeRTOS对我来说是黑箱,我不知道会有哪些因素会影响它。