1. Simple front-and-back sequence execution program. This type of writing is the method used by most people. You don't need to think about the specific architecture of the program, you can write the application directly through the execution sequence.
2. Time slice polling method, which is a method between sequential execution and the operating system.
3. Operating system, this method should be the highest level of application writing.
Let's talk about the advantages and disadvantages of these three methods and the scope of adaptation.
First, the sequential execution methodThis method, this application is relatively simple, real-time, parallel requirements are not very high, it is a good method, the program design is simple, the idea is clearer. But when the application is more complicated, if there is not a complete flow chart, I am afraid that it is difficult for others to understand the running state of the program, and as the function of the program increases, the brain of the engineer who writes the application becomes confused. This is not conducive to upgrade maintenance, and is not conducive to code optimization. I wrote a few more complicated applications, I just used this method at the beginning, but although I can achieve the function, my thinking has been in a state of confusion. The program has not been able to satisfy itself.
This method is used by most people, and the education we receive is basically using this method. For those of us MCU engineers who have not learned the data structure and program architecture, it is undoubtedly difficult to improve the design of the application, and it is difficult for the applications written by different engineers to mutually benefit and learn.
I suggest that if you like to use this method, if you write a more complex application, you must first clear your mind, design a complete flow chart and then write the program, otherwise the consequences will be serious. Of course, the program itself is very simple, this method is still a very necessary choice.
The following is a program model that is executed sequentially, which is convenient for comparison with the following two methods:
Code
/************************************************* *************************************
* FuncTIonName : main()
* DescripTIon : main function
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Int main(void)
{
Uint8 keyValue;
InitSys(); // Initialize
While (1)
{
TaskDisplayClock();
keyValue = TaskKeySan();
Switch (keyValue)
{
Case x: TaskDispStatus(); break;
. . .
Default: break;
}
}
}
Second, time film pollingTime slice polling is mentioned in many books, and many times it comes with the operating system, which means that this method is often used in operating systems. However, the time slice polling method we are going to talk about here is not to hang under the operating system, but to use this method in the front and back programs. This is also the method to be explained and introduced in detail.
For the time slice polling method, although many books have been introduced, most of them are not systematic, just mentioning concepts. Below I will introduce this mode in detail, and refer to the method of a time slice polling architecture program established by other people's code, I think it will give some beginners some reference.
Here we first introduce the reuse function of the timer.
Use one timer, which can be any timer. There is no special explanation here. If there are 3 tasks below, then we should do the following work:
1. Initialize the timer, here assumes that the timer's timer interrupt is 1ms (of course you can change it to 10ms, this is the same as the operating system, the interrupt is too frequent and the efficiency is low, the interrupt is too long, and the real-time performance is poor).
2. Define a value:
Code
#define TASK_NUM (3) // The number of tasks defined here is 3, indicating that there are three tasks that will use this timer to time.
Uint16 TaskCount[TASK_NUM] ; // Here are three variables defined for the three tasks to store the timing values.
Uint8 TaskMark[TASK_NUM]; // Also corresponds to three flag bits, 0 means the time has not arrived, and 1 means the time is up.
3. Add in the timer interrupt service function:
Code
/************************************************* *************************************
* FuncTIonName : TImerInterrupt()
* Description : Timed interrupt service function
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TimerInterrupt(void)
{
Uint8 i;
For (i=0; i "TASKS_NUM; i++)
{
If (TaskCount[i])
{
TaskCount[i]--;
If (TaskCount[i] == 0)
{
TaskMark[i] = 0x01;
}
}
}
}
Code explanation: The timer interrupt service function judges one by one in the interrupt. If the timing value is 0, it means that the timer is not used or the timer has completed timing, and no processing is required. Otherwise, the timer is decremented by one. When it is known to be zero, the corresponding flag bit value is 1, indicating that the timing value of this task has arrived.
4. In our application, add the following code where you need the application timing. Let's take task 1 as an example:
Code
TaskCount[0] = 20; // delay 20ms
TaskMark[0] = 0x00; // Start the timer for this task
At this point we only need to judge whether TaskMark[0] is 0x01 in the task. The other tasks are added the same, and the reuse problem of a timer is achieved. Use the friends you need to try, the effect is good. . . . . . . . . . .
Through the above multiplexing of a timer, we can see that while waiting for a timing to arrive, we can loop through the flag bits and also perform other functions.
Loop judgment flag:
Then we can think about it, if the loop judges the flag, is it the same as the sequential execution procedure described above? A large loop, but this delay is more precise than the normal for loop, which can achieve precise delay.
Execute other functions:
So if we perform other functions when a function is delayed, make full use of CPU time, is it similar to the operating system? But the task management and switching of the operating system is very complicated. Below we will use this method to architect new applications.
The structure of the time slice polling method:
1. Design a structure:
Code
// task structure
Typedef struct _TASK_COMPONENTS
{
Uint8 Run; // Program run flag: 0 - no run, 1 run
Uint8 Timer; // timer
Uint8 ItvTime; // task run interval
Void (*TaskHook)(void); // The task function to run
} TASK_COMPONENTS; // task definition
The design of this structure is very important, one with four parameters, the comments are very detailed, not described here.
2. The task run flag is displayed. This function is equivalent to the interrupt service function. This function needs to be called in the timer's interrupt service function. It is isolated and ported and understood.
Code
/************************************************* *************************************
* FunctionName : TaskRemarks()
* Description : Task flag processing
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TaskRemarks(void)
{
Uint8 i;
For (i=0; i "TASKS_MAX; i++) // task-by-task time processing
{
If (TaskComps[i].Timer) // time is not 0
{
TaskComps[i].Timer--; // minus one beat
If (TaskComps[i].Timer == 0) // Time is reduced
{
TaskComps[i].Timer = TaskComps[i].ItvTime; // Restore timer value, new next time
TaskComps[i].Run = 1; // Task can run
}
}
}
}
Do you carefully compare the next function, is it the same as the timed reuse function?
3. Task processing:
Code
/************************************************* *************************************
* FunctionName : TaskProcess()
* Description : Task Processing
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TaskProcess(void)
{
Uint8 i;
For (i=0; i "TASKS_MAX; i++) // task-by-task time processing
{
If (TaskComps[i].Run) // time is not 0
{
TaskComps[i].TaskHook(); // Run the task
TaskComps[i].Run = 0; // flag cleared
}
}
}
This function is to determine when to perform the task, to achieve the task management operation, the application only needs to call this function in the main () function, and does not need to call and process the task function separately.
At this point, the architecture of a time-slice polling application is built. Is it very simple to see? This architecture only requires two functions, one structure, and an enumeration variable will be built for the application side.
Let's talk about how to apply it. Suppose we have three tasks: clock display, key scan, and work status display.
1. Define a structure variable as defined above:
Code
/************************************************* *************************************
* Variable definition
************************************************** ************************************/
Static TASK_COMPONENTS TaskComps[] =
{
{0, 60, 60, TaskDisplayClock}, // display clock
{0, 20, 20, TaskKeySan}, // key scan
{0, 30, 30, TaskDispStatus}, // Show working status
// Add your task here. . . .
};
When defining variables, we have initialized the values. The initialization of these values ​​is very important, and it has something to do with the specific execution time priority. This needs to be mastered by ourselves.
1 probably means that we have three tasks, no 1s to execute the following clock display, because our clock minimum unit is 1s, so it is enough to display once after the second change.
2Because the button will be jittery when pressed, and we know that the jitter of the general button is about 20ms, then we usually extend 20ms in the function of sequential execution, and here we scan every 20ms, it is very good, that is The purpose of debounce is achieved, and the key input is not missed.
3 In order to be able to display other prompts and work interface after the button, we design it once every 30ms. If you feel that the reaction is slow, you can make these values ​​smaller. The latter name is the corresponding function name, you must write this function name and the same three tasks in the application.
2. Task list:
Code
// task list
Typedef enum _TASK_LIST
{
TAST_DISP_CLOCK, // display clock
TAST_KEY_SAN, // key scan
TASK_DISP_WS, // work status display
// Add your task here. . . .
TASKS_MAX // total number of scheduled tasks available for allocation
} TASK_LIST;
Take a good look, the purpose of defining this task list here is actually the value of the parameter TASKS_MAX. Other values ​​have no specific meaning, just for the sake of clear surface tasks.
3. Write the task function:
Code
/************************************************* *************************************
* FunctionName : TaskDisplayClock()
* Description : Show task
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TaskDisplayClock(void)
{
}
/************************************************* *************************************
* FunctionName : TaskKeySan()
* Description : Scanning task
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TaskKeySan(void)
{
}
/************************************************* *************************************
* FunctionName : TaskDispStatus()
* Description : Work status display
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TaskDispStatus(void)
{
}
// Add other tasks here. . . . . . . . .
Now you can write tasks according to your needs.
4. The main function:
Code
/************************************************* *************************************
* FunctionName : main()
* Description : main function
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Int main(void)
{
InitSys(); // Initialize
While (1)
{
TaskProcess(); // task processing
}
}
At this point our time slice polls the application's architecture and it's done, you just need to add your own task function where we're prompted. Is it very simple, is there a feeling of operating system inside?
Do not try to see if the tasks do not interfere with each other? Running in parallel? Of course, it is important to note that when you transfer data between tasks, you need to use global variables. In addition, you need to pay attention to dividing tasks and execution time of tasks. When writing tasks, try to get the tasks to complete as soon as possible. . . . . . . .
Third, the operating systemThe operating system itself is a relatively complicated thing, the management of tasks, the implementation of the ability does not require us to understand. But it is very difficult to transplant. It is very difficult to say that although some people have said, "If you have used the system, you will not be using the pre-background program." But there aren't many people who can actually use the operating system, not only because the system itself is complex, but also requires a license (ucos is no exception, if it is commercial).
I don't want to introduce the operating system itself too much here, because not one or two sentences can explain it. The following is a list of the programs that should be written under UCOS. You can compare the advantages and disadvantages of each of these three methods.
Code
/************************************************* *************************************
* FunctionName : main()
* Description : main function
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Int main(void)
{
OSInit(); // Initialize uCOS-II
OSTaskCreate((void (*) (void *)) TaskStart, // task pointer
(void *) 0, // parameter
(OS_STK *) &TaskStartStk[TASK_START_STK_SIZE - 1], // stack pointer
(INT8U) TASK_START_PRIO); // Task priority
OSStart(); // Start multitasking environment
Return (0);
}
Code
/************************************************* *************************************
* FunctionName : TaskStart()
* Description : Task creation, only create tasks, not complete other tasks
* EntryParameter : None
* ReturnValue : None
************************************************** ************************************/
Void TaskStart(void* p_arg)
{
OS_CPU_SysTickInit(); // Initialize the SysTick.
#if (OS_TASK_STAT_EN) 0)
OSStatInit(); // This thing can measure CPU usage
#endif
OSTaskCreate((void (*) (void *)) TaskLed, // Task 1
(void *) 0, // without arguments
(OS_STK *) &TaskLedStk[TASK_LED_STK_SIZE - 1], // stack pointer
(INT8U) TASK_LED_PRIO); // Priority
// Here the task of creating your
While (1)
{
OSTimeDlyHMSM(0, 0, 0, 100);
}
}
It is not difficult to see that the advantage of the time slice polling method is still relatively large, that is, the advantages of the sequential execution method and the advantages of the operating system. The structure is clear, simple and very easy to understand.
16MM Key Switches
In the past 30 years, our company has been striving to create a high-quality and high-reliability 16mm power Key Switch. In order to enhance the competitive advantage in the world, our company has dozens of imported advanced testing equipment and has a complete ISO 9001 quality management system. The series On Off Key Switch products are strictly screened and repeatedly tested to provide customers with reliable products for the purpose of making customers rely on our quality.
One of the the most competitive factor of our key lock switch is that we have design a bran-new modal, ie, S301 serious , which is the only exclusive security key switch in the switches industry. Furthermore, the voltage and electricity of 16MM key switches is stronger, could supply bigger equipment and machines, like Metal Switches, Automotive Switches, Rocker Switches and Slide Switches.
Quality assurance of our 16 mm key switch power lock: In order to meet the requirements of customers in Japan, Europe,the United States and the globe, our 16mm key switches have passed the European and American environmental protection RoHS certification, and can provide customers with a full range of key switch SGS material analysis report, UL certification and other Relevant third-party testing and certification.
Key Switches,Key Switch Lock,Lock Switch,Power Lock Key Switch,Power Switch Lock,Power Lock Switch,Power Key Lock,Key Switch On Off,3 Position Slide Switch
YESWITCH ELECTRONICS CO., LTD. , https://www.yeswitches.com