Pic32MX ISR Wrapper for C and C++ Users

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() { portSAVE_CONTEXT();
//do ISR work here

portRESTORE_CONTEXT();
} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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? Jason

Pic32MX ISR Wrapper for C and C++ Users

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.

Pic32MX ISR Wrapper for C and C++ Users

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! 🙂 Again…thanks Dave for your input!

Pic32MX ISR Wrapper for C and C++ Users

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. Regards.

Pic32MX ISR Wrapper for C and C++ Users

Thanks for your input on this … FreeRTOS discusses this GCC naked attribute here: http://www.freertos.org/implementation/a00013.html 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:

portSAVE_CONTEXT(); 

//do some work here

//clear interrupt flag here

portRESTORE_CONTEXT();
} void attribute((interrupt(ipl1), vector(EXTERNAL1_VECTOR))) TrueISRHandler(void) { MyISR(); } ~~~~~~~~~~~~~~~~~~~~~~~~~ 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: portSAVECONTEXT() and portRESTORECONTEXT() 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.