C + + programming to realize analog interrupt processing

Note: to view the full text, please follow the author or go to: https://yuhan2001.github.io/2021/11/17/%E5%AE%9E%E9%AA%8C%E4%B8%80%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86/

Experiment 1 interrupt processing

Experimental topic

  1. During the working process of the computer system, if an interrupt event occurs, the hardware records it in the interrupt register. Each bit of the interrupt register can correspond to an interrupt event. When an interrupt event occurs, a bit of the corresponding interrupt register is set to "1".

    • After executing an instruction, the processor must check the interrupt register. When the content of the interrupt register is not "0", it indicates that an interrupt event has occurred. The hardware stores the contents of the interrupt register and the breakpoint of the current program in a fixed unit of main memory. The operating system can know the nature of the interrupt event by analyzing the contents of the interrupt register stored in the fixed unit of main memory, so as to make corresponding processing.
    • In this experiment, the function of interrupt register is simulated by reading information from the keyboard, and the processor executes an instruction by adding 1 to the counter. After each simulated instruction is executed, the information is read from the keyboard and analyzed. When the read information = 0, it means that no interrupt event occurs and the instruction continues to be executed; When the read information = 1, it indicates that a clock interrupt event has occurred, and the clock interrupt handler is turned.
  2. Assuming that the computer system has a clock, it generates an interrupt request signal according to the power frequency (50Hz), that is, an interrupt request signal is generated every 20 milliseconds, which is called a clock interrupt signal, and the interval between clock interrupts (20 milliseconds) is called a clock unit.

    • Students can type "0" or "1" on the keyboard according to the frequency determined by themselves to simulate the clock interrupt signal generated according to the power frequency.
  3. The interrupt processing program shall first protect the site of the interrupted current process (general register content, breakpoint, etc.), and the site information can be saved in the process control block; Then process the interrupt event and modify the state of the interrupted process according to the processing result; Finally, turn to processor scheduling, which selects the runnable process and restores the site to make it run.

    • This experiment mainly simulates the processing of interrupt events. For simplicity, it can save the work of protecting the site and processor scheduling.
  4. In order to simulate the processing of clock interrupt, first analyze the function of clock interrupt. Using the clock interrupt, the calendar clock can be calculated, and it can also be used as a timing alarm clock.

    • Calculate calendar clock - store the time at startup in the specified work unit called "calendar clock", and use a timer to accumulate the number of clock interrupts. The current accurate calendar clock can be calculated according to the number of clock interrupts and clock unit (20ms) and the calendar clock at startup.
    • Timing alarm clock - for the occasion requiring timing, the time slice value of the running process can be sent to the work unit called "timing alarm clock". Each time a clock interrupt is generated, the timing alarm clock value will be reduced by 1. When the value is "0", it indicates that the determined time has come and plays the role of timing.
  5. The simulation program of this experiment can be composed of two parts. One part simulates the clock interrupt generated by hardware, and the other part simulates the clock interrupt processing program of operating system. The algorithm of the simulation program is shown in the figure. Among them, the work of protecting the field and processor scheduling can be omitted in programming. The contract processor scheduler always selects the interrupted process to continue execution.

Description of data structures and symbols used in the program

  • Character array (data structure: array)

    • char *s_st;: String form of boot time.
    • char *s_now;: The string form of the current time.
  • time_t (long integer):

    • time_t st;: The number of seconds elapsed since the start-up time on January 1, 1970.
    • time_t now;: The number of seconds that the current time has elapsed since January 1, 1970.
  • Integer (int):

    • int count;: (instruction) counter.
    • int timer; : (time interrupt) timer.
    • int wr;: Enter information on the keyboard.
    • int time_alarm: timing alarm clock (clock unit: 20ms).
    • int p;: The elapsed time (in milliseconds) from the start-up time.

Source program and notes:

#include <iostream>
#include <ctime>
using namespace std;

int main()
{
	time_t st = time(0); //The number of seconds elapsed since January 1, 1970 based on the startup time of the current system.
	char *s_st = ctime(&st); //Convert the startup time into string form;
	cout << "Startup time:" << s_st;
	//Format: Www Mmm dd hh:mm:ss yyyy
	//Where Www represents the day of the week, Mmm represents the month in letters, dd represents the day of the month, hh:mm:ss represents the time and yyyy represents the year.
	int count = 0; //Counter
	int timer = 0; //timer
	int wr;//Keyboard input information, "0" or "1" to simulate the clock interrupt signal generated by the power frequency
	int time_alarm; //Timing alarm clock
	cout << "Please enter a timed alarm:";
	cin >> time_alarm; //Set timing alarm clock (MS)
	while (time_alarm != 0) //When the timing clock is not 0
	{
		cout << "An instruction was executed" << endl;
		count++; //Counter plus 1
        cout << "Please input the analog clock interrupt signal:";
		cin >> wr; //Read in keyboard input information
		if (wr == 1) //If there is a clock interrupt
		{
			cout << "Clock interrupt, save scene" << endl;
			timer++; //Timer plus 1;
			time_alarm--; //Timing alarm clock minus 1;
			cout << "Processor scheduling" << endl;
		}
	}
	//When the timing alarm clock is 0, the cycle ends, and then the current calendar clock is calculated.
	int p; //Elapsed time from startup time (unit: ms)
	p = timer * 20;
	time_t now = st + p / 1000; // The number of seconds that the current time has elapsed since January 1, 1970
	char *s_now = ctime(&now);	//Converts the current time to a string
	cout << s_now;
    return 0;
}
/*
//To set the boot time:_ t st = time(0); Replace with the following:
	struct tm timeptr;
	int a;
	cout << "Please enter the day of the week (0-6): ";
	cin >> timeptr.tm_wday;
	cout << "Please enter month (0-11): ";
	cin >> timeptr.tm_mon;
	cout << "Please enter the day (1-31): ";
	cin >> timeptr.tm_mday;
	cout << "Please enter (0-6): ";
	cin >> timeptr.tm_hour;
	cout << "Please enter a score (0-6): ";
	cin >> timeptr.tm_min;
	cout << "Please enter seconds (0-6): ";
	cin >> timeptr.tm_sec;
	cout << "Please enter the number of years since 1900: ";
	cin >> timeptr.tm_year;
	time_t st = mktime(&timeptr); //The number of seconds elapsed since January 1, 1970 based on the startup time of the current system.
*/

Initial value and running result during program running

Initial value:

result:

After 50 timed alarm clocks, i.e. 1 second.

Thinking questions:

  • When the process scheduling strategy is combined with this experiment, the scheduling strategy of time slice rotation can be selected. Each process is assigned the same time slice. After each clock interrupt is generated, the time slice of the interrupted process is reduced by 1. When the time slice value! = 0, the process will run first. If the time slice value = 0 and the process has not finished running, it will be placed at the end of the queue and then assigned one Time slice until all processes run. How to design process control block? How to change the state of each process? Add processor scheduler to the program of this experiment.

The source code is as follows:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stdlib.h>
#include <iomanip>
using namespace std;
#define N 1000000

int n, q, temp_q; //Number of processes, time slice size, current time slice size
struct process
{
	int id; //number
	int pos; //Sorted position
	int arrive; //arrival time
	int work; //Interval time
	int begin; //start time
	int end; //Completion time
	int turnaround; //Turnaround time
	int wait; //waiting time
	bool in; //Have you entered the ready queue
	bool finish; //Complete
	int rest; //Remaining interval time
} proc[N];

queue <process> ready; //Ready queue
bool cmp_FCFS(process a, process b)
{
	if (a.arrive != b.arrive)
		return a.arrive < b.arrive;
	else
		return a.id < b.id;
}

void init()
{
	cout << "Please enter the number of processes:";
	cin >> n;
	cout << "Please enter the time slice size:";
	cin >> q;
	temp_q = q;
	cout << "Please enter the process information according to the arrival order of the process (1~n): Arrival time interval" << endl;
	//It is required to enter according to the arrival order, so as to judge the arrival order when the arrival time is the same
	for (int i = 1; i <= n; i++)
	{
		cout << "process" << i << ":";
		cin >> proc[i].arrive >> proc[i].work;
		//Information initialization
		proc[i].id = i;
		proc[i].in = 0;
		proc[i].begin = -1; //It means it hasn't started yet
		proc[i].finish = 0;
		proc[i].rest = proc[i].work;
	}
	sort(proc, proc + n + 1, cmp_FCFS);
	for (int i = 1; i <= n; i++)
	{
		proc[i].pos = i;
	}
}

bool cmp_id(process a, process b)
{
	return a.id < b.id;
}

void RR_one(int timer)
{
	for (int i = 1; i <= n; i++) //Traverse all processes
	{
		if (!proc[i].in && proc[i].arrive == timer) //If any process has not entered the ready queue and currently arrives
		{
			proc[i].in = 1; //Change tag
			ready.push(proc[i]); //Enter ready queue
		}
	}
	if (!ready.empty())
	{
		process t = ready.front();
		ready.pop();
		if (t.begin == -1)
		{
			t.begin = timer;
		}
		temp_q--;
		t.rest--;
		cout << "process" << t.id << "Running...";
		if (t.rest == 0)
		{
			cout << "The process has completed";
			t.end = timer + 1; //Completion time = latest current time
			t.finish = 1; //Update tag: completed
			t.turnaround = t.end - t.arrive; //Turnaround time = completion time - arrival time
			t.wait = t.turnaround - t.work; //Waiting time = turnaround time interval time
			proc[t.pos] = t; //Update (completed) process information
		}
		if (temp_q == 0) //The current time slice is used up
		{
			if (t.rest > 0) //If not, enter the ready queue
			{
				ready.push(t);
			}
			temp_q = q;
		}
		cout << endl;
	}
}

void display()
{
	sort(proc, proc + n + 1, cmp_id);
	cout << "The current status of all processes is as follows:" << endl;
	cout << setw(8) << "Process number" << setw(10) << "arrival time" << setw(10) << "Interval time" << setw(10) << "start time" << setw(
	         10) << "Completion time" << setw(10) << "Turnaround time" << setw(10) << "waiting time";
	cout << endl;
	for (int i = 1; i <= n; i++)
	{
		cout << left << setw(10) << proc[i].id << setw(10) << proc[i].arrive << setw(10) << proc[i].work;
		if (proc[i].begin != -1)
			cout << left << setw(10) << proc[i].begin;
		else
			cout << left << setw(10) << "Not started";
		if (proc[i].finish)
			cout << left << setw(10) << proc[i].end << setw(10) << proc[i].turnaround << setw(10) << proc[i].wait;
		else
			cout << left << setw(10) << "hang in the air" << setw(10) << "hang in the air" << setw(10) << "hang in the air";
		cout << endl;
	}
	return;
}

int main()
{
	init();
	time_t st = time(0); //The number of seconds elapsed since January 1, 1970 based on the startup time of the current system.
	char *s_st = ctime(&st); //Convert the startup time into string form;
	cout << "Startup time:" << s_st;
	//Format: Www Mmm dd hh:mm:ss yyyy
	//Where Www represents the day of the week, Mmm represents the month in letters, dd represents the day of the month, hh:mm:ss represents the time and yyyy represents the year.
	int count = 0; //Counter
	int timer = 0; //timer
	int wr;//Keyboard input information
	int time_alarm; //Timing alarm clock
	cout << "Please enter a timed alarm:";
	cin >> time_alarm; //Set timing alarm clock (MS)
	while (time_alarm != 0) //When the timing clock is not 0
	{
		cout << "An instruction was executed..." << endl;
		count++; //Counter plus 1
		cout << "Please input the analog clock interrupt signal:";
		cin >> wr; //Read in keyboard input information
		if (wr == 1) //If there is a clock interrupt
		{
			cout << "Clock interrupt, save scene..." << endl;
			RR_one(timer);
			timer++; //Timer plus 1;
			time_alarm--; //Timing alarm clock minus 1;
		}
	}
	//When the timing alarm clock is 0, the cycle ends, and then the current calendar clock is calculated.
	int p; //Elapsed time from startup time (unit: ms)
	p = timer * 20;
	time_t now = st + p / 1000; // The number of seconds that the current time has elapsed since January 1, 1970
	char *s_now = ctime(&now);	//Converts the current time to a string
	cout << "The current time is:" << s_now;
	display();
	return 0;
}

Initial value and running result during program running

initial value

Operation results

Experimental experience

  • This experiment allows me to further understand the function of interrupt and interrupt handler by writing simulation program. In the process of programming, I came into contact with the time related library < CTime > in C + +, and learned to use time_t st = time(0) get the startup time based on the current system (the number of seconds elapsed since January 1, 1970), and then use CTime & St to convert the time into string form (Format: Www Mmm dd hh:mm:ss yyyy). The simulation of interrupt is a while loop based on timing clock. In addition, I expanded. First, you can set the startup time by yourself through information input and processing the tm structure of time (see the note at the end of the source program). The second is to complete the thinking problem, combine processor scheduling with time interrupt, just understand the operation mechanism of interrupt, and effectively improve the programming ability.

  • This experiment allows me to further understand the function of interrupt and interrupt handler by writing simulation program. In the process of programming, I came into contact with the time related library < CTime > in C + +, and learned to use time_t st = time(0) get the startup time based on the current system (the number of seconds elapsed since January 1, 1970), and then use CTime & St to convert the time into string form (Format: Www Mmm dd hh:mm:ss yyyy). The simulation of interrupt is a while loop based on timing clock. In addition, I expanded. First, you can set the startup time by yourself through information input and processing the tm structure of time (see the note at the end of the source program). The second is to complete the thinking problem, combine processor scheduling with time interrupt, just understand the operation mechanism of interrupt, and effectively improve the programming ability.

Tags: C++ Operating System

Posted on Sat, 04 Dec 2021 13:51:52 -0500 by areric