Task Notification Problems

I’m having trouble with task notifications and am sure it’s something stupid that I’m missing. My environment is such:

NXP LPC4330
NXP MCUXpresso 10.3.1
Segger j-link Ultra+ with J-Link 642b software
FreeRTOSv202012.00

Initially I just want 2 of my own tasks running. One that blinks an LED (tskIDLE_PRIORITY + 1UL) and one that processes data via USB 0 (tskIDLE_PRIORITY + 2UL). We can ignore the LED task as it works without issue. The USB task is where things go awry. I want it to read 27 bytes into a receive buffer, copy the 27 bytes to a transmit buffer, and then send the 27 bytes back. In the read function, I have this:


ulTaskNotifyTakeIndexed(0, pdFALSE, portMAX_DELAY);

(I want it to act like a counting semaphore just in case I fall behind on reading). In the USB ISR, I have this:


xTaskNotifyIndexedFromISR(g_pUSBTaskHandle, 0, 0, eIncrement, &xHigherPriorityTaskWoken);|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);|

where g_pUSBTaskHandle is defined as:

TaskHandle_t g_pUSBTaskHandle = 0;

and the task is created as:

xTaskCreate(vUSBTask, “USBTask”, 10 * configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 2UL), &g_pUSBTaskHandle);

with configMINIMAL_STACK_SIZE defined as:

#define configMINIMAL_STACK_SIZE ((unsigned short)1024/130/)

I can debug both this embedded side and the host PC application at the same time. If I slowly step through each, everything runs as expected. The PC application sends 27 bytes, the arm executes the ISR, it sends the notification and the task wakes up and sends the data back. However, if I let both the embedded side and the PC side run uninterrupted, then at random times different things happen on the embedded side.

Sometimes the USB task on the embedded side appears to hang in ulTaskGenericNotifyTake. Viewing the task handle in the debugger shows ulNotifiedValue[0] = 1, and ucNotifyState[0] = 2.

Sometimes the USB task just disappears altogether in the debugger.

Sometimes I get a hard fault and cannot (or maybe do not know the best way how to) determine what caused the hard fault.

If I don’t use notifications, and instead have the USB task do a busy loop waiting for a variable to change (signaling that the ISR happened), then the embedded side will run at least for several hours (have not let it run longer).

Any help?

Thanks,

C-Coder

Somehow I just finally got the configASSERT stuff to work (not sure why it wasn’t working before, but obviously something wasn’t correct). Now when the ISR runs, it gets into the xTaskGenericNotifyFromISR and the configASSERT(ucCurrentPriority >= ucMaxSysCallPriority ) fails. ucCurrentPriority = 0, and ucMaxSysCallPriority = 160. I’ve read:

and

but I’m not certain what I need to change where. I do know that these are defined as such:

#define configPRIO_BITS __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */

Thanks,

C-Coder

What is the value of configMAX_SYSCALL_INTERRUPT_PRIORITY in your FreeRTOSConfig.h and what is the priority of the USB ISR which calls xTaskNotifyIndexedFromISR?

You need to ensure that the logical priority of the USB ISR is less than or equal to configMAX_SYSCALL_INTERRUPT_PRIORITY. Note that for Cortex-M, numerically higher priority means logically lower priority.

Thanks.

Sounds like you need to set the priority of the USB interrupt, and it still has the default of 0, which for ARM processors is the HIGHEST priority, and above the max allowed.

Guarav,

#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5

#define configPRIO_BITS __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */

I’m not seeing any calls to NVIC_SetPriority, so I probably need to add one or more in.

C-Coder

Yes, you need to lower the priority of USB interrupt.

Thanks.

That’s all it took.

Cheers mate!