Source | Yu Linjun
Overview
1. Simple Sequential Execution Program: This method is used by most people. There is no need to think about the specific architecture of the program; just write the application according to the execution order.
This application is relatively simple and is generally used as an entry-level simple usage scenario where real-time requirements are not too high. The program design is straightforward, and the logic is clear. However, when the main loop logic is quite complex, without a complete flowchart, it can be difficult for others to understand the program’s execution logic.
Below is a model of a sequential execution program.
int main(void) { uint8 TaskValue; InitSys(); // Initialize while (1) { TaskValue= GetTaskValue(); switch (TaskValue) { case x: TaskDispStatus(); break; ... default: break; } } }
This program is characterized by the default program running continuously in the background loop, with the Interrupt Service Routine (ISR) generating corresponding interrupt flags, and the main program running tasks related to the interrupt flags. The general implementation follows this thought process:
By setting flag variables, the foreground can respond to interrupts by setting or resetting the flag variables, achieving event signal acquisition, and then processing the corresponding events or data in the background main loop, transferring the program flow to the main program.
Front and Back Execution Program
void IRQHandler(void){ if(GetITStatus == 1) { SysFlag = 1; GetITStatus = 0; }}int main(void) { uint8 TaskValue; InitSys(); // Initialize while (1) { TaskValue= GetTaskValue(); switch (TaskValue) { case x: if(SysFlag == 1) { TaskDispStatus(); SysFlag == 0; } break; ... default: break; } } }
When people see the Time-Slice Round Robin method, they usually compare it with operating systems. It is not that operating systems include this method, but rather that it forms a time-slice round-robin architecture in conjunction with time management in front and back programs.
This architecture is already very close to RTOS, with time management, interrupt management, and task management all present. However, RTOS will make deeper modifications to the kernel, with more complex features such as delay-based thread switching and preemptive task switching.
Time-Slice Round Robin Program
Time-slice management is mainly achieved through multiple uses of timers, changing flag bits at regular intervals, and then the main program judges the truth of the flags to execute different tasks based on different times.
Since this architecture has well-structured code, I will describe it in detail.
Step
1: Initialize the corresponding timer: Note to set the timer’s interval frequency; you can set it according to the chip’s performance. For example, set the timer interrupt to 1ms or 10ms. The timer part in the round-robin architecture has the same function as the timer part in the operating system. Too frequent interrupts affect the efficiency of the main program’s sequential execution; too long intervals result in poor real-time response.
2: Set a function structure flag for the tasks running on the timer to perform time counting and flag operations.
#define TaskTAB_NUM 6 //Number of tasks__packed typedef struct{ u8 flag; //Timer flag u32 numcount;//Count according to the timer interrupt u32 target; //Set target timer value int(*fun)(void);//Set the target task function to be executed at the timer}TaskTimTypeDef
Step
3: Establish a task table through the structure table to determine the task execution schedule.
When defining variables, we have already initialized values. These initializations are very important and relate to specific execution time priorities that need to be mastered.
/*MdmSendTimTab task function default cycle, unit 5ms, TIM7*/static TaskTimTypeDef TaskTimTab[TaskTAB_NUM] ={ {1, 0, 30000, *Task00}, //Task00 3000 value is the target value; if it feels too slow, this value can be set lower {1, 0, 3000, *Task01}, //Task01 {1, 0, 300, *Task02}, //Task02 {1, 0, 30, *Task03}, //Task03 {1, 0, 3, *Task04}, //Task04 {1, 0, 0xFFFFFFFF, *Task05}, //Task05 //Tasks can be added according to TaskTAB_NUM};int Task00(void)//Write task function according to structure template (int(*fun)(void);){...}//Assuming execute button operationint Task01(void){...}//Assuming execute USART sending taskint Task02(void){...}//Assuming execute CAN communicationint Task03(void){...}//Assuming execute relay controlint Task04(void){...}//Assuming execute network parsingint Task06(void){...}//Assuming execute idle
Step
4: Timer interrupt service function, counting according to the required time and flag operations.
//Timer interrupt service function void TimerInterrupt(void) { for(char i=0; i<TaskTAB_NUM; i++) { if(TaskTimTab[i].flag == 1) { (TaskTimTab[i].numcount< TaskTimTab[i].target)//Compare current timer count with target time (TaskTimTab[i].numcount++):(TaskTimTab[i].flag = 0); } } }
Step
5: The main function executes the task functions.
int main(void) { InitSys(); // Initialize while (1) { for(char i=0; i<TaskTAB_NUM; i++)//// Task processing { if(TaskTimTab[i].flag == 0) { if(TaskTimTab.flag == 0) { TaskTimTab[i].flag = 1; TaskTimTab[i].numcount= 0; TaskTimTab[i].fun(); } } } }
The embedded operating system is a more optimized execution framework, particularly suitable for projects that require complex functionality and strong extensibility. RTOS is a highly efficient real-time multitasking kernel optimized for different processors, capable of providing similar API interfaces for dozens of series of embedded processors MPU、MCU、DSP、SOC, etc. This forms the basis for device-independent application development. Therefore, C language programs based on RTOS have great portability. Currently, operating systems for micro-embedded or microcontrollers include VxWorks、UCOS、Free RTOS and domestic RTT. These operating systems are quite similar, with basic functions like task management, inter-task synchronization and communication, memory management, real-time clock services, and interrupt management services.
(Image source: Blog)
RTOS continues to add features like task suspension and recovery, blocking thread switching, etc., which is an accumulation of functions and further optimization. Since this time is not a discussion of RTOS, I have learned to use UCOS, RTT, and Free RTOS. Due to space and time limitations, I will take time to further study and introduce the RTOS system architecture.
Currently, there are many RTOS systems, and many projects tend to use RTOS. However, through the analysis of several architectures, it is clear that different projects require different architectures; not all projects need or are suitable for using RTOS. For example, if the coupling of tasks in the project is too high, using RTOS would require a lot of task synchronization, making it impossible to plan threads. In this case, some bare-metal architectures may be more suitable.
1.Virtual Round Table Meeting Part 1 – Embedded System Information Security
2.The secret of Huawei’s 5G is actually in the hands of a Turkish person?!
3.The latest semiconductor rankings are out, and Nvidia achieves 50% growth!
4.[MCU] A “flexible and resource-saving” IAP upgrade solution
5.Why is RISC-V becoming a hot topic?
6.A suitable introduction to Harmony OS for developers~
Disclaimer: This article is a reprint from the internet, and the copyright belongs to the original author. If there are any copyright issues, please contact us, and we will confirm the copyright based on the copyright certificate you provide and pay for the manuscript or delete the content.
Leave a Comment
Your email address will not be published. Required fields are marked *