Using task notification API in ISR causes change in ISR rate occurrence

Hello there,

Please see below for details.

General Details:

  • Hardware Platform : Ambiq SoC Apollo4 Blue Plus (Cortex M4F + M0).

  • FreeRTOS version : v10.1.1

Firmware Description:

  • Thread 1 to handles communication. Intends to send the data after post processing completed by thread 2.

  • Thread 2 to process data received from a hardware peripheral.

  • On the hardware platform we have configured a peripheral that provides data using a DMA. We expect to receive an interrupt at every ~85mS from DMA controller. In this ISR we use the below code to inform thread 2 to process the data.

        vTaskNotifyGiveFromISR(Thread2Handle, &xHigherPriorityTaskWoken);
  • Thread 2 is blocked until it receives a notification as shown below.
        if(ulTaskNotifyTake(pdTRUE, portMAX_DELAY) != pdFALSE)
            // do post processing of the data
  • Following are the priorities of the threads. Thread 1 priority is 2. Thread 2 priority is 3. Thread 1 wakes up nomially at ~500mS spends above 100uS to run few instructions.

  • DMA interrupt priority is set to 4.

  • RTOS related interrupt nesting definitions are below. Provided by Manufacturer (Ambiq)

#define configKERNEL_INTERRUPT_PRIORITY               (0x7 << 5)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY          (0x4 << 5)
#define NVIC_configKERNEL_INTERRUPT_PRIORITY          (0x7)

Problem Statement

  • Both threads are spawned and if task notification is used then the interrupt rate changes from ~85mS to ~91mS. This leads to unexpected result.

  • As a test, the communication hardware peripheral handled by thread 1 was turned off and the issues seems to be fixed meaning the interrupt rate is 85mS. However, this is not a feasible solution since we need to ship this data using Thread 1.

  • As another test, the communication hardware peripheral handled by thread 1 is turned ON and after 5 seconds thread 1 is suspended and thread 2 is resumed. Interrupt rate is as expected at ~85mS.

  • I have also tried to increase the priority of configMAX_SYSCALL_INTERRUPT_PRIORITY to (0x5 << 5) so the peripheral interrupt priority is lower than syscall_interrupt prirority. But the issue still exists.

  • At this point I am contemplating if the issue is due to the OS or due to the hardware component used for communication in thread 1 is somehow messing the DMA interrupt rate. I am not sure and hence looking to get some suggestions from the community.

Thank you.

Does the hardware component used for communication uses any interrupt? Do you have any other interrupts in your application? Are you using critical section in your application or otherwise blocking interrupts?

Tasks and task priorities should not make any difference at all here. Where do you clear your interrupt source? Either the ISR runs longer than 85ms, or the interrupt source is not reenabled in time.

Thanks for the response.

Hardware component used for communication does use interrupts and its a piece of firmware provided by the manufacturer. They also disable and enable interrupts in there code.

On the firmware we are developing, we currently one one DMA interrupt setup and don’t use any critical sections (no mutex’s I mean) and we don’t block interrupts.

I still am not sure how blocking of interrupts for a short duration can cause this behavior consistently.

Thanks for the response.
I clear the interrupt before notifying the thread2. The ISR does run longer than 85mS when BLE thread starts running.

I am not disabling the DMA interrupt to reenable it, if that’s what you meant by interrupt source not reenabled in time.

Keeping the community updated about my findings.
Turns out the issue was due to the system clock drift when particular peripherals were up and running. After fixing this issue, it works as expected.

Hence, it was nothing to do with using task notification API in ISR.