Introduction
In embedded software development, including microcontroller development, software architecture is a critical consideration for developers. The software architecture is vital for the overall stability and reliability of the system. A suitable software architecture is not only clearly structured but also facilitates development. I believe that most developers in the early stages of embedded or microcontroller software development adopt a simple sequential execution architecture (I did). In embedded software development, program architectures can be mainly divided into three types, which this article will elaborate on.
1. The Significance of Software Architecture
A good program architecture can be seen as a dividing line between an experienced engineer and a beginner. Software architecture is friendly to developers; you can decide which tasks to execute first, which tasks to execute next, or which tasks will synchronize with certain events, etc. The specific methods for solving these problems vary under different software architectures.The greatest help that software architecture provides to developers is: it helps them grasp the framework of the entire project. Once you become proficient in a particular program architecture, you will be able to quickly locate and resolve bugs that arise in the system. Of course, I recommend choosing a suitable software architecture based on your needs, and the specific reasons will be discussed later in the article.
2. In-Depth Introduction to Three Different Program Architectures
The three commonly used software architectures are: sequential execution front-and-back system, time-slice polling system, and multitasking operating system. To provide a clearer understanding, I will introduce an example using these three software architectures. This example includes four tasks: key scanning, sound and light alarm, display refresh, and ultrasonic distance measurement. The specific function of this example is to set a threshold for measuring distance via keys, triggering a sound and light alarm when the measured distance falls below the set threshold, and displaying the measured distance in real-time on the screen (this application is a specific embodiment of a car reversing radar).
- 2.1 Sequential Execution Front-and-Back System
In the sequential execution front-and-back system, I will place the keyboard scanning in a querying manner within while(1), while using interrupts for display refresh and ultrasonic distance measurement. After obtaining the measured distance in the interrupt service function, it will be displayed, while key detection and sound-light processing will occur in the main function’s loop. Thus, the entire program executes in a synchronized manner using variable flags between the main loop and background interrupts, as shown in the corresponding program code:
Main function of the sequential execution front-and-back system
Interrupt service function of the sequential execution front-and-back systemThe advantage of this architecture is its simplicity and ease of understanding, while the disadvantage is that if each task occupies too much CPU time, it can lead to poor real-time performance, such as in key detection.
- 2.2 Time-Slice Polling System and Multitasking Operating System
The time-slice polling method typically appears in operating systems, meaning it belongs to the operating system. However, what is discussed here is time-slice polling based on the front-and-back system. The essence of the time-slice polling method is to select a timer, increment the count value on each timer interrupt, and execute tasks in the main loop based on this count value, which represents the time slice for task polling. In this example, if a time-slice polling system is adopted, we first select any timer from the main control chip, with the timer’s timing cycle determined by us. To ensure real-time performance and operational efficiency, this value is usually set to 10ms, 30ms, 50ms, etc. I would set the key scanning polling value to 20ms, as the key bounce duration is generally around 20ms. This approach achieves debouncing while ensuring no key detection is missed; the display refresh is set to 30ms, and if you feel the refresh response is slow, you can modify this polling value for improvement; the ultrasonic distance measurement polling value is set to 100ms, meaning distance measurement is triggered every 100ms, which is sufficient for most situations.The program code is as follows:
Main function of the time-slice polling system
Timer interrupt function of the time-slice polling systemIt can be seen that the time-slice polling method has significant advantages over sequential execution, combining the benefits of both sequential execution and some advantages of operating systems.
- 2.3 Multitasking Operating System
The operating system itself is quite complex, and the management and scheduling of tasks at the underlying level is intricate and challenging. However, we generally regard the operating system as a tool or platform; our goal is to utilize its functions rather than develop an operating system. I have used small real-time operating systems like uCOS and FreeRTOS, as well as large operating systems like Linux. With an operating system, both program stability and development efficiency improve significantly. When using an operating system, we need to learn and understand its scheduling and communication methods. In reality, not many people can effectively use an operating system; instead, the majority run bare-metal systems, which also relates to specific product requirements, as many simple systems only require bare-metal solutions.I will not delve too deeply into the operating system itself here, as it is indeed quite complex. The code in the following illustration shows the program structure for controlling an LED with a key in FreeRTOS, which you can compare:
Main function in the FreeRTOS multitasking system
Task callback function in the FreeRTOS multitasking operating system
3. How to Choose the Right Software Architecture
I have used various MCUs for project development, such as STM32, STC15, Nuvoton, etc., and have encountered complex design requirements, such as in-vehicle intelligent systems and smart homes. I have worked with operating systems like uCOS, FreeRTOS, and Linux, and when returning to bare-metal development, I inevitably ponder the design issues of the complete system’s software architecture. I believe that most readers also engage in bare-metal development.I think there is no best software architecture (program architecture), only the most suitable one. Different application scenarios require different program designs, and simply comparing which program architecture is the best is not practically meaningful. Next, we will analyze specific application scenarios. In systems with clear logic and single functions, the sequential execution front-and-back architecture is very suitable, as this software architecture often meets most of our needs, such as in rice cookers, induction cookers, and voice-controlled light bulbs. In cases where resources are limited and system reliability is crucial, this method is very appropriate, as it consumes relatively little system resources, sacrificing only one timer. However, choosing this program architecture requires careful consideration of time slice allocation. Finally, in systems with complex functions and challenging logical control, a multitasking operating system is suitable, such as in video surveillance systems, drones, and other application scenarios.As an embedded software engineer, mastering these three software architectures is essential, as they provide us with more options and considerations when designing programs. Each different program architecture has its own advantages and disadvantages, which we need to practice diligently to appreciate their intricacies.
Source: Toutiao – Embedded on the Left, C Language on the Right
Link: https://www.toutiao.com/i6804446207872598539/
[1] C Language State Machine Programming Ideas
[2] Pitfalls Encountered When Writing MODBUS Protocol Code
[3] Common Communication Interfaces for Microcontrollers: I2C, SPI, UART, etc.
[4] Bootloader for Microcontrollers, Enabling Easy Program Upgrades for Users
[5] How to Choose Power Filters and Important Parameters of Power Filters?
[6] A Boost Circuit with Four Components, Easily Doubling the Voltage