一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

非常實用,推薦一種面向?qū)ο笏季S的單片機程序框架

jf_pJlTbmA9 ? 來源:小麥大叔 ? 作者:小麥大叔 ? 2023-10-24 18:03 ? 次閱讀

程序架構(gòu)重要性

很多人尤其是初學(xué)者在寫代碼的時候往往都是想一點寫一點,最開始沒有一個整體的規(guī)劃,導(dǎo)致后面代碼越寫越亂,bug不斷。

最終代碼跑起來看似沒有問題(有可能也真的沒有問題),但是系統(tǒng)的可擴展性很差,添加一個功能的時候會浪費大量的時間,甚至導(dǎo)致整個代碼的崩潰。

所以,在一個項目開始的時候多花一些時間在代碼的架構(gòu)設(shè)計上是十分有必要的。代碼架構(gòu)確定好了之后你會發(fā)現(xiàn)敲代碼的時候會特別快,并且在后期調(diào)試的時候也不會像無頭蒼蠅一樣胡亂找問題。當(dāng)然,調(diào)試也是一門技術(shù)。

在學(xué)習(xí)實時操作系統(tǒng)的過程中,發(fā)現(xiàn)實時操作系統(tǒng)框架與個人的業(yè)務(wù)代碼之間的耦合性就非常低,都是只需要將業(yè)務(wù)代碼通過一定的接口函數(shù)注冊好后就交給操作系統(tǒng)托管了,十分方便。

但是操作系統(tǒng)的調(diào)度過于復(fù)雜,這里就使用操作系統(tǒng)的思維方式來重構(gòu)這個時間片輪詢框架。實現(xiàn)該框架的完全解耦,用戶只需要包含頭文件,并且在使用過程中不需要改動已經(jīng)寫好的庫文件。

Demo

首先來個demo,該demo是使用電腦開兩個線程:一個線程模擬單片機定時器中斷產(chǎn)生時間片輪詢個時鐘,另一個線程則模擬主函數(shù)中一直運行的時間片輪詢調(diào)度程序。

#include
#include
#include
#include"timeslice.h"

//創(chuàng)建5個任務(wù)對象
TimesilceTaskObjtask_1,task_2,task_3,task_4,task_5;

//具體的任務(wù)函數(shù)
voidtask1_hdl()
{
printf(">>task1isrunning...n");
}

voidtask2_hdl()
{
printf(">>task2isrunning...n");
}

voidtask3_hdl()
{
printf(">>task3isrunning...n");
}

voidtask4_hdl()
{
printf(">>task4isrunning...n");
}

voidtask5_hdl()
{
printf(">>task5isrunning...n");
}

//初始化任務(wù)對象,并且將任務(wù)添加到時間片輪詢調(diào)度中
voidtask_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);
}

//開兩個線程模擬在單片機上的運行過程
voidtimeslice_exec_thread()
{
while(true)
{
timeslice_exec();
}
}

voidtimeslice_tick_thread()
{
while(true)
{
timeslice_tick();
Sleep(10);
}
}

intmain()
{
task_init();

printf(">>tasknum:%dn",timeslice_get_task_num());
printf(">>tasklen:%dn",timeslice_get_task_timeslice_len( task_3));

timeslice_task_del( task_2);
printf(">>delettask2n");
printf(">>task2isexist:%dn",timeslice_task_isexist( task_2));

printf(">>tasknum:%dn",timeslice_get_task_num());
timeslice_task_del( task_5);printf(">>delettask5n");
printf(">>tasknum:%dn",timeslice_get_task_num());
printf(">>task3isexist:%dn",timeslice_task_isexist( task_3));

timeslice_task_add( task_2);printf(">>addtask2n");
printf(">>task2isexist:%dn",timeslice_task_isexist( task_2));

timeslice_task_add( task_5);printf(">>addtask5n");
printf(">>tasknum:%dn",timeslice_get_task_num());

printf("nn========timeslicerunning===========n");

std::threadthread_1(timeslice_exec_thread);
std::threadthread_2(timeslice_tick_thread);

thread_1.join();
thread_2.join();

return0;
}

運行結(jié)果如下:

poYBAGGnJ7OAZ5XZAACMwYJDoAU530.png

由以上例子可見,這個框架使用十分方便,甚至可以完全不知道其原理,僅僅通過幾個簡單的接口就可以迅速創(chuàng)建任務(wù)并加入到時間片輪詢的框架中,十分好用。

時間片輪詢架構(gòu)

其實該部分主要使用了面向?qū)ο蟮乃季S,使用結(jié)構(gòu)體作為對象,并使用結(jié)構(gòu)體指針作為參數(shù)傳遞,這樣作可以節(jié)省資源,并且有著極高的運行效率。

其中最難的部分是侵入式鏈表的使用,這種鏈表在一些操作系統(tǒng)內(nèi)核中使用十分廣泛,這里是參考RT-Thread實時操作系統(tǒng)中的侵入式鏈表實現(xiàn)。

h文件:

#ifndef_TIMESLICE_H
#define_TIMESLICE_H

#include"./list.h"

typedefenum
{
TASK_STOP,
TASK_RUN
}IsTaskRun;

typedefstructtimesilce
{
unsignedintid;
void(*task_hdl)(void);
IsTaskRunis_run;
unsignedinttimer;
unsignedinttimeslice_len;
ListObjtimeslice_task_list;
}TimesilceTaskObj;

voidtimeslice_exec(void);
voidtimeslice_tick(void);
voidtimeslice_task_init(TimesilceTaskObj*obj,void(*task_hdl)(void),unsignedintid,unsignedinttimeslice_len);
voidtimeslice_task_add(TimesilceTaskObj*obj);
voidtimeslice_task_del(TimesilceTaskObj*obj);
unsignedinttimeslice_get_task_timeslice_len(TimesilceTaskObj*obj);
unsignedinttimeslice_get_task_num(void);
unsignedchartimeslice_task_isexist(TimesilceTaskObj*obj);

#endifc文件:
#include"./timeslice.h"

staticLIST_HEAD(timeslice_task_list);

voidtimeslice_exec()
{
ListObj*node;
TimesilceTaskObj*task;

list_for_each(node, timeslice_task_list)
{

task=list_entry(node,TimesilceTaskObj,timeslice_task_list);
if(task->is_run==TASK_RUN)
{
task->task_hdl();
task->is_run=TASK_STOP;
}
}
}

voidtimeslice_tick()
{
ListObj*node;
TimesilceTaskObj*task;

list_for_each(node, timeslice_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;
}
}
}
}

unsignedinttimeslice_get_task_num()
{
returnlist_len( timeslice_task_list);
}

voidtimeslice_task_init(TimesilceTaskObj*obj,void(*task_hdl)(void),unsignedintid,unsignedinttimeslice_len)
{
obj->id=id;
obj->is_run=TASK_STOP;
obj->task_hdl=task_hdl;
obj->timer=timeslice_len;
obj->timeslice_len=timeslice_len;
}

voidtimeslice_task_add(TimesilceTaskObj*obj)
{
list_insert_before( timeslice_task_list, obj->timeslice_task_list);
}

voidtimeslice_task_del(TimesilceTaskObj*obj)
{
if(timeslice_task_isexist(obj))
list_remove( obj->timeslice_task_list);
else
return;
}

unsignedchartimeslice_task_isexist(TimesilceTaskObj*obj)
{
unsignedcharisexist=0;
ListObj*node;
TimesilceTaskObj*task;

list_for_each(node, timeslice_task_list)
{
task=list_entry(node,TimesilceTaskObj,timeslice_task_list);
if(obj->id==task->id)
isexist=1;
}

returnisexist;
}

unsignedinttimeslice_get_task_timeslice_len(TimesilceTaskObj*obj)
{
returnobj->timeslice_len;
}

底層侵入式雙向鏈表

該鏈表是linux內(nèi)核中使用十分廣泛,也十分經(jīng)典,其原理具體可以參考文章:

https://www.cnblogs.com/skywang12345/p/3562146.html

h文件:

#ifndef_LIST_H
#define_LIST_H
#defineoffset_of(type,member)(unsignedlong) ((type*)0)->member
#definecontainer_of(ptr,type,member)((type*)((char*)(ptr)-offset_of(type,member)))

typedefstructlist_structure
{
structlist_structure*next;
structlist_structure*prev;
}ListObj;

#defineLIST_HEAD_INIT(name){ (name), (name)}
#defineLIST_HEAD(name)ListObjname=LIST_HEAD_INIT(name)

voidlist_init(ListObj*list);
voidlist_insert_after(ListObj*list,ListObj*node);
voidlist_insert_before(ListObj*list,ListObj*node);
voidlist_remove(ListObj*node);
intlist_isempty(constListObj*list);
unsignedintlist_len(constListObj*list);

#definelist_entry(node,type,member)
container_of(node,type,member)

#definelist_for_each(pos,head)
for(pos=(head)->next;pos!=(head);pos=pos->next)

#definelist_for_each_safe(pos,n,head)
for(pos=(head)->next,n=pos->next;pos!=(head);
pos=n,n=pos->next)

#endif

c文件:

#include"list.h"

voidlist_init(ListObj*list)
{
list->next=list->prev=list;
}

voidlist_insert_after(ListObj*list,ListObj*node)
{
list->next->prev=node;
node->next=list->next;

list->next=node;
node->prev=list;
}

voidlist_insert_before(ListObj*list,ListObj*node)
{
list->prev->next=node;
node->prev=list->prev;

list->prev=node;
node->next=list;
}

voidlist_remove(ListObj*node)
{
node->next->prev=node->prev;
node->prev->next=node->next;

node->next=node->prev=node;
}

intlist_isempty(constListObj*list)
{
returnlist->next==list;
}

unsignedintlist_len(constListObj*list)
{
unsignedintlen=0;
constListObj*p=list;
while(p->next!=list)
{
p=p->next;
len++;
}

returnlen;
}

到此,一個全新的,完全解耦的,十分方便易用時間片輪詢框架完成。

來源:小麥大叔

免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請聯(lián)系小編進行處理

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6059

    文章

    44825

    瀏覽量

    644962
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    404

    瀏覽量

    17745
收藏 人收藏

    評論

    相關(guān)推薦
    熱點推薦

    一種面向飛行試驗的數(shù)據(jù)融合框架

    天地氣動數(shù)據(jù)致性,針對某外形飛行試驗數(shù)據(jù)開展了典型對象的天地氣動數(shù)據(jù)融合方法研究。結(jié)合數(shù)據(jù)挖掘的隨機森林方法,本文提出了一種面向飛行試驗的數(shù)據(jù)融合
    的頭像 發(fā)表于 11-27 11:34 ?627次閱讀
    <b class='flag-5'>一種</b><b class='flag-5'>面向</b>飛行試驗的數(shù)據(jù)融合<b class='flag-5'>框架</b>

    單片機編程語言有哪些選擇

    些常用的單片機編程語言,以及它們的特點和應(yīng)用場景: 1. C語言 特點 :C語言是一種通用的編程語言,以其高效性和靈活性而聞名。它提供了豐富的庫函數(shù)和直接的硬件訪問能力,非常適合用于單片機
    的頭像 發(fā)表于 11-01 14:13 ?1901次閱讀

    單片機怎么寫入程序

    單片機(Microcontroller Unit,MCU)是一種集成電路芯片,它將計算機的CPU、存儲器、輸入/輸出接口等功能集成在個芯片上。單片機廣泛應(yīng)用于嵌入式系統(tǒng)和物聯(lián)網(wǎng)設(shè)備中
    的頭像 發(fā)表于 10-21 11:21 ?1908次閱讀

    單片機有哪些中斷類型

    單片機中斷是指在單片機執(zhí)行程序的過程中,當(dāng)外部設(shè)備或內(nèi)部條件發(fā)生某個特定事件時,能夠暫停當(dāng)前正在執(zhí)行的程序,轉(zhuǎn)而去執(zhí)行個特定的服務(wù)
    的頭像 發(fā)表于 10-17 18:12 ?1874次閱讀

    單片機的中斷機制

    單片機的中斷機制是一種重要的處理方式,它允許單片機在執(zhí)行主程序的過程中,能夠暫停當(dāng)前任務(wù),轉(zhuǎn)而處理外部或內(nèi)部緊急事件。這種機制極大地提高了系統(tǒng)的響應(yīng)速度和處理能力,使得
    的頭像 發(fā)表于 10-17 18:03 ?1607次閱讀

    單片機io口的四工作狀態(tài)

    單片機的I/O口工作狀態(tài)是單片機編程和硬件操作中非常重要的部分,它決定了單片機如何與外部設(shè)備進行通信。 1.
    的頭像 發(fā)表于 09-14 14:24 ?3179次閱讀

    單片機hex文件反編譯成C語言的過程

    單片機和Hex文件簡介 單片機(Microcontroller Unit,MCU)是一種集成了處理器、存儲器和輸入/輸出接口的微型計算機。它廣泛應(yīng)用于各種嵌入式系統(tǒng)和智能設(shè)備中。單片機
    的頭像 發(fā)表于 09-02 10:49 ?5223次閱讀

    keil可以讀出單片機程序

    Keil是款廣泛應(yīng)用于單片機程序開發(fā)的軟件,它提供了包括C編譯器、宏匯編、連接器、庫管理和個功能強大的仿真調(diào)試器等在內(nèi)的完整開發(fā)方案。然而,關(guān)于Keil是否能直接“讀出”
    的頭像 發(fā)表于 09-02 10:32 ?1784次閱讀

    單片機燒錄程序用什么軟件

    單片機燒錄程序單片機開發(fā)過程中的個重要環(huán)節(jié),涉及到將編寫好的程序代碼通過燒錄器寫入單片機的R
    的頭像 發(fā)表于 09-02 10:05 ?2777次閱讀

    單片機燒錄程序可以重新燒嗎

    單片機(Microcontroller Unit, MCU)是一種集成電路芯片,它將計算機的CPU、存儲器、輸入/輸出接口等集成在塊芯片上,用于控制各種電子設(shè)備。單片機燒錄
    的頭像 發(fā)表于 09-02 10:04 ?2516次閱讀

    單片機燒錄程序的線比單片機上的少還能燒錄嗎

    單片機燒錄原理 單片機燒錄是指將編寫好的程序代碼通過定的方式傳輸?shù)?b class='flag-5'>單片機的存儲器中,使其能夠按照程序
    的頭像 發(fā)表于 09-02 09:54 ?869次閱讀

    單片機燒錄程序的基本步驟是什么

    單片機燒錄程序單片機開發(fā)過程中非常重要的步,它涉及到將編寫好的程序代碼通過
    的頭像 發(fā)表于 09-02 09:47 ?2213次閱讀

    stm32單片機燒錄程序會擦除原來的程序

    在STM32單片機燒錄程序的過程中, 通常情況下會擦除原來的程序 ,并將新程序寫入單片機的閃存(Flash)中。這
    的頭像 發(fā)表于 09-02 09:42 ?3828次閱讀

    文讀懂什么單片機:組成結(jié)構(gòu)與應(yīng)用

    歡迎來到單片機的世界,這是一種微小(但功能強大)的設(shè)備,改變了嵌入式系統(tǒng)的面貌。在本文中,您將了解單片機些基本知識、單片機的結(jié)構(gòu)以及微處
    的頭像 發(fā)表于 08-09 11:49 ?2130次閱讀
    <b class='flag-5'>一</b>文讀懂什么<b class='flag-5'>單片機</b>:組成結(jié)構(gòu)與應(yīng)用

    大學(xué)生學(xué)單片機不能錯過的比賽

    單片機比賽是電子和計算機領(lǐng)域的項重要賽事,旨在提升參賽者的專業(yè)技能、團隊協(xié)作能力和創(chuàng)新思維。以下是些常見的單片機比賽
    的頭像 發(fā)表于 05-15 09:50 ?2357次閱讀
    大學(xué)生學(xué)<b class='flag-5'>單片機</b>不能錯過的比賽