Well it’s complicated, but long story short my FreeRTOS tasks are all C++ classes, my hardware drivers are all C++ classes. So a hardware driver that has an ISR has a static ISR function that’s not part of the class that gets passed the this pointer to the class from the interrupt handler. This static ISR uses the this pointer to call the ISR that is a class member function. Unfortunately the FreeRTOS macro portYIELD_FROM_ISR() can’t be used inside the class ISR member function, this macro also uses the FreeRTOS macro port_END_SWITCHING_ISR which accesses the FreeRTOS global variable ulPortYieldRequired which is set depending on the value of xHigherPriorityTaskWoken, but ulPortYieldRequired is not in the namespace of the class ISR. So the problem I had was the way I was calling portYIELD_FROM_ISR(). This call has to be made in the static ISR function not the class member ISR function. Once I resolved this problem everything works beautifully. All the questions raised here by everyone made me realize that portYIELD_FROM_ISR was not getting passed the xHigherPriorityTaskWoken from the class ISR so the task switch was never occurring until the next tick. Again, many thanks to all for leading me down the path to a solution.
John