I’m having trouble with task notifications and am sure it’s something stupid that I’m missing. My environment is such:
NXP MCUXpresso 10.3.1
Segger j-link Ultra+ with J-Link 642b software
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);|
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 = 1, and ucNotifyState = 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).