Pic32MX ISR Wrapper for C and C++ Users

jasonfromca wrote on Sunday, February 23, 2014:

One of the issues I have with the FreeRTOS port for the Pic32MX processors are the need to wrap the ISR’s in assembly.

Has anyone found a better way of doing this? It seems like the issue has to do with C code not being able to call assembly?

For other ports, it seems they can do it this way:

//a small ISR pseudocode example:
void MyISR()

    //do ISR work here


To me, that’s way more convenient! However, this is NOT supported on the current Pic32MX processors (compiler/assembler issue?). Instead, you are forced to write a assembly wrapper. I can do this, but it’s for sure not convenient.

Is there a better way for C and C++ users?


davedoors wrote on Sunday, February 23, 2014:

Looking at the docs I think you only need the assembly wrapper if you want to have interrupt nesting and a separate interrupt stack, otherwise you can use the keywords provided by the compiler to designate a function as an interrupt handler. Separate interrupt stacks are important if you use interrupt nesting.

The compiler is GCC. Does it support attribute((naked))? If it does then you can write the whole thing in the C file by making the C function naked.

jasonfromca wrote on Sunday, February 23, 2014:

Dave, thank you for your response!

You are partially right. Yes, I do need the wrapper if I want to have interrupt nesting and a separate interrupt stack. That’s correct! However, I also need an wrapper if I call Free RTOS API calls (message queue sending from an interrupt).

In this case, for me, the compiler is Microchip’s XC32 compiler. Using this compiler, I’m forced to wrap a C function in assembly. This means I have to create little assembly stubs for all my ISR’s. I wouldn’t say that is entirely convenient. Does it work? Yes. Do I like it, not really.

I thought I would throw the question out here to see what others may be doing or if they have a better way to wrap an ISR preferably in C rather than assembly.

Like I said, I believe there is an issue with calling assembly macro’s from this C/C++ XC32 compiler. Therefore, I think I’m forced into having to wrap it via assembly. But, it’s just not that pretty.

If anyone has any additional input on this, I’d appreciate it! :slight_smile:

Again…thanks Dave for your input!

rtel wrote on Sunday, February 23, 2014:

Assembly macros can be called from C function if they are written as inline assembly (with __asm keyword, and correct string and line end structures) rather than macros that are designed to be included in an assembly file. Converting them to inline assembly does not help you though because you need to have control over entry to the function, without any code code being inserted by the compiler as the function prologue. That means either the functions need to be declared naked (in which case inline assembly can be used) or you need to have the wrappers in an assembly file.

XC32 is GCC by another name. On some platforms GCC includes the naked attribute and on some it doesn’t. Last time I looked the MIPS version (which is what XC32 is a modification of) didn’t, but it might be that it has since been added in as the port was written with an older version of the compiler. If the naked attribute (or equivalent) is not supported then you have to use the asm wrapper.


jasonfromca wrote on Sunday, February 23, 2014:

Thanks for your input on this …

FreeRTOS discusses this GCC naked attribute here:


Issue #1:

However, under the XC32 V1.31 and when using the naked attribute with an ISR, you get the following compiler error message:

** error: interrupt handler functions cannot also be naked functions **

Of course, that’s where I’d want the naked attribute to be used: in the ISR since we are utilizing a different FreeRTOS ISR stack.

However, it can possibly be done this way:

__attribute__(( naked )) void MyISR()

    //NOTE: No way to call portSAVE_CONTEXT() or portRESTORE_CONTEXT()
    //under the Pic32MX port from XC32. If I could, then it would look
    //like the following:


    //do some work here

    //clear interrupt flag here


void __attribute__((interrupt(ipl1), vector(_EXTERNAL_1_VECTOR))) TrueISRHandler(void)

However, I’m not sure how portRESTORE_CONTEXT() will behave since ‘TrueISRHandler’ is NOT naked.

But, I’m also faced with the other issue (assuming the above may possibly work):

Issue #2:

portSAVE_CONTEXT() and portRESTORE_CONTEXT() are both written as assembly macro’s under the Pic32MX port. Assuming the naked attribute did work, I don’t know of a way to call from C an assembly macro. From C, I can call an assembly function. However, I don’t know how to call an assembly macro under the XC32 compiler.

Any input on this second related issue?

Once I have a solution to Issue #2, I can then try and see what we’ve discussed in Issue #1 above.