Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on 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 systeminterrupta.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 .vector132,code, keep .equ __vectordispatch132, IntVectorUSBInstance0 .global __vectordispatch132 .set nomicromips .set noreorder .set nomips16 .set noat .ent IntVectorUSBInstance0 IntVectorUSBInstance0: portSAVECONTEXT 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) { USBDEVICETasks_ISR(sysObj.usbDevObject0); }

When I use the assembly wrapper, the ...TasksISR() proceeds as expected and proceeds all the way into a callback function APPUSBDeviceEventHandler(). 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); portENDSWITCHINGISR( xHigherPriorityTaskWoken1 ); break;

This brings us back to the ...TasksISR(). (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 portENTERCRITICAL(). 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(USBVECTOR, ipl4) _IntHandlerUSBInstance0(void) { USBDEVICETasksISR(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


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by edwards3 on January 26, 2015

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().

Are you sure? I dont think a task can run if an interrupt is running, unless the task code is being called from the interrupt handling code so it is still running in the interrupt.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 26, 2015

I'm pretty sure that task code ends up running in the middle of the interrupt. The call stack at the assert() instant shows a couple levels deep of ISR calls, then the callback function (which should end the ISR) and then about 8 levels deep of generic Harmony task code, ending with the portEnterCritical() call. This, of course, should not be, unless Microchip coded it this way in Harmony. Which I don't believe.

Paul


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by rtel on January 27, 2015

The PIC32 port does not need to portENDSWITCHINGISR() call to be at the end of the interrupt provided that:

  • the SW0 software interrupt used for the yield has the lowest possible interrupt priority.

  • Also I think on the MIPS core it is important to ensure the lowest interrupt priority does not become enabled in the interrupt controller during the execution of other interrupts (can't quite remember if this is the case or not). The FreeRTOS ASM code will re-enable interrupts above the priority of the currently running interrupt only - make sure no other code is re-enabling all interrupts.

Also ensure the system/interrupt stack is large enough. You might want to increase the size of configISRSTACKSIZE in FreeRTOSConfig.h to make sure.

Regards.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 27, 2015

Thanks, RTE.

Okay, I tried increasing configISRSTACKSIZE considerably and doubling configISRSTACKSIZE to 800. Still getting the assert() error from a portEnterCritical() call (from Harmony code). Which should never be called during an interrupt, but it seems to be.

I don't know quite how to address your second bullet. There are no other calls to SYSINTEnable() in the app code.

Perhaps an important clue to this is that when the mhc-generated assembly wrapper above is used, the assert() error happens. But when the _ISR() macro above is used, the code runs fine. It would seem that the only difference is the use of the assembly routines portSAVECONTEXT and portRESTORECONTEXT. Which would call into question the ISR stack size, right? But I doubled it! BTW, I find no configISRSTACK_SIZE reference in the documentation, to study up on.

Any more ideas?


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by rtel on January 27, 2015

Does the FreeRTOS port layer exactly match the port layer in the official release, or has it been edited? The port layer includes all the files in the FreeRTOSSourceportableMPLABPIC32MZ directory. You can check this by downloading whichever version is used in Harmony from SourceForge: http://sourceforge.net/projects/freertos/files/FreeRTOS/

I'm not sure if it will make any difference, but just as a sanity check, try changing

la s6, IntHandlerUSBInstance0
jalr s6
nop

to

ja IntHandlerUSBInstance0
nop

Regards.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 27, 2015

I tried changing the assembly to:

ja		IntHandlerUSBInstance0

// la s6, IntHandlerUSBInstance0 // jalr s6

But this results in an unrecognized opcode. Not being a MIPS assembly-literate, I find it strange. BTW, this is PIC32MZ, not MX.

I'll check the port layer as you recommended.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 27, 2015

And yes, the offending instruction is preceded by .extern IntHandlerUSBInstance0


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by rtel on January 27, 2015

Sorry - my bad - it should have been "jal IntHandlerUSBInstance0" not "ja IntHandlerUSBInstance0".

Regards.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 27, 2015

Gotcha. Using "jal" will assemble properly but the result is the same assert() call.

I can't find the FreeRTOS version in the Harmony docs, though I'm sure I saw it once. The "vendor release date" is December 2014 and I see a lot of "November 10" in the port files. I'll see if that matches anything.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by rtel on January 27, 2015

The version number should be in the comments at the top of every source file as:

"FreeRTOS V[whatever] - Copyright (C) 201x Real Time Engineers Ltd."

where [whatever] is the version number.

Regards.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 27, 2015

Oh, yes. FreeRTOS 8.1.2. Shall I diff every port/ file? Or merely check the version?


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by rtel on January 27, 2015

Diff the whole of every port file. Should be simple enough if you have a diff tool.

Regards.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 27, 2015

Not quite sure of this. The diff tool I have comes with MPLABX and goes one file at a time. Seems that it would be faster to just plug in the version direct from your site.

The FreeRTOS dual CDC comm port PIC32MZ app that comes with Harmony works, and that uses the assembly wrapper and all the port/ files.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 28, 2015

Status: I get the assert() error signifying a call to portEnterCritical() in ISR code if I use the macros portSAVECONTEXT and portRESTORECONTEXT in the ISR assembly wrapper recommended by FreeRTOS. No assert() error if these macros are commented out.

I've tried raising as many stack sizes as I can think of, to no avail. configMAXSYSCALLINTERRUPT_PRIORITY is at the same level as my highest task.


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by pbjork on January 30, 2015

Okay, here's the solution. Contrary to the Harmony manual, you MUST NOT #define the macro OSALUSERTOS when you are using FreeRTOS. Either the macro name or the actual usage is completely misleading. If the configurator puts it in, comment it out. And explain why, as follows. (Note: the RTOS demos in Harmony 1.02 all comment it out, but do NOT explain why.)

With OSALUSERTOS defined (as 1), the osaldefinitions.h file will include the source file osalfreertos.c. YOU DO NOT WANT THIS. This was the problem with the portEnterCritical() call from an ISR, and the resultant assert() error.

Without this, the macro file osalimplbasic.h file will be pulled in and interrupt safe calls will be made. And you will be happy.

Real Time Engineers, please address this manual discrepancy with Microchip. This confusion is misleading and unprofessional. And will someone please explain what oral_freertos.c is for, if not for this?

Paul


PIC32 assembly wrappers problem with portEND_SWITCHING_ISR()

Posted by rtel on January 30, 2015

Paul - I will certainly bring this to Microchip's attention and let you know the conclusion.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner