当前位置:网站首页>SCM polling program framework based on linked list management
SCM polling program framework based on linked list management
2022-07-04 13:51:00 【Li Xiaoyao】
Focus on 、 Official account of star standard , Straight to the highlights
source :ERYUESANHI
Hello everyone , This is Xiao Yao , Today, I share the article of bare metal program framework of single chip microcomputer .
1
The importance of the overall program architecture
Many people, especially beginners, often want to write a little bit when they write code , In the beginning, there was no overall plan , This leads to more and more messy code ,bug constantly .
In the end, the code seems to run smoothly ( Maybe and really no problem ), But it will waste a lot of time to add a function , And even cause the whole code to crash .
therefore , At the beginning of a project, it is necessary to spend more time on the architecture design of the code . After the code structure is determined, you will find that the time to knock code will be very fast , And in the later debugging, it will not look for problems like headless flies . Of course , Debugging is also a technology .
In the process of learning real-time operating system , It is found that the coupling between real-time operating system framework and individual business code is very low , All you need to do is register the business code with a certain interface function and then give it to the operating system for hosting , It is very convenient .
But the scheduling of the operating system is too complex , Here we use the thinking mode of the operating system to reconstruct the time slice polling framework . Complete decoupling of the framework is realized , Users only need to include header files , And in the process of using, there is no need to change the library file that has been written .
2
Reference code
Let's start with demo, The demo Is to use the computer to open two threads : A thread simulates the timer interrupt of single chip microcomputer to generate time slice and poll a clock , The other thread simulates the time slice polling scheduler that has been running in the main function .
1#include <thread>
2#include <stdio.h>
3#include <windows.h>
4#include "timeslice.h"
5
6// establish 5 A task object
7TimesilceTaskObj task_1, task_2, task_3, task_4, task_5;
8
9// Specific task functions
10void task1_hdl()
11{
12 printf(">> task 1 is running ...\n");
13}
14
15void task2_hdl()
16{
17 printf(">> task 2 is running ...\n");
18}
19
20void task3_hdl()
21{
22 printf(">> task 3 is running ...\n");
23}
24
25void task4_hdl()
26{
27 printf(">> task 4 is running ...\n");
28}
29
30void task5_hdl()
31{
32 printf(">> task 5 is running ...\n");
33}
34
35// Initialize the task object , And add the task to the time slice polling schedule
36void task_init()
37{
38 timeslice_task_init(&task_1, task1_hdl, 1, 10);
39 timeslice_task_init(&task_2, task2_hdl, 2, 20);
40 timeslice_task_init(&task_3, task3_hdl, 3, 30);
41 timeslice_task_init(&task_4, task4_hdl, 4, 40);
42 timeslice_task_init(&task_5, task5_hdl, 5, 50);
43 timeslice_task_add(&task_1);
44 timeslice_task_add(&task_2);
45 timeslice_task_add(&task_3);
46 timeslice_task_add(&task_4);
47 timeslice_task_add(&task_5);
48}
49
50
51// Open two threads to simulate the running process on MCU
52void timeslice_exec_thread()
53{
54 while (true)
55 {
56 timeslice_exec();
57 }
58}
59
60void timeslice_tick_thread()
61{
62 while (true)
63 {
64 timeslice_tick();
65 Sleep(10);
66 }
67}
68
69int main()
70{
71 task_init();
72
73 printf(">> task num: %d\n", timeslice_get_task_num());
74 printf(">> task len: %d\n", timeslice_get_task_timeslice_len(&task_3));
75
76 timeslice_task_del(&task_2);
77 printf(">> delet task 2\n");
78 printf(">> task 2 is exist: %d\n", timeslice_task_isexist(&task_2));
79
80 printf(">> task num: %d\n", timeslice_get_task_num());
81
82 timeslice_task_del(&task_5);
83 printf(">> delet task 5\n");
84
85 printf(">> task num: %d\n", timeslice_get_task_num());
86
87 printf(">> task 3 is exist: %d\n", timeslice_task_isexist(&task_3));
88 timeslice_task_add(&task_2);
89 printf(">> add task 2\n");
90 printf(">> task 2 is exist: %d\n", timeslice_task_isexist(&task_2));
91
92 timeslice_task_add(&task_5);
93 printf(">> add task 5\n");
94
95 printf(">> task num: %d\n", timeslice_get_task_num());
96
97 printf("\n\n========timeslice running===========\n");
98
99 std::thread thread_1(timeslice_exec_thread);
100 std::thread thread_2(timeslice_tick_thread);
101
102 thread_1.join();
103 thread_2.join();
104
105
106 return 0;
107}
The operation results are as follows :
It can be seen from the above examples that , This framework is very easy to use , You may not even know how it works , With just a few simple interfaces, you can quickly create tasks and add them to the time slice polling framework , It's very easy to use .
3
Time slice polling Architecture
In fact, this part mainly uses object-oriented thinking , Using structures as objects , And use the structure pointer as a parameter to pass , This saves resources , And it's very efficient .
The most difficult part is the use of intrusive linked lists , This kind of linked list is widely used in some operating system kernels , Here is Reference resources RT-Thread Implementation of intrusive linked list in real-time operating system .
h file :
1#ifndef _TIMESLICE_H
2#define _TIMESLICE_H
3
4#include "./list.h"
5
6typedef enum {
7 TASK_STOP,
8 TASK_RUN
9} IsTaskRun;
10
11typedef struct timesilce
12{
13 unsigned int id;
14 void (*task_hdl)(void);
15 IsTaskRun is_run;
16 unsigned int timer;
17 unsigned int timeslice_len;
18 ListObj timeslice_task_list;
19} TimesilceTaskObj;
20
21void timeslice_exec(void);
22void timeslice_tick(void);
23void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len);
24void timeslice_task_add(TimesilceTaskObj* obj);
25void timeslice_task_del(TimesilceTaskObj* obj);
26unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj);
27unsigned int timeslice_get_task_num(void);
28unsigned char timeslice_task_isexist(TimesilceTaskObj* obj);
29
30#endif
.c file :
1#include "./timeslice.h"
2
3static LIST_HEAD(timeslice_task_list);
4
5void timeslice_exec()
6{
7 ListObj* node;
8 TimesilceTaskObj* task;
9
10 list_for_each(node, ×lice_task_list)
11 {
12
13 task = list_entry(node, TimesilceTaskObj, timeslice_task_list);
14 if (task->is_run == TASK_RUN)
15 {
16 task->task_hdl();
17 task->is_run = TASK_STOP;
18 }
19 }
20}
21
22void timeslice_tick()
23{
24 ListObj* node;
25 TimesilceTaskObj* task;
26
27 list_for_each(node, ×lice_task_list)
28 {
29 task = list_entry(node, TimesilceTaskObj, timeslice_task_list);
30 if (task->timer != 0)
31 {
32 task->timer--;
33 if (task->timer == 0)
34 {
35 task->is_run = TASK_RUN;
36 task->timer = task->timeslice_len;
37 }
38 }
39 }
40}
41
42unsigned int timeslice_get_task_num()
43{
44 return list_len(×lice_task_list);
45}
46
47void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len)
48{
49 obj->id = id;
50 obj->is_run = TASK_STOP;
51 obj->task_hdl = task_hdl;
52 obj->timer = timeslice_len;
53 obj->timeslice_len = timeslice_len;
54}
55
56void timeslice_task_add(TimesilceTaskObj* obj)
57{
58 list_insert_before(×lice_task_list, &obj->timeslice_task_list);
59}
60
61void timeslice_task_del(TimesilceTaskObj* obj)
62{
63 if (timeslice_task_isexist(obj))
64 list_remove(&obj->timeslice_task_list);
65 else
66 return;
67}
68
69
70unsigned char timeslice_task_isexist(TimesilceTaskObj* obj)
71{
72 unsigned char isexist = 0;
73 ListObj* node;
74 TimesilceTaskObj* task;
75
76 list_for_each(node, ×lice_task_list)
77 {
78 task = list_entry(node, TimesilceTaskObj, timeslice_task_list);
79 if (obj->id == task->id)
80 isexist = 1;
81 }
82
83 return isexist;
84}
85
86unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj)
87{
88 return obj->timeslice_len;
89}
4
Bottom intrusive two-way linked list
The linked list is linux It's widely used in the kernel , It's also very classic , Its principle can refer to the article :
https://www.cnblogs.com/skywang12345/p/3562146.html
.h file :
1#ifndef _LIST_H
2#define _LIST_H
3
4#define offset_of(type, member) (unsigned long) &((type*)0)->member
5#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offset_of(type, member)))
6
7typedef struct list_structure
8{
9 struct list_structure* next;
10 struct list_structure* prev;
11} ListObj;
12
13#define LIST_HEAD_INIT(name) {&(name), &(name)}
14#define LIST_HEAD(name) ListObj name = LIST_HEAD_INIT(name)
15
16void list_init(ListObj* list);
17void list_insert_after(ListObj* list, ListObj* node);
18void list_insert_before(ListObj* list, ListObj* node);
19void list_remove(ListObj* node);
20int list_isempty(const ListObj* list);
21unsigned int list_len(const ListObj* list);
22
23#define list_entry(node, type, member) \
24 container_of(node, type, member)
25
26#define list_for_each(pos, head) \
27 for (pos = (head)->next; pos != (head); pos = pos->next)
28
29#define list_for_each_safe(pos, n, head) \
30 for (pos = (head)->next, n = pos->next; pos != (head); \
31 pos = n, n = pos->next)
32
33#endif
.c file :
1#include "list.h"
2
3void list_init(ListObj* list)
4{
5 list->next = list->prev = list;
6}
7
8void list_insert_after(ListObj* list, ListObj* node)
9{
10 list->next->prev = node;
11 node->next = list->next;
12
13 list->next = node;
14 node->prev = list;
15}
16
17void list_insert_before(ListObj* list, ListObj* node)
18{
19 list->prev->next = node;
20 node->prev = list->prev;
21
22 list->prev = node;
23 node->next = list;
24}
25
26void list_remove(ListObj* node)
27{
28 node->next->prev = node->prev;
29 node->prev->next = node->next;
30
31 node->next = node->prev = node;
32}
33
34int list_isempty(const ListObj* list)
35{
36 return list->next == list;
37}
38
39unsigned int list_len(const ListObj* list)
40{
41 unsigned int len = 0;
42 const ListObj* p = list;
43 while (p->next != list)
44 {
45 p = p->next;
46 len++;
47 }
48
49 return len;
50}
Here we are , A brand new , Completely decoupled , Very convenient and easy to use time slice polling framework to complete .
Copyright notice : Source network of this paper , Free delivery of knowledge , The copyright belongs to the original author . If involves the work copyright question , Please contact me to delete .
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
Pay attention to my WeChat official account , reply “ Add group ” Join the technical exchange group according to the rules .
Click on “ Read the original ” See more sharing , Welcome to share 、 Collection 、 give the thumbs-up 、 Looking at .
边栏推荐
- 动画与过渡效果
- Openharmony application development how to create dayu200 previewer
- 基于链表管理的单片机轮询程序框架
- Introduction to XML III
- Practice: fabric user certificate revocation operation process
- Cors: standard scheme of cross domain resource request
- WS2811 M是三通道LED驱动控制专用电路彩灯带方案开发
- Go 语言入门很简单:Go 实现凯撒密码
- 请问大佬们有遇到这个情况吗,cdc 1.4 连接MySQL 5.7 无法使用 timestamp
- Building intelligent gray-scale data system from 0 to 1: Taking vivo game center as an example
猜你喜欢
Zhongang Mining: in order to ensure sufficient supply of fluorite, it is imperative to open source and save flow
数据库公共字段自动填充
基于STM32+华为云IOT设计的酒驾监控系统
基于链表管理的单片机轮询程序框架
Is the outdoor LED screen waterproof?
Building intelligent gray-scale data system from 0 to 1: Taking vivo game center as an example
Annual comprehensive analysis of China's mobile reading market in 2022
Go 语言入门很简单:Go 实现凯撒密码
Distributed base theory
2022kdd pre lecture | 11 first-class scholars take you to unlock excellent papers in advance
随机推荐
Redis - how to install redis and configuration (how to quickly install redis on ubuntu18.04 and centos7.6 Linux systems)
动画与过渡效果
Besides, rsync+inotify realizes real-time backup of data
30:第三章:开发通行证服务:13:开发【更改/完善用户信息,接口】;(使用***BO类承接参数,并使用了参数校验)
WPF double slider control and forced capture of mouse event focus
Cann operator: using iterators to efficiently realize tensor data cutting and blocking processing
高效!用虚拟用户搭建FTP工作环境
#yyds干货盘点# 解决名企真题:连续最大和
Alibaba cloud award winning experience: build a highly available system with polardb-x
C語言宿舍管理查詢軟件
Runc hang causes the kubernetes node notready
ASP.NET Core入门一
聊聊支付流程的设计与实现逻辑
Apache server access log access Log settings
Fs4056 800mA charging IC domestic fast charging power IC
The only core indicator of high-quality software architecture
Samsung's mass production of 3nm products has attracted the attention of Taiwan media: whether it can improve the input-output rate in the short term is the key to compete with TSMC
[cloud native | kubernetes] in depth understanding of ingress (12)
Is the outdoor LED screen waterproof?
unity不识别rider的其中一种解决方法