#412 Interrupt priority based overlay on 8051/52


This is a suggestion for the 8051/52 overlaying system.

So far I guard ISRs or functions called by ISRS with preprocessor macros like this:

#pragma save
#ifdef SDCC
#pragma nooverlay

void ISR_foo(void) interrupt 5 using 1 {

#pragma restore

A simple policy could make this obsolete. When the using directive is used you can rely on leaf functions not requiring memory simultaneously, because they are on the same interrupt priority level (which allows them to use the same register bank unguarded).

Of course they cannot be overlaid with functions using other banks (i.e. 0, 2 and 3 in this example), but overlaying can happen with all using 1 leaf functions.

So my proposal is to maintain one overlay list for each register bank, instead of a global one. This way ISRs can use local variables to backup SFRs they need to manipulate (paging registers etc.) with a much lower memory impact.

The alternative would be to only use globals in ISRs, but that would be semantically incorrect and probably make it more difficult for the compiler to perform optimisations.


  • Maarten Brock
    Maarten Brock

    I don't quite understand. Overlaying does not happen on the registers, it happens on local variables in leaf functions that are placed in data memory. By default locals are not placed on the stack but in data memory. And to try to minimize allocated data memory the variables are overlayed. But since an interrupt call tree is in parallel to the main loop call tree, just looking for leafs is not enough.

  • It's a side effect.

    By declaring "using 1" the programmer is promising that there is no other thread with a "using 1" function. That's something the programmer has to ensure any way, because the >0 register banks are not stack protected when calling an ISR to avoid 8 push and pop operations.

    So saying "using 1" implies a lot more than just use register bank 1. It means the programmer ensured that ISRs using that register bank have the same interrupt priority and cannot interrupt each other. I.e. you can perform overlaying within the set of "using 1" functions.

    Last edit: Kamikaze Dominic Fandrey 2014-06-11
  • Maarten Brock
    Maarten Brock

    Ah, now I see.

    Btw. using globals is pretty much identical to using pragma nooverlay in memory consumption.

    This can be implemented by using a few extra OVR areas and maybe some changes to the linker.

    This might also mean that we should at least warn against calling functions using one bank from a function using another bank. And maybe we should just inhibit that.

  • I noticed that the register bank is already part of the function pointer type so you can implement bank safe interrupt callbacks (something lacking in other compilers). So it appears the linker already has the necessary information.

  • Maarten Brock
    Maarten Brock

    Yes, I believe that is implemented.

    But the linker really knows nothing about register banks. It only knows areas and their (ABS,OVR,CON,CODE,etc) flags.