Design of PC/104-based graphical interface control software
2026-04-06 07:24:41··#1
Abstract: Establishing graphical user interface (GUI) software is of great practical significance in the operating system selected for embedded PC/104. This article discusses the method and related issues of establishing a GUI based on message processing mechanism for relevant industrial control projects. Keywords:Graphical User Interface; Operating System; Control System 1 IntroductionIn the emerging field of embedded PC/104 applications, due to the unique characteristics of the hardware, the user's operating system software often needs to have the following characteristics: ● Small operating system footprint, approximately a few megabytes or tens of megabytes; ● Good system stability; ● Low hardware configuration requirements; ● High software development flexibility; ● Direct hardware operation and fast control response. Software based on such operating systems sometimes requires providing a good human-machine interface (HMI). However, these operating systems often have significant shortcomings in graphical interface capabilities compared to Windows. To address this challenge, I have actively explored the development of a graphical interface for injection molding robot control software, hoping to contribute to related software development. Establishing a user-interactive graphical interface requires more than just drawing graphics on the system (these systems often provide drawing functions). The most crucial aspect is establishing the software's response to user actions on the graphics. Similar to Windows, the system should respond to user clicks on various functional icons (such as buttons) on the graphics. Therefore, the key to building a graphical interface is establishing an interaction mechanism between the user and the software. This issue will be discussed in detail in the following sections. 2. Event Control Mechanism Software programs have two basic control mechanisms: sequential (or process-driven) mechanisms and event control mechanisms. Programs designed using a sequential mechanism have a clear start, a clear process, and a clear end. This control mechanism is not conducive to establishing a user-friendly HMI. There is another program control mechanism, the event-driven mechanism. Programs designed using the event-driven mechanism are controlled by the occurrence of events. Such a program control mechanism provides users with a better human-computer interface. The event-driven mechanism is particularly suitable for programs with strong human-computer interaction, giving users more control over program execution. Event-driven control mechanisms are commonly used in Windows-based software, where software development often utilizes visual development platforms like VC and VB. These platforms typically provide built-in event-driven mechanisms, requiring users to design event handlers without delving into the internal workings of the mechanism. However, in the development environment discussed in this paper, a custom event-driven platform must be built, increasing the difficulty and complexity of program design. The event-driven mechanism significantly reduces the possibility of message loss. For example, if a new message is generated while the program is processing a current message, the event-driven mechanism adds the new message to a message queue, processing it only after the current message is finished, thus preventing message loss. This program control method is well-suited for systems that respond promptly to user requests and establish a user-friendly interface. This is more user-friendly than programs designed using a sequential mechanism. 3. Building an Event-Driven Mechanism Platform In user interface design, events are the various signals generated when users operate through various input devices, also known as messages. A message is a fundamental, triggering signal used to connect users, computer systems, and application software. For example, a user pressing a key on the keyboard creates a message, as this action sends a triggering signal to the system, causing it to change from one state to another. Messages can be generated in many ways, primarily by the user pressing a key on the keyboard or moving the mouse and pressing another key. The generator of a message is called the message source. Message sources include the mouse, keyboard, serial port interrupts, relevant software tools, device drivers, other input devices, other positioning devices, and even the application itself. Since events are the most fundamental factor in triggering human-computer interaction, the key to human-computer interaction is studying message processing techniques and algorithms generated by events. The quality of a user interface depends to some extent on the quality of event and message management technology. 3.1 Implementation Method of Event-Driven Mechanism The following is a data structure of the message queue used to load messages generated by keyboard and mouse events in the injection molding robot control software I participated in: struct event_define { struct event_define *Last; unsigned char ScanCode; unsigned char KeyState; int MouseState; int CursorX; int CursorY; struct event_define *Next; }; The functions of each element in this structure are described below: ● The pointer Last in struct event define *Last is used to store the address of the previous message queue record; ● The pointer Next in struct event define *Next is used to store the address of the next message queue record. The contents of these two pointers are completed during the message queue initialization process, forming a chained queue with the head and tail pointing to the message data record in the message queue, which defaults to 0. ● `unsigned char ScanCode` stores the key value of the key pressed when a keyboard press event occurs. ● `unsigned char KeyState` stores the key state (pressed or released) of the key when a keyboard press event occurs. ● `int MouseState` stores the mouse message content when a mouse event occurs, such as left mouse button pressed or released. ● `int CursorX` and `int CursorY` store the coordinates of the mouse on the screen when a mouse event occurs. In this project, message loading is done using interrupts. The specific methods for interrupt handling are briefly described below. In the program, when mouse, keyboard, and serial port data events occur, these events are treated as interrupts. The advantage of this is that the CPU does not need to spend a lot of time checking whether external events have occurred. Because the timing of interrupt events is unpredictable, once an external event requests an interrupt, it sends an electrical signal to the CPU's interrupt signal receiving pin, which the CPU can immediately detect. For example, when a key is pressed on the keyboard is random; the CPU doesn't need to repeatedly check the keyboard state but can execute other programs. Once a key is pressed, the keyboard immediately generates an interrupt request signal. Upon receiving this signal, the CPU immediately executes the interrupt service routine for the keyboard. After completing the service, the CPU resumes executing the interrupted program logic. The advantages of interrupt-driven event handling are: fast execution speed, real-time processing, and minimal CPU time consumption. In the injection molding robot control software, the main task of the interrupt service routine is to load the interrupt event into the corresponding message queue. For example, when a key is pressed, the currently pressed key value and its state are added to the message queue, and then the tail pointer is moved to the next message queue data record. If the head and tail pointers point to the same message queue record before a keystroke, the tail pointer will point to the next message queue record after the keystroke, meaning the head and tail pointers will now point to different records. If a new message arrives, it is added to the current message queue record pointed to by the tail pointer, and the tail pointer is moved forward to the next record. The main program uses a loop to continuously check if the head and tail pointers point to the same address. If they do, the loop continues, checking again. If a check finds that the head and tail pointers point to different addresses, a message has been added to the message queue. The main program reads the message content, moves the head pointer forward to the next record, processes the message, and then checks again. If they do not, the program processes the message; otherwise, it continues the loop. This process involves external events adding messages to the message queue, moving the tail pointer forward. The main program then reads the data records from the message queue in a first-in, first-out (FIFO) order, moving the head pointer forward and processing the messages accordingly. This event-driven processing method is also known as a message handling mechanism, as shown in Figure 1. A special case can easily occur during this process: when message density is high and the main program's processing speed is slower than the rate at which messages are added to the message queue, the queue will eventually be full while new messages continue to be generated. There are two ways to handle this: one is to ignore new messages; the other is to overwrite existing messages with new ones. This program ignores new messages until a new data record becomes available in the message queue before adding the generated messages. If this happens, messages generated after the queue is full and during the period when a new data record becomes available will not be responded to or processed, which is unacceptable in actual program execution. To avoid a situation where the main program's processing speed is slower than the message arrival speed, three measures can be taken: ● Write the interrupt service routine in assembly language; ● Keep the main program's message handling section as concise as possible; ● Set the number of data records in the message queue to be sufficiently large. [align=center]Figure 1 Message Handling Mechanism[/align] Writing the interrupt service routine in assembly language makes it more concise, consumes less CPU time, and thus provides more time for the main program to run. This means that situations that might have previously caused data blocking can be avoided by using an assembly language interrupt routine. The increased time allocated to the main program allows it to complete message processing, promptly freeing up data records in the message queue for new messages. Keeping the main program's message handling section as concise as possible will speed up the main program's message processing speed, making it faster than the message loading speed. Setting the number of data records in the message queue to be sufficiently large provides a large enough space for new messages, acting like a large buffer to store new message data. This ensures that even if new messages arrive frequently, there is still sufficient space to store them, indirectly providing more time for the main program to process messages. However, the size of the message queue data record space is actually limited, so this problem is solved by a combination of three methods in program design.