I’m using the Raspberry Pi Pico W for a project and running into issues implementing FreeRTOS and the btstack. When I pair my Bluetooth device and send packets, the FreeRTOS scheduler seems to be starved. My first thought was to put all bt tasks onto only one core, but it seems to be an issue on both cores! I can confirm these results by setting up a blink task on both cores and starting the bt. When the device is paired everything seems to be fine, but the issue arises when I start sending lots of packets it seems to have a major delay on the blink tasks on BOTH cores. Is there a way to keep RTOS on time? Does the scheduler not track the actual passage of time? I assume this has to do with the SPI used to communicate to the RP2040. The question isn’t necessarily about the btstack, but instead how to handle interrupts starving the kernel and delaying timing.
After further investigation, I set up my debugger and paused the pico when sending lots of packets. The call stack has an interrupt above the task scheduler and services some Bluetooth things and also triggers a spi interrupt. This work is also being done on the core I’ve assigned it to, yet it starves both tasks. From what I’ve read FreeRTOS uses software interrupts to keep schedule. I’ve tried setting all interrupts on the pico to low priority and setting the configKERNEL_INTERRUPT_PRIORITY to max priority, but no luck.
I would like to avoid making my own scheduler with timers and such because FreeRTOS is such a breeze. I wonder why the btstack takes away work from both cores. I’ve been trying to troubleshoot this problem for a while and I’m stuck. If anyone could provide me with some insight or correct my assumptions I’d be very thankful.
First, configKERNAL_INTERRUPT_PRIORITY MUST be the lowest interrupt priority, as it must only interrupt tasks, and not other interrupts.
Second, if your ISRs are saturating the CPU, then you have an issue with your ISRs. High speed SPI transfers are notorious for being CPU intensive if you don’t use DMA for them, and perhaps unintuitively, should often NOT be done in an ISR.
My guess is you may need to look at your Bluetooth stack and get it to use DMA for transferring the packets.
Thanks for your reply! Changing the kernel interrupt priority was just a shot in the dark, but I can see why that was a bad idea. Although, while I agree DMA would speed things up greatly I’m still questioning the implementation of timing on the RTOS scheduler. Is it done by a counter or some other timer tracking actual elapsed time? If I can just get the scheduler to trigger the task on time (in between interrupts) I can disable the interrupts while I do work. At least that’s what I’d be implementing by hand if I can’t get this working. Please forgive any misunderstandings I might have. I’m still learning.
Task time is done by counting Timer interrupts. If you have interrupts being continually firing so that other ISRs can’t get in, your system has broken normal “Real Time” requirements and isn’t suitable for “Real-Time” scheduling.
Now, if you have possible maximum continuous ISR operation for say 3 milliseconds (with a gap after that) then setting Tick interrupt for less than 3 milliseconds is not practical, but a Tick interrupt rate of once every 5 milliseconds would be.
It sounds like your problem is that you get into a long-term continuous ISR operation when you have maximal packet reception, and that just breaks the concept of “Real Time”.