Currently I have a C code that looks like this:
set_idt_entry(idt, 0, code_segment, &handle_interrupt0, 0, 0xE);
set_idt_entry(idt, 1, code_segment, &handle_interrupt1, 0, 0xE);
set_idt_entry(idt, 2, code_segment, &handle_interrupt2, 0, 0xE);
set_idt_entry(idt, 3, code_segment, &handle_interrupt3, 0, 0xE);
set_idt_entry(idt, 4, code_segment, &handle_interrupt4, 0, 0xE);
set_idt_entry(idt, 5, code_segment, &handle_interrupt5, 0, 0xE);
set_idt_entry(idt, 6, code_segment, &handle_interrupt6, 0, 0xE);
.
.
.
Repeated calls are taking about 256 lines and are looking ugly. I'm stuck trying to come up with a macro that could take care of this in a loop somehow. Is possible to do or leaving 256 lines of code is the best I can do?
CodePudding user response:
You should place those variables in an array. Assuming these are ISR function pointers, then it would look something like:
void (*handle_interrupt[256])(void) = { ... };
Or better yet use a typedef:
typedef void isr_t (void);
isr_t* handle_interrupt [256] = { ... };
And even better, assuming embedded system, ensure this table ends up in flash:
static isr_t* const handle_interrupt [256] = { ... };
Now to avoid code repetition in this initializer list, come up with a default interrupt vector for those ISRs that aren't used. Like for example:
#define handle_default reset_interrupt
You can then create a default initializer list like this:
#define def1 handle_default, // note the comma here
#define def2 def1 def1
#define def5 def2 def2 def1
#define def10 def5 def5
... // you get the idea
#define def256 def100 def100 def50 def5 def1
static isr_t* const handle_interrupt [256] = { def256 };
Now I'm assuming that some of these won't be default vector. In that case we can do a trick by adding extra designated initializer at the end of the list. The order of evaluation of sub-expressions in an initializer list is unspecified, but the actual order of initialization is left-to-right (the order the initializers appear, C17 6.7.9/19). Like this:
static isr_t* const handle_interrupt [256] =
{
def256,
[ 5] = handle_adc, // #5 used for custom ADC interrupt
[10] = handle_spi, // #10 used for custom SPI interrupt
};
And now run-time code using this array will be trivial:
for(size_t i=0; i<256; i )
set_idt_entry(idt, 0, code_segment, &handle_interrupt[i], 0, 0xE);
