一种面向对象思维的单片机程序框架
关注、星标公众号,直达精彩内容
来源:网络素材
大家好,单片机编码中稍不注意就会陷入一种混沌状态,函数、变量、文件分类用的多了就会乱了,对初学者尤其如此,实现功能是简单的,但是让程序变得可移植性好,一目了然,架构清晰才是进阶必经之路,今天分享一篇单片机程序框架的文章,希望对大家有帮助。
程序架构重要性
Demo
// 创建5个任务对象TimesilceTaskObj task_1, task_2, task_3, task_4, task_5;// 具体的任务函数void task1_hdl(){printf(">> task 1 is running ...\n");}void task2_hdl(){printf(">> task 2 is running ...\n");}void task3_hdl(){printf(">> task 3 is running ...\n");}void task4_hdl(){printf(">> task 4 is running ...\n");}void task5_hdl(){printf(">> task 5 is running ...\n");}// 初始化任务对象,并且将任务添加到时间片轮询调度中void task_init(){timeslice_task_init(&task_1, task1_hdl, 1, 10);timeslice_task_init(&task_2, task2_hdl, 2, 20);timeslice_task_init(&task_3, task3_hdl, 3, 30);timeslice_task_init(&task_4, task4_hdl, 4, 40);timeslice_task_init(&task_5, task5_hdl, 5, 50);timeslice_task_add(&task_1);timeslice_task_add(&task_2);timeslice_task_add(&task_3);timeslice_task_add(&task_4);timeslice_task_add(&task_5);}// 开两个线程模拟在单片机上的运行过程void timeslice_exec_thread(){while (true){timeslice_exec();}}void timeslice_tick_thread(){while (true){timeslice_tick();Sleep(10);}}int main(){task_init();printf(">> task num: %d\n", timeslice_get_task_num());printf(">> task len: %d\n", timeslice_get_task_timeslice_len(&task_3));timeslice_task_del(&task_2);printf(">> delet task 2\n");printf(">> task 2 is exist: %d\n", timeslice_task_isexist(&task_2));printf(">> task num: %d\n", timeslice_get_task_num());timeslice_task_del(&task_5);printf(">> delet task 5\n");printf(">> task num: %d\n", timeslice_get_task_num());printf(">> task 3 is exist: %d\n", timeslice_task_isexist(&task_3));timeslice_task_add(&task_2);printf(">> add task 2\n");printf(">> task 2 is exist: %d\n", timeslice_task_isexist(&task_2));timeslice_task_add(&task_5);printf(">> add task 5\n");printf(">> task num: %d\n", timeslice_get_task_num());printf("\n\n========timeslice running===========\n");std::thread thread_1(timeslice_exec_thread);std::thread thread_2(timeslice_tick_thread);thread_1.join();thread_2.join();return 0;}
运行结果如下:

时间片轮询架构
其实该部分主要使用了面向对象的思维,使用结构体作为对象,并使用结构体指针作为参数传递,这样作可以节省资源,并且有着极高的运行效率。
typedef enum {TASK_STOP,TASK_RUN} IsTaskRun;typedef struct timesilce{unsigned int id;void (*task_hdl)(void);IsTaskRun is_run;unsigned int timer;unsigned int timeslice_len;ListObj timeslice_task_list;} TimesilceTaskObj;void timeslice_exec(void);void timeslice_tick(void);void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len);void timeslice_task_add(TimesilceTaskObj* obj);void timeslice_task_del(TimesilceTaskObj* obj);unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj);unsigned int timeslice_get_task_num(void);unsigned char timeslice_task_isexist(TimesilceTaskObj* obj);
static LIST_HEAD(timeslice_task_list);void timeslice_exec(){ListObj* node;TimesilceTaskObj* task;list_for_each(node, ×lice_task_list){task = list_entry(node, TimesilceTaskObj, timeslice_task_list);if (task->is_run == TASK_RUN){task->task_hdl();task->is_run = TASK_STOP;}}}void timeslice_tick(){ListObj* node;TimesilceTaskObj* task;list_for_each(node, ×lice_task_list){task = list_entry(node, TimesilceTaskObj, timeslice_task_list);if (task->timer != 0){task->timer--;if (task->timer == 0){task->is_run = TASK_RUN;task->timer = task->timeslice_len;}}}}unsigned int timeslice_get_task_num(){return list_len(×lice_task_list);}void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len){obj->id = id;obj->is_run = TASK_STOP;obj->task_hdl = task_hdl;obj->timer = timeslice_len;obj->timeslice_len = timeslice_len;}void timeslice_task_add(TimesilceTaskObj* obj){list_insert_before(×lice_task_list, &obj->timeslice_task_list);}void timeslice_task_del(TimesilceTaskObj* obj){if (timeslice_task_isexist(obj))list_remove(&obj->timeslice_task_list);elsereturn;}unsigned char timeslice_task_isexist(TimesilceTaskObj* obj){unsigned char isexist = 0;ListObj* node;TimesilceTaskObj* task;list_for_each(node, ×lice_task_list){task = list_entry(node, TimesilceTaskObj, timeslice_task_list);if (obj->id == task->id)isexist = 1;}return isexist;}unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj){return obj->timeslice_len;}
底层侵入式双向链表
typedef struct list_structure{struct list_structure* next;struct list_structure* prev;} ListObj;void list_init(ListObj* list);void list_insert_after(ListObj* list, ListObj* node);void list_insert_before(ListObj* list, ListObj* node);void list_remove(ListObj* node);int list_isempty(const ListObj* list);unsigned int list_len(const ListObj* list);container_of(node, type, member)for (pos = (head)->next; pos != (head); pos = pos->next)for (pos = (head)->next, n = pos->next; pos != (head); \pos = n, n = pos->next)
#include "list.h"void list_init(ListObj* list){list->next = list->prev = list;}void list_insert_after(ListObj* list, ListObj* node){list->next->prev = node;node->next = list->next;list->next = node;node->prev = list;}void list_insert_before(ListObj* list, ListObj* node){list->prev->next = node;node->prev = list->prev;list->prev = node;node->next = list;}void list_remove(ListObj* node){node->next->prev = node->prev;node->prev->next = node->next;node->next = node->prev = node;}int list_isempty(const ListObj* list){return list->next == list;}unsigned int list_len(const ListObj* list){unsigned int len = 0;const ListObj* p = list;while (p->next != list){p = p->next;len++;}return len;}
本文来源网络,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ 关注我的微信公众号,回复“加群”按规则加入技术交流群。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。
评论
