[
Well....talk about bloat!
So, I need a state machine in an interrupt so as to quickly execute some action based upon the current state. I encoded it the same as before in the main line code, and lo and behold:
To select the proper state function from the function array, 16 bit multiplier code must be linked into the app. This code is non-reentrant, so the compiler must import at least two copies of the same multiplier function. I assume if I include state machines in other interrupt handlers, each will require their own respective 16 bit mulitplier routines.Code:/opt/microchip/xc8/v2.40/pic/sources/c99/common/Umul16.c:15:: advisory: (1510) non-reentrant function "___wmul" appears in multiple call graphs and has been duplicated by the compiler
This for something that I can do in .asm with a handful of instructions.
Just FYI -- as the project get bigger, the C to .asm code size ratio is getting worse. I'm at about 100:1 right now -- mostly because I needed sprintf to do some byte to ASCII conversion. Obviously, I'll have to hand turn some conversion code. I cannot depend on the stock libs to produce reasonably sized/speed code.
And...the fact that I have to perform a multiplication in an interrupt handler! Absolutely atrocious. It'll probably be quicker to decode the 16 states with the stock and if-then-else structure.
I hate C. At least for 8 bit micros. For all the reasons I've been bitching about the last 10 years. I was right.
You can also check the XC8 stack model.MPLAB® XC8 C Compiler User’s Guide
5.9.7.1 DISABLING DUPLICATION
The automatic duplication of the function can be inhibited by the use of a special pragma. This should only be done if the source code guarantees that an interrupt cannot occur while the function is being called from any main-line code. Typically this would be achieved by disabling interrupts before calling the function. It is not sufficient to disable the interrupts inside the function after it has been called; if an interrupt occurs when executing the function, the code can fail. See Section 5.9.5 “Enabling Interrupts”, for more information on how interrupts can be disabled. The pragma is: #pragma interrupt_level 1 The pragma should be placed before the definition of the function that is not to be duplicated. The pragma will only affect the first function whose definition follows. For example, if the function read is only ever called from main-line code when the interrupts are disabled, then duplication of the function can be prevented if it is also called from an interrupt function as follows. #pragma interrupt_level 1 int read(char device) { // ... } In main-line code, this function would typically be called as follows: di(); // turn off interrupts read(IN_CH1); ei(); // re-enable interrupts The level value specified indicates for which interrupt the function will not be duplicated. For mid-range devices, the level should always be 1; for PIC18 devices it can be 1 or 2 for the low- or high-priority interrupt functions, respectively. To disable duplication for both interrupt priorities, use the pragma twice to specify both levels 1 and 2. The following function will not be duplicated if it is also called from the low- and high-priority interrupt functions. #pragma interrupt_level 1 #pragma interrupt_level 2 int timestwo(int a) { return a * 2; }
https://microchipdeveloper.com/xc8:duplicated-functions
multiplication in an interrupt handler!
Sure, if the software is interrupt bound (packet processing I/O in an ISR) and we have vectored high/low level interrupt on a 8-bit processor with shadow registers.


