Overview
An operating system must have interactivity. The so-called interactivity means an exchange between people and computers, there are two most basic interactive devices, one is the display, one is the keyboard. The display is a computer to communicate with the person. The computer tells some information through the monitor, and the keyboard is used to communicate with the computer. When the person sends the command to the computer via the keyboard, the computer acceptor passed the keyboard , Then processes, and finally, the result of the process will tell people through the display, so that the simplest and most basic interaction is completed. In this article, the writer will describe how the operating system should handle the keyboard from an angle of writing an operating system, allowing people to interact with the computer through the keyboard. In this article, we will also use PYOS as our experimental platform, and experiment the operating system on the PYOS to control the control of the keyboard. In order to carry out this experiment, the author specializes in a very simple "push box" game, when Pyos After startup, you can enter the "GAME" command, and then the system will be transferred to this game. At this time, you can play the game with the four arrow keys, after the game is over, press the "ESC" button. Return to the system kernel. Everything you will learn from this article how to implement it.
In this article, PYOS implements a message system similar to Windows. In other words, the PYOS here is driven by the message. If you can drive Windows, it is very curious, but I don't know how it is achieved, then, The message driver of PYOS introduced in this article can help you understand Windows messages :)
This article is a relatively close correlation with the first few experimental reports, especially the "interrupted programming in protection mode", you can be in the "Pure C Forum" (http://purec.binghua.com) The "Operation System Experiment" area found them, the above content will be aware of this article.
During the writing of Pyos, we have got a strong support and help of many friends, China's Anteni Laboratory
Zhang Lixi
The teacher pointed out some problems in PYOS and gave a method of making PYOS development in a Windows environment. Harbin Institute of Technology Kylix, Sun made a very good view for the strange phenomenon in this realization, extreme Big extension the author's ideas and eyes, pineapple, lizhenguo spent a lot of energy for this experiment ...
There are also many friends to send me an email and leave a message on QQ, help and support the author's experiment, and I can't listen to it. Only for the above-mentioned friends who care about PYOS, the most sincere gratitude and greetings!
?? ok, missing is correct, let's start our experiment, let's go! ~~
?
Keyboard drive profile
The CPU's management of external devices is performed by interrupting programs, and the keyboard is also an external device, so the CPU's management of the keyboard is also performed by interrupt. When you hit the keyboard, the keyboard controller will make an interrupt request to the CPU, the CPU responds to this interrupt, which is completely simple to interact with the keyboard.
There is a very detailed hardware control note of the keyboard. You can find an article called "PS / 2 Keyboard Control" on the Pure C Forum. This article describes the hardware control of the keyboard. Since this article is intended to describe how the operating system interacts from the operating system, it is not intended to describe the control method of the keyboard controller, if you want to know more control details of the keyboard, For example, set the keyboard response time, repeat key frequency, keyboard self-test, etc., you will find all the content in "PS / 2 Keyboard Control". Here, only some of the details used by Pyos, because PYOS is a very simple system. J From above, we can see that there are many attributes such as response time, repetition frequency, and so on, but more fortunate is that after the computer is booted, BIOS has done all this. If you don't need a special application, use the BIOS to set the default value for us is enough for the system like Pyos, so I am happy to refer to the settings of the BIOS to initialize the keyboard, due to BIOS Running is performed before the operating system runs, so when the operating system is transferred and the keyboard has completed initialization, this time the keyboard is waiting for the state of the user input. In the previous few articles, we know that the keyboard interrupt is connected inside the computer.
8259A
On the IRQ1 line of the interrupt controller, the keyboard controller will send the interrupt signal on the IRQ1 when the button is in the IRQ1.
8259A
The interrupt controller will make this interrupt signal to the interrupt signal sent by the other external devices through the remaining IRQ lines, queued, and finally, give this information to the CPU. After the CPU is running, it will check if there is an interrupt signal delivery. If there is interrupt signal delivery, the interrupt vector of this interrupt signal will be used in the interrupt descriptor table. Which interrupt processing should be used? program. When the interrupt handler is found, the CPU will call this interrupt handler for interrupt processing. After the interrupt is completed, the CPU returns to the original interrupt program to continue execution. related
8259A
Initialization, interrupt vector and initialization of interrupt vector tables in the previous experiment report << Protective mode
8259A
The chip programming and interrupt processing inquiry >> have been described in detail, and it is not in the multi-fold tongue. Now we only need to know, the CPU passes
8259A
The interrupt vector number transmitted in the transmitted keyboard is transferred to the keyboard interrupt program in the interrupt vector table. Below we will concentrate, come and see what the keyboard interrupt procedure has completed something.
?
Keyboard interrupt program overview
The keyboard interrupt program has to complete something, this is not fixed. Different systems have different divises for their various functional modules, but for keyboard interrupt programs, it must complete the task is to tell the system keyboard what key is pressed, this is read One port of the keyboard controller is complete.
Each key on the keyboard has two unique values for logos. Why use two values instead of a value? This is because a key can be pressed or released. When a key is pressed, they produce a unique value, when a button is released, it produces a unique value, we save these values in a table, when you get through the check list, you can know Which key is tapped and you can know that it is pressed or released. These values are called keyboard scanning code in the system, and this table for query is called a keyboard scanning code set. The earliest number of keyboard keys is small, and the current keyboard key is much more than before, the change in the keyboard key has also caused the change of the scan code, and three keyboard scanning code sets are generated in history, respectively marked SET 1, respectively. , SET 2, SET 3, they have no essential difference, and the difference is that the scan code taken is not the same for the same key on the keyboard. Modern keyboard often uses Set 2, but in order to comply with the previous vintage keyboard, the BIOS automatically sets the keyboard controller to work in SET 1 mode when starting, so the keyboard controller will automatically translate the scan code sent by the keyboard data cable. , Turn it with the code in Set 2 into the code in SET 1. Therefore, it is a scan code in Set 1 to the CPU or the operating system. Of course, we can send a command to the keyboard controller to make such a conversion, but this seems nothing necessary. Below, let's take a look at the keyboard scanning code in Set 1: SET 1 keyboard scan code
key
Press down code
Release code
-----
key
Press down code
Release code
-----
key
Press down code
Release code
A
1E
9E
?
9
0A
8A
?
[
1A
9A
B
30
B0
?
`
29
89
?
Insert
E0, 52
E0, D2
C
2E
AE
?
-
0C
8C
?
HOME
E0, 47
E0, 97
Di
20
A0
?
=
0D
8D
?
PG UP
E0, 49
E0, C9
E
12
92
?
/
2b
AB
?
Delete
E0, 53
E0, D3
Fly
twenty one
A1
?
BKSP
0E
8E
?
End
E0,
4F
E0, CF
G
twenty two
A2
?
Space
39
B9
?
PG DN
E0, 51
E0, D1
Hide
twenty three
A3
?
Tab
0F
8f
?
U arrow
E0, 48
E0, C8
I
In one
97
?
Caps
3A
BA
?
L arrow
E0,4b
E0, CB
J
twenty four
A4
?
L SHFT
2A
AA
?
D arrow
E0, 50
E0, D0
K
25
A5
?
L Ctrl
1D
9D
?
R arrow
E0,4D
E0, CD
L
26
A6
?
L gui
E0,5b
E0, DB
?
Num
45
C5
M
32
B2
?
L alt
38
B8
?
KP /
E0, 35
E0, B5
N
31
B1
?
R shft
36
B6
?
KP *
37
B7
O
18
98
?
R Ctrl
E0, 1D
E0,9D
?
KP -
4A
CA
P
19
99
?
R GUI
E0,
5C
E0, DC
?
KP
4E
CE
Qi
10
19
?
R alt
E0, 38
E0, B8
?
KP EN
E0,
1C
E0,
9C
R
13
93
?
Apps
E0,5d
E0, DD
?
KP.
53
D3
S
Allf
9f
?
ENTER
1C
9C
?
KP 0
52
D2
T
14
94
?
ESC
01
81
?
KP 1
4F
CF
U
16
96
?
F1
3B
BB
?
KP 2
50
D0
V
2F
AF
?
F2
3C
BC
?
KP 3
51
D1
W
11
91
?
F3
3D
BD
?
KP 4
4b
CB
X
2D
AD
?
F4
3E
Bo
?
KP 5
4C
CC
Y
15
95
?
F5
3F
BF
?
KP 6
4D
CD
Z
2C
AC
?
F6
40
C0
?
KP 7
47
C7
0
0B
8b
?
F7
41
C1
?
KP 8
48
C8
1
02
82
?
F8
42
C2
?
KP 9
49
C9
2
03
83
?
F9
43
C3
?
]
1b
9b
3
04
84
?
F10
44
C4
?
;
27
A7
4
05
85
?
F11
57
D7
?
'
Twist
A8
5
06
86
?
F12
58
D8
?
,
33
B3
6
07
87
?
PRNT SCRN
E0,
2A
E0, 37?
? E0, B7, E0, AA
?
.
34
B4
Seduce
08
88
?
Scroll
46
C6
?
/
35
B5
8
09
89
?
PAUSE
E1, 1D, 45 E1, 9D, C5
?
?
?
?
?
?
Of course, the table above is not complete, but it includes most of the keys on the ordinary keyboard, and the complete SET 1 scan code set can be found in the "PS / 2 Keyboard Control" mentioned earlier. From above we can see that the keyboard scan code of each key is different, and press the code and the pop-up code is also different, and they only have any rules. Hey, the law here is that there is no connection between the ASCII code they do with their corresponding keys, not to say that other contacts are not. Look at the keyboard scan code value of these keys of A, S, D, and F: 1E,
Allf
, 20, 21, then look at A, S, D, F position on the keyboard, huh, huh, through the above table, we don't want to imagine, how to arrange the keys on ancient keyboards. : P
Take a closer look, we can also find some other laws, for example, the release code is greater than 0x80, and all: press the code 0x80, some key scan code is multiple bytes, for the two bytes The scan code, the first byte is E0. You may also find out more interesting phenomena, but for our experiments, it is enough to understand these.
Here you may want to ask, why not use the ASCII code directly, and use a separate scan code? I think this problem is because the scan code is easier to implement for keyboard hardware (from the relationship between the above scan code and the mounting method of the keyboard); the second is that the number of ASCII is limited, and cannot be changed However, the number of keys on the keyboard is uncertain. With the development of the keyboard, the key may increase may also be reduced; third, for example, "Alt" keys, there are two left and right on the keyboard, maybe we may The task "Press Left Alt, Completes A", "Press Right Alt, Complete B", if you use the ASCII code, the left and right ALT will make the CPU to receive the same ASCII code, the CPU cannot be divided into Is it "left alt" or "right al" T is generated. Oh, the words returned, continue to our description. When the keyboard presses a key or releases a key, the keyboard controller puts the corresponding scan code value of this button in the 0x60 port register and puts forward the request to the CPU, so the main task of interrupt request is to read. The keyboard scan code value of the 0x60 port, and the operating system can know which button is pressed by the interrupt service program, so that the corresponding processing can be performed, and the interaction with the user can be performed.
The 0x60 port has only one byte size, and in the above scan code we can find that some key scan code is multiple bytes. In fact, for this multiple byte scan code, the keyboard controller will send multiple interrupt requests to the CPU and send them sequentially. For example, the INSERT button is pressed as "E0
52
"
These two bytes, then when the INSERT button is pressed, the keyboard controller first puts "E"
0
"
Send to the 0x60 port, then apply for an interrupt, wait for the interrupt service program to read. When the interrupt service program is read, the keyboard controller will immediately put the second byte "
52
"
Send to the 0x60 port, once again apply to interrupt, let the interrupt service program to read. Note that this fact: Only after the interrupt service program takes data from the 0x60 port, the keyboard controller will send new interrupts to the 0x60 port.
The principle of interrupt service procedures is overview, and the description is described here, is it very simple? It's better to say that it is better to see it. Below we will use an actual example to see how it should be programmed, there are many details that they are unclear, only in the code can be seen in the code. Let us use PYOS to perform this experiment, complete a operating system that can receive user keyboards :).
?
Write a PYOS that can receive keyboard input
Let's take a quick look at Pyos's kernel, which is what the system has done in the memory into the memory. Below is the core code of PYOS.
const Int kernelMAGEMAXLENGTH = 32; // Set the message queue length
?
/ * Defines the buffer * / for a message queue * /
Struct_pyos_message kernelMessage [kernelMessageMaxLength];
Class_template_pyos_buffer
/ * Pointer to the queue of the current reception message * /
Class_template_pyos_buffer
?
/ * Define the buffer of the temporary user input * /
CHAR BUFFER [4];
INT buffer_count = 0;?
/ * Kernel main function * /
EXTERN "C" void pyos_main ()
{
? /* system initialization */
? Class_pyos_system :: init ();
? / * Clean screen, print welcome information * /
? Class_pyos_video :: clearscreen ();
Class_pyos_Video :: PrintMessage ("Welcome to Pyos, You CAN Input);
Class_pyos_Video :: PrintMessage ("Game", CLRED, TRUE, CLBLUE);
Class_pyos_Video :: PrintMessage ("To Play a Game ~~:): / n");
? Class_pyos_video :: PrintMessage ("pyos>");
? / * Initialize the message queue used by the Kernel, and a message queue that must exist in the global situation * /
KernelMessageQueue.init (kernelMessage, kernelMessageMaxlength);
• / * Define the message queue of kernel as the current message to receive the queue to accept the message issued by the keyboard * /
? ReceiveMessageQueue = & kernelMessageQueue;
? / * You can now update the keyboard interrupt * /
Class_pyos_keyboard :: init (); // Keyboard class initialization
Class_pyos_keyboard :: openinterrupt (); // Open the keyboard interrupt
?
? / * Enter the message loop below * /
? Struct_pyos_Message Message;
? Bool exitMessageloop = false;
? While (! exitMessageloop) {
??? / * Remove the message from the message queue, the READDATA return value indicates the number of messages obtained, if it is 0, indicates that the message is not taken * /
??? if (kernelMessageQueue.ReadData) {
????? f (message.MessageType == pyos_message_type_keyboard) {// keyboard message
??????? // acquire scanning code from the message, and call the translation function to translate this scanning code, get the ASCII code
??????? char ch = class_pyos_keyboard :: traslatescancodetoasciicode (message.keyboardscan);
??????? / * If it returns 0, it means this is a function key * /?
??????? if (! class_pyos_keyboard :: stateKey.down || CH == 0) {// ignore the release button, the scan code of the function key
??????????????????
???????}?
??????? Else if (ch == '/ n') {// Indicates the entered enterprise
?????????? / * check if the buffer is empty * /
????????? f (buffer [0]) {?????????????
???????????? * check if the input is "game" * /
??????????? IF (buffer [0] == 'g' && buffer [1] == 'a' && buffer [2] == 'm' && buffer [3] == ' E ') {????????????? // Turn into the game
????????????? / * initialize the game, mainly the message queue of the initialization game * /
????????????? gameinit ();
?????????????? * Define the game for the current reception message * /
????????????? receiveMessageQueue = & gameMessageQueue;
????????????? / * transferred to the game * /
????????????? game_push_box_main ();
?????????????? * game exit, restore yourself to the queue of the current received message * /
????????????? receiveMessageQueue = & kernelMessageQueue;
????????????? / * clear screen, print information * /
?????????????? class_pyos_video :: clears ();
?????????????? Class_pyos_Video :: PrintMessage ("GameOver ~~: p / n");
???????????}
??????????? else {
????????????? / * output error message * /
????????????? Class_pyos_Video :: PrintMessage ("/ NYOUR INPUT IS NOT A Command: (", CLBROWN);
???????????}
?????????} ?????????
????????? / * Because it is a key button, the user's input buffer * /
??? ?????? for (int i = 0; i <4; i) {
??????????? buffer [i] = 0;
?????????}
????????? buffer_count = 0;
????????? / * displays a new prompt * /
????????? Class_pyos_Video :: printmessage ("/ n");
????????? Class_pyos_Video :: PrintMessage ("pyos>"); ?????????
???????}
??????? else {
????????? / *, if you print characters, print * /
????????? IF (CH> = 32 && ch <= 126) {
??????????? buffer [buffer_count % 4] = CH;
??????????? Class_pyos_video :: PrintMessage (CH);
?????????}
???????} ???????????????????
?????}
???}
??? __ASM __ ("hlt"); // downturn, release CPU usage
?
}
Although the code grows, it is very clear, it is more readily readily read. Let's take a look at it.
After entering the pyos_main () function, the system calls class_pyos_system :: init (); to perform the initialization of the kernel, it completed the initialization work of the overall descriptor table and the interrupt meter, this work has previously a few experiment reports There is a detailed description, you don't say more, you can look at its source code to understand what tasks they have completed. After the kernel initialization is completed, the system calls class_pyos_video :: printMessage () Print some welcome information, then the system has established a message queue for the kernel, and defines a pointer to the message queue that is currently accepting the message, making it point to the system. Queue to indicate that the current is a message from the system kernel, this is
? / * Initialize the message queue used by the Kernel, and a message queue that must exist in the global situation * /
KernelMessageQueue.init (kernelMessage, kernelMessageMaxlength);
• / * Define the message queue of kernel as the current message to receive the queue to accept the message issued by the keyboard * /
? ReceiveMessageQueue = & kernelMessageQueue;
These two statements are completed. For message queues, since it is newly implemented in this experiment, I will tell it in detail below.
The PYOS of this experiment is a message driver using it. It is simply that the system completes the initialization work, then enter a message loop, and keeps no messages in the expedition message loop, if there is a message, remove it. The message is a structure, it has a member being used with a flag message category, and some members are used with the parameters of the message, the message category is used to tell the message, the recipient is what message, the parameter of the message is used to send to the message The recipient passes the data. Once the application gets the message, some processing can be performed according to the category of the message.
PYOS message queue is implemented in a row column. The definition of this loop queue is in the buffer.h file, which defines two most important functions, one is putdata (), used to put the message into the queue, and One is getData () to remove messages from the message queue. The principle and implementation of the loop queue, there is a very detailed description of any books in the data structure. Everyone will be very familiar with this, and it will not be detailed. If you are interested, friends can look at Buffer.h Source code, there is a very detailed note.
The main job of PYOS keyboard interrupts is to read the keyboard scan code from the 0x60 port of the keyboard controller. , Then put this message into the kernel message queue, its work is completed.
When the keyboard interrupt program puts a message in the message queue of the kernel, the main program will find message queues in the next loop, and then have messages in the message queue, then the kernel calls the getData () function to get the message, and then do this message Processing, this is very clear in the code above.
Below, we will take a look at the core content of this experiment, the keyboard handler of PYOS.
?
PYOS keyboard handler
In the above program we can see that the following two statements are performed before the kernel performs the message loop:
Class_pyos_keyboard :: init (); // Keyboard class initialization
Class_pyos_keyboard :: openinterrupt (); // Open the keyboard interrupt
The role of these two statements is to initialize the keyboard interrupt, and open the keyboard interrupt, that is, allow the keyboard to make an interrupt request to the CPU (when Pyos is just booted, it is shielded all interrupts). Let's take a look at what these two functions have finished doing. First, look at the first function: / * Initialize keyboard * /
Void class_pyos_keyboard :: init ()
{
? / * Initialization status key * /
? StateKey.down = false;
? StateKey.Altdown = false;
? StateKey.ctrldown = false;
StateKey.shiftdown = false;
? / * Install the keyboard interrupt, the interrupt number is 0x21 * /
Class_pyos_Interrupt :: InstallInterrupt (0x21, (void *) pyos_asm_interrupt_handle_for_keyboard);
• * This is not allowed to interrupt, because it is possible that the primary call will prepare some other resources before the license keyboard interrupt, so when the main call program
? ** After you are ready, call the OpenInterrupt function license interrupt by yourself.
? * /
}
The comments in the program have been very detailed, and it is necessary to explain that Pyos has a STATEKEY structure to save the keyboard state, such as which function key, shift, alt, and ctrl are pressed, this Is it a button or release button or the like. At the beginning of the function, set various states to the initial value, which then calls an installinterrupt () function to install the keyboard interrupt.
The interrupt of PYOS is done by the installation method. In the first few experiment reports we already know that the operational system has established an interrupt vector table in memory, which stores an interrupt descriptor for a group, and each interrupt descriptor contains a corresponding interrupt processing function. Function pointer. When an interrupt occurs, the corresponding interrupt descriptor is acquired in this interrupt vector table, thereby obtaining a function pointer of the corresponding interrupt processing function, and the interrupt handler can be invoked. When PYOS is initialized, the interrupt vector table is established in the class_pyos_interrupt :: init () function, when the system does not know what interrupts will be interrupted, and what their interrupt handler function pointer is, so that the system will be unified An interrupt descriptor for an interrupt (CPU a total of 256 interrupts) is set to a default interrupt descriptor, while it is installed by each interrupt service program when needed. The so-called installation is actually used to replace the old interrupt descriptor in the interrupt vector table with a new interrupt descriptor. This is the work that the installinterrupt () function is completed. After the interrupt installation is complete, the system only updates the interrupt vector table. The corresponding entry, so it is followed, the system calls the openinterrupt () function to open the keyboard interrupt, the so-called open interrupt, actually to reset the interrupt controller
8259A
The shield register makes it no longer shielding the keyboard interrupt, the following is the code of the OpenInterrupt () function:
/ * Open the keyboard interrupt * /
Void class_pyos_keyboard :: openinterrupt ()
{
? / * License keyboard interrupt * /
Class_pyos_system :: toport (0x21, 0xfd);
}
Very simple, below I think we can take a look at one of our heaviest parts, actually being called by the CPU:
/ * Interrupt actual processing function * /
void class_pyos_keyboard :: handleinterrupt () {
? // read the scan code from the 0x60 port of the keyboard controller, otherwise the keyboard will not interrupt the second time because the keyboard is waiting for the user to read data from 0x60 port.
• unsigned char ch = class_pyos_system :: fromport (0x60);
? // Filter special bytes first
? if (ch == 0x0) {// 0x0 indicates that the button will generate an error.
??? Return;
?
? ELSE IF (CH == 0xE0) {// Detect whether it is a prefix of an extended code
??? // Set an extended code tag
??? EX = true;
??? // Return directly, wait for the next interrupt to send real scan code
??? Return;
?
? Else {???
??? // Construct a keyboard message
??? Struct_pyos_message message;
??? Message.MessageType = pyos_message_type_keyboard;
??? if (ex == true) {
????? message.keyboardscancode.keyboardscancodehighhjar = 0xE0; // Let the high byte are expanded
???}
??? Else {
??? message.keyboardscancode.keyboardscancodehighhjar = 0;
???}
??? EX = 0; // Empty expansion code logo???
??? Message.keyboardscancode.keyboardscancodelowchar = ch; // Let the low byte as the true scan code sent???
??? * Send a message to the application, ReceiveMessageQueue points to the queue of the received message * /
??? ReceiveMessageQueue-> Putdata (Message);
?
}
With the background introduced earlier, it is very simple to see this function, so, it will not be more expensive, directly enter the next link.
?
PYOS processes for user input
It is actually written here, the main issues of this article are basically described, although there are some small details, such as how Pyos identifies and saves user input.
Let's take a look at how Pyos recognizes user input. When the kernel gets the message from the message queue, the scan code is obtained from the parameters of this message, and then the system calls the translatescancodetoascialode () function to translate this scan code into the ASCII code, which is actually a process of querying the set 1 table. If you are interested, you can look at its source code. If the pressed is a function key, translatescancodetoascialode () will return 0, then save the function key status in StateKey, otherwise, return this key ASCII code. This allows the kernel to identify the user's input.
How to save the user input for PYOS, in this experiment, PYOS uses the simplest and most stupid and most spacious method: P, PYOS defines an array buffer for saving user input, We are estimated to refer to this array into the user input buffer. It sequentially places the input into the buffer, and then when the user enters the carriage return, it is detected that the value in the buffer is "Game", if yes, It is considered that the user will press Enter to enter "Game", that is, the user enters the "Game" command, then the game program is transferred. If not, the user thinks that the user enters an unrecognizable command, so output an error message, And clear the buffer, waiting for the user to enter next time. Here, there is a detail. After the game program is toned, the user keyboard message should be received by the game program instead of the kernel, so, the gamper's message queue has become a queue currently received, so in formal Before transferring the game program, the system also implemented the following two statements:
/ * Initialize the game, mainly the message queue of the initialization game * /
Gameinit ();
/ * Define the game for the current reception message * /
ReceiveMessageQueue = & gameMessageQueue;
Since the game is just a demonstration, it is not the protagonist of our experiment, so it is not described in detail on the game, but the principle used is completely introduced with this report, there is also a very detailed source code. Note, if you are interested, you can see, huh, you are very welcome to write games for PYOS ^ _ ^
?
?
Thoughts on the PYOS message drive mechanism
I have no chance to read the source code of Windows, so I don't know how the message driver mechanism in Windows is implemented, or what is optimized, in short, I have some questions and ideas when I realize the message mechanism of PYOS. Here, I hope to discuss with everyone.
I personally think that the message mechanism has some drawbacks. For example, let's take a look at the message mechanism in PYOS. First, there is a large cycle in the kernel. This loop has remained the message in the message queue, then pass the Switch () function to detect the message. Type, then go to the appropriate processing statement for processing.
After the Switch () statement is compiled by the compiler, there will be many instructions such as CMP, JNE, JMP. Jumping instructions such as JMP will greatly destroy the CPU's water supply mechanism, and make the CPU prefetched instructions scrapped, and Make the failure chance of cache, therefore will reduce the efficiency of the system, if you have tens of thousands of messages, and put a message that is frequently triggered in the last CASE statement of Switch (), Then this statement will first execute 10,000 CMP and JMP before being executed, this efficiency should be quite low! (Note: For the water supply mechanism of the CPU, I am currently inference according to the situation described in the CPU composition in the textbooks, Kylix advocates, the current CPU has some new features for the water supply mechanism, Intel is This is also a lot of optimization, but I don't know what INTEL has made this optimization. Therefore, it is still in accordance with the knowledge you have learned. If you have a deep research on this, I hope you Can point me points to me)
Second, the message is a pre-defined structure, and its number of parameters is fixed. For example, in Windows, there are only two parameters. But the two parameters are not enough? Some messages may not require parameters, some messages only need a parameter, and some messages require more parameters because they have more data to be passed to the recipient. For this case, some other methods can only be handled. In one byte of the message parameters, then remove this data through some translation functions, such as the translation message of the translateMessage (), which we often see next to Windows, and this obviously aggravates the burden on the programmer. And the readability and simpleness of the program are affected. So how to solve the above problem? My current idea is in the later PYOS system, transform PYOS into an event-driven kernel instead of a message driver. The so-called event driver, I understand that the processing function of the event's trigger calling the event is handled instead of sending a message to this processing function. For a simple example, when the PYOS keyboard interrupts read the keyboard to scan code, it no longer constructs a message into the kernel message queue, but directly calls a function of the process of currently handling the keyboard event.
Of course, this is only an idea, there are still many details I don't want to understand, such as how this event handler is obtained? What way the parameters passes? If there are multiple events, how to respond, how to queue, how to deal with? Very welcome friends to communicate, advice :) Below is some of this experiment
740) this.width = 740 "Border = undefined> Original: http://purec.binghua.com/Article/showArticle.asp? ArticleId = 104