2025-03-05 1:54 AM
Hello, I'm new to STM world, so I'll post what may seem a trivial question to many, but which is not totally clear to me:
I'd like to understand better the behavior of the micro controller in a situation like:
/* Configure ISR on UART RX */
/* Enter Critial Section */
uint32_t primask_bit = __get_PRIMASK( );
__disable_irq( );
/* Do stuff */
/* !!! ISR occurring on UART RX !!! */
/* Do other stuff */
/* Exit Critial Section */
__set_PRIMASK( primask_bit )
Is the ISR totally ignored by the micro controller or the IRQ associated to the ISR is executed right after line 12?
I understand that __disable_irq() works on the I-bit of the CPSR register, which disables IRQ interrupts globally, so my guess is that the NVIC may take trace of the ISR occurrence until the core has re-enabled the I-bit of CPSR register (line 12).
Is this a correct interpretation or is it misleading?
Also in case the IRQ of UART ISR is responsible of re-configuring the interrupt enable bit in UART registers, is it possible that in the previous scenario:
1. The ISR occurs during the CRITICAL SECTION
2. IRQ is not executed, so the IE flag has been cleared by HW due to the ISR occurrance, but it has not been set by the IRQ.
3. ISR cannot occur anymore.
Thank you for the support.
Solved! Go to Solution.
2025-03-05 5:00 AM - edited 2025-03-05 5:10 AM
The PRIMASK in Cortex-M4 and newer is improvement over simple interrupt disable flag of Cortex-M0.
It supports cases when you want to keep certain high-priority interrupts enabled, and mask the rest of interrupts at once. Basically it simplifies separation of interrupt sources to "real-time" and "less real-time".
A well known example of using PRIMASK is FreeRTOS. This RTOS supports calling the RTOS services from interrupt handlers, but only from these of certain priority and lesser. Interrupts of higher priorities are never masked by FreeRTOS and can preempt it - but they cannot do RTOS calls. This is implemented with the PRIMASK. The "critical section" means disabling only those interrupts that may call RTOS services.
The interrupt sources do not know why the CPU does not accept the request, so the behavior of pending interrupt sources is same for __disable_irq() or raising PRIMASK. They will hang and wait for the CPU. Anyway, NVIC is part of the CPU so it always does the right thing.
> IRQ is not executed, so the IE flag has been cleared by HW due to the ISR occurrance
Interrupt flags of the "devices" (IP modules) are never cleared upon acceptance of the interrupt. Only NVIC interrupt status bits are affected by this. Interrupt flags of the "devices" are affected only by explicit reads or writes by the program.
2025-03-05 5:00 AM - edited 2025-03-05 5:10 AM
The PRIMASK in Cortex-M4 and newer is improvement over simple interrupt disable flag of Cortex-M0.
It supports cases when you want to keep certain high-priority interrupts enabled, and mask the rest of interrupts at once. Basically it simplifies separation of interrupt sources to "real-time" and "less real-time".
A well known example of using PRIMASK is FreeRTOS. This RTOS supports calling the RTOS services from interrupt handlers, but only from these of certain priority and lesser. Interrupts of higher priorities are never masked by FreeRTOS and can preempt it - but they cannot do RTOS calls. This is implemented with the PRIMASK. The "critical section" means disabling only those interrupts that may call RTOS services.
The interrupt sources do not know why the CPU does not accept the request, so the behavior of pending interrupt sources is same for __disable_irq() or raising PRIMASK. They will hang and wait for the CPU. Anyway, NVIC is part of the CPU so it always does the right thing.
> IRQ is not executed, so the IE flag has been cleared by HW due to the ISR occurrance
Interrupt flags of the "devices" (IP modules) are never cleared upon acceptance of the interrupt. Only NVIC interrupt status bits are affected by this. Interrupt flags of the "devices" are affected only by explicit reads or writes by the program.
2025-03-05 5:31 AM
Hi @tcpctrnk
Your interpretation is right : if interrupt is raised between lines 5 and 12, processing of IT will be delayed after line 12
For the 2nd question (source of interrupt is disabled during the critical section, for example RXNEIE), I think that if interrupt occurs prior its source is disabled (RXNEIE=0), then it will be pending at NVIC level, and will be processed, once irq are enabled again. Otherwise, no interrupts will be raised.
Regards
2025-03-05 7:40 AM
As @Pavel A. pointed out, I was missing this piece of information:
Interrupt flags of the "devices" are affected only by explicit reads or writes by the program.
which solved my doubts and helped me to understand that the underlying problem was a bad management of the error conditions (specifically overrun error which occurred during the critical section) of my ISR.
Thank you for the support and clarification!