**Problem: ** the __interrupt() keyword is ignored when using the -c (--compile-only) flag. Interrupt handler functions can only work if placed in a file that you don't use this feature on (ie main.c).
I discovered this today when I split my single-file (main.c) project into multiple files. My interrupt code stopped executing (my UART wouldn't print more than 1 character and timer0 overflow didn't do anything).
Attached example demonstration: Very simple code that wiggles port 5 when timer 0 overflows.
Note: You may want to delete the P5M0 and P5M1 lines, I use those because my STC 8051 configures those pins to be floating inputs by default. The extra SFR writes that these lines cause might or might not be harmless on other 8051's.
version1.c works as expected. Everything is in one sourcefile and the -c compiler flag is not used.
version2 is the same code split into two files (one for main(), the other for the __interrupt() ISR). Both of the version2 hex files do not work as expected, the ISR never fires. For version2_allreloc.hex I compiled both files with -c and for version2_somereloc.hex I only used -c for the file with the __interrupt() ISR, but it makes no difference.
Run ./build.sh to recompile everything. Intermediate files are kept in the junk/ directory (don't judge my naming scheme :P).
SDCC version: tested on both 4.2.0 and 4.4.0-rc2, same results.
Are you sure this is about -c? Interrupt handlers need to be declared (doesn't matter where they are defined) in the file that contains main, as the manual states in section 3.8.1.
My apologies, it seems you are correct.
If I compile version1.c (which has everything in one file) with the following commands then the ISR works correctly:
I didn't spot that in the manual, thanks for the ref:
In my original project I was using -c on all of the sourcefiles (including main.c), then linking all of the *.rel into the final ihx. I realised the manual said I shouldn't do this (instead main.c should be provided as the first arg of the final linking command) so I worked backwards to make the example attached in this bug report and I came to the wrong conclusion.
Using -c on all source files should work as expected. Also linking for mcs51 does not require main.c or main.rel to be the first object.
What is required is to have the file containing main() to also declare the ISR including its __interrupt(number).
If it's not easy to remove this limitation, is it instead possible to emit a warning if __interrupt() is used in a file without main()?
Last edit: Hales 2024-01-09
Both removing the limitation and adding the warning would require substantial effort.
In particular, we don't just want to warn for
__interruptin files withoutmain, since this would be annoying to users that have the interrupt handler declaration in the same file asmain, but the definition in a different file.So it really would have to be a "
__interruptdefinition in file without main, but no corresponding declaration in the file withmain" warning. Which means the infrastructure for the warning would need to be partially in the compiler, partially in the linker.Last edit: Philipp Klaus Krause 2024-01-09