pbjork wrote on Monday, January 26, 2015:
I’m using the PIC32MZ processor, Harmony 1.02 with it’s version of FreeRTOS (8.x), compiler XC32 v1.34, MPLAB 2.26. I’ve adapted the FreeRTOS dual CDC USB demo code for the USB and CDC tasks, mostly without changes.
The Harmony configurator generates interrupt assembly code in the system_interrupt_a.S file. The assembly code as-is seems to be pretty close to that recommended for FreeRTOS interrupt assembly wrappers. For example:
.extern IntHandlerUSBInstance0
.section .vector_132,code, keep
.equ __vector_dispatch_132, IntVectorUSBInstance0
.global __vector_dispatch_132
.set nomicromips
.set noreorder
.set nomips16
.set noat
.ent IntVectorUSBInstance0
IntVectorUSBInstance0:
portSAVE_CONTEXT
la s6, IntHandlerUSBInstance0
jalr s6
nop
portRESTORE_CONTEXT
.end IntVectorUSBInstance0
The wrapper calls the C handler function as recommended, which then calls a Harmony-provided USB driver,
void IntHandlerUSBInstance0(void)
{
USB_DEVICE_Tasks_ISR(sysObj.usbDevObject0);
}
When I use the assembly wrapper, the …Tasks_ISR() proceeds as expected and proceeds all the way into a callback function APP_USBDeviceEventHandler(). One of the states finishes up with the standard interrupt-ending call to a semaphore operation followed by the context switch function as follows:
xSemaphoreGiveFromISR(appCDCData->xSemaphoreBlockUsbConfigure, &xHigherPriorityTaskWoken1);
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken1 );
break;
This brings us back to the …Tasks_ISR(). (But it is NOT the last instruction in the Harmony ISR - there are a couple more which seems to be a no-no in the PIC32MX port docs.) When I view the call stack, I see that the higher priority task (a CDC-related task) seems to awake right there, while the interrupt is still running, and proceeds to a spot where it happens to call portENTER_CRITICAL(). This generates an Assert() error, since this is not supposed to be called from an ISR.
Oddly, if I chuck the assembly wrapper and just use an ISR macro, it all works. (BTW, there is also a system timer ISR that uses the mhc-generated assembly wrapper.)
void __ISR(_USB_VECTOR, ipl4) _IntHandlerUSBInstance0(void)
{
USB_DEVICE_Tasks_ISR(sysObj.usbDevObject0);
}
Any comments on what is happening here? Is the assembly code at fault? I’ve tried various things such as declaring the ISR wrapper in the compiler instead, and “.extern”-ing it in the assembly file, to no avail.
Thanks for your consideration,
Paul