USART interrupt handler is invoked only once

The previous debug observation, I shared when I used “xTaskResumeFromISR” in interrupt handler.

But When I use “xTaskNotifyFromISR” from interrupt handler, the control is getting stuck in,

#if ( configUSE_TASK_NOTIFICATIONS == 1 )

    BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWait,
                                       uint32_t ulBitsToClearOnEntry,
                                       uint32_t ulBitsToClearOnExit,
                                       uint32_t * pulNotificationValue,
                                       TickType_t xTicksToWait )

As the control is getting stuck at “taskEXIT_CRITICAL()”, that’s why the interrupt is not enabled and interrupt handler is not invoked second time on wards.

I am using this version → FreeRTOS Kernel V10.5.1

That looks like the issue I pointed to before. It looks like it is actually stuck at the configASSERT, which means that uxIndexToWait isn’t less than configTASK_NOTIFIACTION_ARRAY_ENTRIES.

Look at those values and figure out what happened. Since you are not using the Indexed versions of the functions, the macros should be inserting zero there, and if you didn’t define a value for configTASK_NOTIFICATION_ARRAY_ENTRIES, then FreeRTOS,h should be defaulting it to 1.

#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 )
Which is this value → uxIndexToWait

“uxIndexToWait” is zero and "configTASK_NOTIFICATION_ARRAY_ENTRIES " is one
configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES );
So the above condition is true.

If you see my comment, the control is actually stuck at “taskEXIT_CRITICAL()” line 4808

The problem is that function can’t get the processor stuck unless you have done something to corrupt memory. It will just decrement the critical level count, and if 0, re-enable the interrupts.

If you go to disassembly mode, what is the exact instruction that is stuck at, and if you try single stepping what does it do?

Please find the disassembly window details,
This is without single step debug,

If I do single step debug,

So that says the program is still running and just happend to be there when you hit break. You may want to continue to single step through vPortExitCritical to make sure you aren’t in a nested critical section (which would be.a problem, and explain you not getting interrupts)

If I do single step debug the control is stuck there, that’s what I shared with you previously.
I am trying various things, but one thing I am unable to understand is, where the control is getting stuck in free rtos code.

I am not sure how and bl instruction can stuck. Not sure if this is your problem, but can you change the following in your FreeRTOSConfig.h:

#define configMINIMAL_STACK_SIZE	(256)
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 7

#define configPRIO_BITS 3 /* 8 priority levels */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1U << (configPRIO_BITS)) - 1)

The value of “configLIBRARY_LOWEST_INTERRUPT_PRIORITY” at present already 7

Let me try with this change,
#define configMINIMAL_STACK_SIZE (256)

Could by “stuck” you mean it doesn’t come back to the debugger? It may mean you need to press pause again as some ISR has had a problem, and you debugger isn’t tracing into the interrupt.

no luck, even after increasing the stack size to 256 from 100

When I say stuck means, I can only see “Terminate” enabled on the debugger, so something is still running.

If something is running, you should see a pause/break option to stop it. Normally only having Terminate means processor is crashed and the debugger has lost communication to the processor. You may need to instruction level single step to see exactly what instruction causes the crash, watching the CPU registers as well. My “Spidey sense” is telling me that likely some bad ISR is triggering here and crashing the system, so perhaps looking at the state of the interrupt controller just before enabling interrupt might help.

What processor are you using?

I am using LPC55S69 from NXP

Just want to check a fundamental thing,
If there is no free RTOS API used in the interrupt handler, the interrupt handler is always invoked when a new data is arrived, and what is blocking and why the interrupt handler is not getting invoked from 2nd instance onwards, even though there is new data arrived.
Even I wondered whether free rtos is disabling the usart interrupt. But I did some analysis.
As of now I set the USART interrupt priority as 3 (which is mapped to 0x60) (cortex-M stores priority in top bits from 5 to 7 => So the range of values are, 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0), and I even checked the assembly level implementation in free rtos in this function,

uint32_t ulSetInterruptMask( void )

there is a comment says “Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY.
Current value of “configMAX_SYSCALL_INTERRUPT_PRIORITY” is 64 (in hex it is 0x40)
So the USART interrupt is not disabled in free rtos. The question is, why the usart interrupt handler is not called 2nd time onwards?

Since 0x60 is greater than 0x40, setting the interrupt mask that way DOES disable the interrupt.

Interrupt priorities in the Arm Ecosystem are numbered with higher priorities having lower numbers. (but zero being somewhat special).

This “reversal” of values can be confusion, see the note at Customization - FreeRTOS™

As per the details mentioned in this link, Running the RTOS on a ARM Cortex-M Core - FreeRTOS™

any interrupt service routine that uses an RTOS API function must have its priority manually set to a value that is numerically equal to or greater than the configMAX_SYSCALL_INTERRUPT_PRIORITY setting. This ensures the interrupt's logical priority is equal to or less than the configMAX_SYSCALL_INTERRUPT_PRIORITY setting.

The numerical value of configMAX_SYSCALL_INTERRUPT_PRIORITY is 64(in hex 0x40). I believe the logical value is 2. Is it correct?

For usart interrupt, the priority value set was 3 (I believe this is logical value), numerically (96 - in hex 0x60)
Based on the comment in that link → USART interrupt Logical priority is less and numerical value is greater. So there won’t be any issue I think.

Right, and the function disables the interrupts for interrupts at the logical priority of configMAX_SYSCALL_INTERRUPT_PRIORITY or lower (values equal or higher) so it will be disabled, as required to use the API but only during the critical section.

This means it will not occur within a critical section, as FreeRTOS WILL disable it during that time.

From the problems you are seeing, if it is locking up after the vPortExitCritical, that the action of enabling those interrupts is allowing some ISR to run that is doing something to crash your processor (What I find the normal cause of the debugger not giving you eather a run / step / or pause/break option.)

What is meant by this statement?