Current interrupt priorities are:
TIM6 1 (used for a general 1kHz timer decrement interrupt - ISR exec time ~10us)
TIM1 1 (not enabled in current project)
UARTs 1
USB 2
A priority of 0 is not used for anything; it appears to be non maskable! This was the default setting for UARTs in Cube MX!
SysTick is 15 - this is standard for FreeRTOS. There is a huge long discussion all over the internet about this; basically FreeRTOS uses Systick to switch tasks but that interrupt must be a lower priority than any ISR, including any timer ISR. The above 1kHz timer ISR doesn't do anything related to FreeRTOS. A key Q is whether you are calling any part of FreeRTOS from an ISR, and I am not.
All my ISRs, even the four UART ISRs (actually 12: 4 x RX, 4 x TX-E, 4 x TX-TC) should be interruptible by anything else. None of them are doing something like a RMW of some config register which applies to more than one UART. This is one aspect I would not put money on.
I would think that
within a given level e.g. 1 there must be a priority hierarchy but what does that actually do? In the past when I had multiple devices on the
same priority they could not interrupt each other's ISR but the "priority within the same priority level" (hard-wired) would determine the
order in which the ISRs are presented for execution, so e.g. if UART1 has a higher priority than UART2, then UART2's ISR would be commenced after UART1's ISR has exited.
The interrupt handler is this
// Common interrupt handler for all USART interrupts
static void usart_common_IRQHandler(UART_HandleTypeDef *huart, uint8_t port)
{
// check if we are here because of RXNE interrupt
if (huart->Instance->SR & USART_SR_RXNE)
{ //if RX is not empty
serial_receive_irq_handler(huart, port);
}
// check if we are here because of TXEIE interrupt
if (huart->Instance->SR & USART_SR_TXE)
{ //if TX is empty
serial_transmit_irq_handler(huart, port);
}
// check if we are here because of the TC interrupt
if (huart->Instance->SR & USART_SR_TC)
{ //if TX complete
serial_transmit_complete_irq_handler(huart, port);
}
}
and that calls each of the 12 ISRs with the "huart" (basically a base address of the memory mapped register set for that UART), and "port" which is 1-4.
The above function is in turn called from the following which are pointed to by the vector table
/**
* @brief This function handles USART1 global interrupt - USART1_IRQn 0
*/
void USART1_IRQHandler(void)
{
usart_common_IRQHandler(&huart1, 1);
}
/**
* @brief This function handles USART2 global interrupt - USART2_IRQn 0
*/
void USART2_IRQHandler(void)
{
usart_common_IRQHandler(&huart2, 2);
}
/**
* @brief This function handles USART3 global interrupt - USART3_IRQn 0
*/
void USART3_IRQHandler(void)
{
usart_common_IRQHandler(&huart3, 3);
}
/**
* @brief This function handles USART6 global interrupt - USART6_IRQn 0
*/
void USART6_IRQHandler(void)
{
usart_common_IRQHandler(&huart6, 4);
}
and the vector table is e.g.
What could possibly be wrong with this?
Note I am using uarts 1,2,3,6 for the four ports. This was dictated by some shared pin constraints.