简体   繁体   中英

Handling interrupt vectors in C

void interrupt (*isr8)(void);
volatile int count;
    
void interrupt MyISR8()
{
    count++;
    isr8();
    if (count > 20*18) // after 20 secs
    {
        setvect(8,isr8);
        exit(1);
    }
}
    
void main()
{
    isr8 = getvect(8);
    setvect(8, MyISR8);
    count = 0;
}

IV 8 is for timer.

Having this function, I need elaboration the order of executing MyIsr8 step by step. For example, why there is count++ before calling the isr8()? does that means the timer starts only after calling isr8? also the code after calling is8 is its there's a hidden infinite loop that keeps checking the if statement?

This is an 8h ISR (interrupt service routine). ISR are special functions to handle hardware events. When a hardware event happens (in this case time has passed) the hardware stops (interrupts) the running program then executes the ISR. When the ISR returns the hardware restores the program that was interrupted and everything continues normally.

is its there's a hidden infinite loop that keeps checking the if statement?

No but the hardware is calling MyISR8 every 18.2/sec

It appears strange to modern programmers because what you've got here is a good old fashioned TSR (terminate and stay resident). Basically what is happening is the program gets loaded. It registers the ISR (Interrupt Service Routine) with the BIOS. Then terminates (main exits). However the program stays in memory until exit is called. I'll annotate the code. Perhaps it will help explain.

void interrupt (*isr8)(void); // Address of the old ISR.
                              // You need this for two reason
                              // 1) So you can restore it when done and
                              // 2) So you can call it from your ISR.
                              // Thus chaining ISRs together to avoid
                              // breaking existing functionality.
volatile int count;
    
void interrupt MyISR8()
{
    count++;
    isr8(); // Call the old ISR
    if (count > 20*18) // after 20 secs
    {
        setvect(8,isr8); // Restore the old ISR
        exit(1); // Exit the program so DOS can free this memory
    }
}
    
void main()
{
    isr8 = getvect(8); // Save the old ISR
    setvect(8, MyISR8); // Register my ISR with BIOS. From here on
                        // the MyISR8 will be called periodically
    count = 0; // Initialize count. Technically this is a race with
               // setvect(8, MyISR8) and should be called first since
               // an ISR can fire anytime. In this case at most you would
               // handle one extra interrupt.

   // We don't have anything else so let main end 
}

Note: If memory serves getvect/setvect were Borland specific _dos_getvect/_dos_setvect became the standard. Modern OSes write their own hardware drivers and bypass BIOS. The main reason for the change was the BIOS interrupts required the CPU to enter real mode, which comes with a bunch of issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM