First off, huge fan of FreeRTOS
I recently got the Silicon Labs Thunderboard EFM32GG12 Eval kit which has a Giant Gecko EFM32GG12B810F1024GM64-A-QFN64 which has a Cortex-M4 with floating point. I was able to get the GCC port for the M4F of FreeRTOSv10.2.1_191129 running on the board, but when I tried to convert my non-FreeRTOS UART handler to run inside of a task, I hit a snag.
Inside the ISR I make a call to vTaskNotifyGiveFromISR() which keeps failing inside vPortValidateInterruptPriority() at line 754: configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
From previous projects with FreeRTOS I remembered that I needed to set the NVIC priority for the interrupt so in my setup code I have: USART_IntEnable(USART0, USART_IF_RXDATAV); NVIC_EnableIRQ(USART0_RX_IRQn); NVIC_SetPriority(USART0_RX_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY + 1); USART_Enable(USART0, usartEnable);
But the assert still trips and when I examine it in the debugger, I see that ucCurrentPriority is 32 but ucMaxSysCallPriority is 160! I seem to remember usually using values in the range of 5 through 8 before, but I don’t have my old code handy to check. I’m assuming it’s something small that I missed in FreeRTOSConfig.h or similar, but I’m at a loss. How do I get interrupts up and running smoothly?
This is a bit tricky to set up as not all Cortex-M devices have the same number of priority bits. There is a page that explains here https://www.freertos.org/RTOS-Cortex-M3-M4.html , but the page is somewhat complex, because the subject is somewhat complex.
The first thing to figure out is how many priority bits your device has. Then look at the configMAX_SYSCALL_INTERRUPT_PRIORITY to make sure it is compatible, and that the priority you set your UART interrupt to is at or below that priority. Take note on the page linked above about how priorities are specified in function calls too - some want shifted bits, some want unshifted.
Hopefully that is enough to get you started, post back with more info if you are not able to figure it out.
I had looked at the page you linked previously and while I understand the theory behind it, I wasn’t at all clear how to get concrete values for my specific case - which is why I had hoped to used a pre-made port/demo and just run with it… However your comment about different functions wanting different representations led me to a working solution, though not sure if it’s the most elegant. Ignoring the comments in FreeRTOSConfig.h about what to use where and instead using the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY when calling NVIC_SetPriority() seems to work, at least for my simple UART code. Thanks for the lead! Might be worth whoever writes the comments/documentation for that port’s file to reword things for us silly coders.
I think the idea is that the configLIBRARY parameter is what to use when calling the CMSIS compatible libraries, which use low shifted values, while FreeRTOS internally directly access the hardware, so uses the high shifted values.