最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用C語言實(shí)現(xiàn)任務(wù)調(diào)度的示例代碼

 更新時(shí)間:2023年04月10日 08:45:17   作者:pie_thn  
這篇文章主要為大家詳細(xì)介紹了如何利用純C語言實(shí)現(xiàn)任務(wù)調(diào)度(可用于STM32、C51等單片機(jī)),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下

前言

這個(gè)任務(wù)調(diào)度模塊的實(shí)現(xiàn)是形成于畢設(shè)項(xiàng)目中的,用在STM32中,斷斷續(xù)續(xù)跨度2個(gè)月實(shí)現(xiàn)了一些基本功能,可能后面再做其他項(xiàng)目時(shí)會(huì)一點(diǎn)點(diǎn)完善起來,也會(huì)多學(xué)習(xí)相關(guān)知識(shí)來強(qiáng)化模塊的實(shí)用性和高效性,畢竟用自己自主實(shí)現(xiàn)出來的功能還是蠻舒心的。

任務(wù)調(diào)度模式結(jié)構(gòu)

整體上的結(jié)構(gòu)屬于線性結(jié)構(gòu),結(jié)合鏈表和定時(shí)器來實(shí)現(xiàn),我使用的是sysTick這個(gè)滴答時(shí)鐘,1ms的頻率,功能比較簡(jiǎn)單,容易理解。

分片

分片的模式,主要體現(xiàn)在函數(shù)分片和時(shí)間分片在我之前就有使用在函數(shù)中,主要的思路是,把函數(shù)功能切片,分為幾個(gè)小部分,每次執(zhí)行時(shí)按次序執(zhí)行小部分,對(duì)于沒有時(shí)序要求的函數(shù)來說,可以把一個(gè)占用CPU大的功能分?jǐn)傞_來實(shí)現(xiàn),從而避免有些地方耗時(shí)長(zhǎng)的問題。對(duì)于時(shí)間分片,其實(shí)就是定時(shí)器的一種應(yīng)用,實(shí)際上,函數(shù)分片在執(zhí)行的時(shí)候已經(jīng)是一種時(shí)間分片了,不過現(xiàn)在加上人為的控制在里面了。

下面是函數(shù)分片的一般結(jié)構(gòu):

void func(char *fos,...){
    static char step=0;//順序控制變量,自由度比較高,可亂序,可循環(huán),可延遲執(zhí)行
    switch(step){
        case 0:{
            //...
            step++;
            break;
        }
        case 1:{
            //...
            step++;
            break;
        }
        //...
        default:{
            //step++;//可以借助default實(shí)現(xiàn)延時(shí)的效果,即跳過幾次空白step
            break;
        }

    }
    return;
}

其中添加的參數(shù)變量*fos必要的,因?yàn)榫褪峭ㄟ^傳入每個(gè)任務(wù)的這個(gè)標(biāo)志位來判斷是否運(yùn)行結(jié)束,而其他的參數(shù),就得基于具體任務(wù)做不一樣的處理了。

輪詢

運(yùn)行框圖

可以看到這個(gè)框圖是一個(gè)頭尾相連的閉環(huán)結(jié)構(gòu),從頭節(jié)點(diǎn)依次運(yùn)行到尾節(jié)點(diǎn)后再?gòu)念^循環(huán)往復(fù)執(zhí)行下去。

輪詢函數(shù)

void loop_task(void){
	static Task_Obj *tasknode;
	
	tasknode=task_curnode->next;//repoint the curnode to the next
	if(tasknode==NULL){//tasknode is null,only the headnode have the attr
		return;//express the task space is none
	}
	else if(tasknode->task_type==TYPE_HEAD){//tasknode is headnode
		task_curnode=tasknode;
		return;
	}
	else{
		if(tasknode->run_type == RUN_WAIT){
            //等待型任務(wù),通過ready標(biāo)志來確定是否執(zhí)行,否則就跳過
			if(!tasknode->ready){
				if(task_curnode->next !=NULL){
					task_curnode=task_curnode->next;
					return;
				}
			}
		}
		if(tasknode->task_status==STATUS_INIT){

			tasknode->tickstart=HAL_GetTick();//獲取tick
			tasknode->task_status=STATUS_RUN;

		}
		else if(tasknode->task_status==STATUS_RUN){
			if((HAL_GetTick() - tasknode->tickstart) > (uint32_t)tasknode->task_tick){
				tasknode->task_name(&(tasknode->task_fos));//run the step task,transfer the fos
				tasknode->tickstart+=(uint32_t)tasknode->task_tick;//update the tickstart
			}
		}
		
	}
	if(tasknode->task_fos==FOS_FLAG){
		
		tasknode->ready=0;
		if(tasknode->waittask!=NULL){
            //置位該任務(wù)綁定的等待的任務(wù)準(zhǔn)備運(yùn)行標(biāo)志位,標(biāo)識(shí)可以準(zhǔn)備運(yùn)行了
			tasknode->waittask->ready=1;
		}
        //運(yùn)行結(jié)束就刪掉該任務(wù)
		delete_task(tasknode);
	}
	else if(tasknode->task_fos==FOC_FLAG){
        //循環(huán)運(yùn)行該任務(wù)
		tasknode->task_status=STATUS_INIT;//continue running from start
		tasknode->task_fos=0;//RESET fos
		
	}
	if(task_curnode->next !=NULL){
		if(task_curnode->next->run_type==RUN_FORCE) return;//force-type's task
		
		else task_curnode=task_curnode->next;
		
	}
	

}

其中有幾個(gè)運(yùn)行態(tài)和標(biāo)志位

#define FOS_FLAG 99//運(yùn)行結(jié)束標(biāo)志
#define FOC_FLAG 100//運(yùn)行結(jié)束后再次執(zhí)行,相當(dāng)于循環(huán)運(yùn)行
#define TYPE_NOMAL 0//標(biāo)識(shí)一般任務(wù)類型
#define TYPE_HEAD 1//標(biāo)識(shí)頭任務(wù)類型
#define TYPE_END 2//標(biāo)識(shí)尾任務(wù)類型
#define RUN_NORMAL 0//一般輪詢模式
#define RUN_FORCE 1//強(qiáng)制運(yùn)行該任務(wù),運(yùn)行結(jié)束才繼續(xù)下一個(gè)任務(wù)
#define RUN_WAIT 2//等待指定的任務(wù)結(jié)束,才可以被運(yùn)行
#define STATUS_INIT 0//任務(wù)的準(zhǔn)備階段,用于獲取起始時(shí)間
#define STATUS_RUN 1//任務(wù)運(yùn)行階段
#define STATUS_UNVAILED 2//無效狀態(tài)

運(yùn)行時(shí)對(duì)時(shí)間間隔tick的把握還有點(diǎn)問題,這個(gè)等待后面有機(jī)會(huì)優(yōu)化下。

調(diào)度實(shí)現(xiàn)

任務(wù)鏈表結(jié)構(gòu)

typedef struct TASK_CLASS{
	void (*task_name)(char *taskfos,...);//任務(wù)函數(shù)
	int task_tick;//任務(wù)的時(shí)間分片間隔
	uint32_t tickstart;//起始時(shí)間點(diǎn),每次執(zhí)行完須加上一個(gè)tick
	char task_fos;//運(yùn)行結(jié)束標(biāo)志
	char task_type;//任務(wù)類型變量
	char task_status;//任務(wù)狀態(tài)
	char run_type;//運(yùn)行狀態(tài)
	char ready;//準(zhǔn)備運(yùn)行標(biāo)志位
	struct TASK_CLASS *next;//下一任務(wù)
	struct TASK_CLASS *waittask;//等待執(zhí)行的任務(wù)
} Task_Obj;

添加任務(wù)

add_task

void add_task(void (*taskname)(char *,...),int tasktick,int runtype){//可變參,這里未做處理
Task_Obj *tasknode,*tmpnode;
char i;

tasknode = (Task_Obj*)malloc(sizeof(Task_Obj));

tasknode->task_name=taskname;
tasknode->task_tick=tasktick;
tasknode->task_fos=0;
tasknode->task_status=STATUS_INIT;//initial status
tasknode->task_type=TYPE_END; //set the new node to endnode
tasknode->run_type=runtype;
tasknode->next=&task_headnode;//the endnode point to the headnode

tmpnode=&task_headnode;
if(task_num==0){
	tmpnode->next=tasknode;
	task_num++;
	return;
}
for(i=0;i<task_num;i++){
	tmpnode=tmpnode->next;//reach the endnode
}
tmpnode->task_type=TYPE_NOMAL;//turn the last endnode to the normal node
tmpnode->next=tasknode;
task_num++;
}

add_wait_task

void add_wait_task(void (*taskname)(char *),void (*waitname)(char *),int tasktick){
Task_Obj *tmpnode,*tasknode;
char i,pos;

tmpnode=&task_headnode;
for(i=0;i<task_num;i++){
	tmpnode=tmpnode->next;//reach the endnode
	if(tmpnode->task_name==taskname){
		pos=i;//獲取要等待任務(wù)的位置
		break;
	}
}

tasknode = (Task_Obj*)malloc(sizeof(Task_Obj));

tasknode->task_name=waitname;
tasknode->task_tick=tasktick;
tasknode->task_fos=0;
tasknode->task_status=STATUS_INIT;//initial status
tasknode->task_type=TYPE_END; //set the new node to endnode
tasknode->run_type=RUN_WAIT;//任務(wù)為等待運(yùn)行
tasknode->ready=0;
tasknode->next=&task_headnode;//the endnode point to the headnode

tmpnode->waittask=tasknode;//獲取新建的等待執(zhí)行的任務(wù)地址,在運(yùn)行結(jié)束后把等待執(zhí)行的任務(wù)的準(zhǔn)備運(yùn)行標(biāo)志位置1

tmpnode=&task_headnode;
if(task_num==0){
	tmpnode->next=tasknode;
	task_num++;
	return;
}
for(i=0;i<task_num;i++){
	tmpnode=tmpnode->next;//reach the endnode
}
tmpnode->task_type=TYPE_NOMAL;//turn the last endnode to the normal node
tmpnode->next=tasknode;
task_num++;

}

刪除任務(wù)

delete_task(局限性大,只針對(duì)當(dāng)前運(yùn)行的任務(wù)而言)

void delete_task(Task_Obj *taskobj){
if(task_curnode->task_type==TYPE_HEAD && task_num < 2){//if curnode is headnode,and tasknum=1
	task_curnode->next=NULL;
}
else{
	task_curnode->next=taskobj->next;//repoint the curnode next
}
free(taskobj);//free the space of where the taskobj pointed

task_num--;

}

delete_task_withname(刪除指定任務(wù)名的任務(wù))

void delete_task_withname(void (*taskname)(char *)){
Task_Obj *tmpnode,*tmpnode2;
char i,pos;

tmpnode=&task_headnode;
for(i=0;i<task_num;i++){
	tmpnode=tmpnode->next;//reach the endnode
	if(tmpnode->task_name==taskname){
		pos=i;
		break;
	}
}
if(i==task_num) return;
tmpnode=&task_headnode;
for(i=0;i<pos+1;i++){
	tmpnode2=tmpnode;
	tmpnode=tmpnode->next;
}
if(tmpnode->next==NULL){//if tmpnode is endnode
	tmpnode2->next=&task_headnode;
}
else{
	tmpnode2->next=tmpnode->next;//repoint the curnode next
}
task_num--;
free(tmpnode);
}

初始化任務(wù)空間

void non_task(char *taskfos){
	return;
}

void init_taskspace(void){
	task_headnode.task_name=non_task;
	task_headnode.task_type=TYPE_HEAD;
	task_headnode.task_status=STATUS_UNVAILED;
	task_headnode.next=NULL;
	task_curnode=&task_headnode;//頭節(jié)點(diǎn)是沒有任務(wù)需要執(zhí)行的
	task_num=0;
}

調(diào)用實(shí)例

add_task(task1,500,RUN_NORMAL);//500ms執(zhí)行一次task1任務(wù)
add_wait_task(task1,task2,500);//task2等待task1結(jié)束才會(huì)執(zhí)行,運(yùn)行的時(shí)間間隔為500ms
delete_task_withname(task1);//刪除task1任務(wù)

while(1){
    //...
    loop_task();//任務(wù)輪詢
}

結(jié)語

整體實(shí)現(xiàn)說難不難,說簡(jiǎn)單不簡(jiǎn)單,但也是我第一次嘗試這種偏向系統(tǒng)級(jí)應(yīng)用的代碼,而且都沒有參照任何其他的資料和代碼,完全以自己的對(duì)任務(wù)的理解和具體項(xiàng)目的需求來一點(diǎn)點(diǎn)實(shí)現(xiàn),希望后面會(huì)把這個(gè)調(diào)度的代碼進(jìn)一步完善成一個(gè)通用型的調(diào)度方式,也方便后面項(xiàng)目的使用了。

到此這篇關(guān)于利用C語言實(shí)現(xiàn)任務(wù)調(diào)度的示例代碼的文章就介紹到這了,更多相關(guān)C語言任務(wù)調(diào)度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C++?STL模擬實(shí)現(xiàn)vector

    詳解C++?STL模擬實(shí)現(xiàn)vector

    這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器vector,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2023-01-01
  • C語言實(shí)現(xiàn)三子棋的示例代碼

    C語言實(shí)現(xiàn)三子棋的示例代碼

    所謂三子棋,就是三行三列的棋盤,玩家可以和電腦下棋,率先連成三個(gè)的獲勝。這篇文章主要為大家詳細(xì)介紹了如何通過C語言實(shí)現(xiàn)三子棋小游戲,感興趣的小伙伴可以嘗試一下
    2023-01-01
  • 深入解析C++設(shè)計(jì)模式編程中解釋器模式的運(yùn)用

    深入解析C++設(shè)計(jì)模式編程中解釋器模式的運(yùn)用

    這篇文章主要介紹了C++設(shè)計(jì)模式編程中解釋器模式的運(yùn)用,解釋器模式給定一個(gè)語言,定義它的文法的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語言中的句子,需要的朋友可以參考下
    2016-03-03
  • QT實(shí)戰(zhàn)之打開最近文檔功能的實(shí)現(xiàn)

    QT實(shí)戰(zhàn)之打開最近文檔功能的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)打開最近文檔功能,并實(shí)現(xiàn)基本的新建、打開、保存、退出、幫助等功能,感興趣的可以動(dòng)手嘗試一下
    2022-06-06
  • C++ delete之靜態(tài)變量問題詳解

    C++ delete之靜態(tài)變量問題詳解

    這篇文章主要為大家詳細(xì)介紹了C++delete的一些問題,學(xué)習(xí)如何動(dòng)態(tài)創(chuàng)建對(duì)象,動(dòng)態(tài)創(chuàng)建的對(duì)象與一般對(duì)象的區(qū)別,動(dòng)態(tài)創(chuàng)建的對(duì)象的初始化以及釋放動(dòng)態(tài)分配的內(nèi)存等知識(shí)點(diǎn),感興趣的朋友可以參考一下
    2021-09-09
  • C++中fstream,ifstream及ofstream用法淺析

    C++中fstream,ifstream及ofstream用法淺析

    這篇文章主要介紹了C++中fstream,ifstream及ofstream用法,適合C++初學(xué)者學(xué)習(xí)文件流的操作,需要的朋友可以參考下
    2014-08-08
  • 詳解C++ 前置聲明

    詳解C++ 前置聲明

    這篇文章主要介紹了C++ 前置聲明的相關(guān)資料,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下
    2020-09-09
  • 利用C++實(shí)現(xiàn)?然連接操作算法

    利用C++實(shí)現(xiàn)?然連接操作算法

    這篇文章主要介紹了利用C++實(shí)現(xiàn)?然連接操作算法,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • C++ Primer Plus 第四章之C++ Primer Plus復(fù)合類型學(xué)習(xí)筆記

    C++ Primer Plus 第四章之C++ Primer Plus復(fù)合類型學(xué)習(xí)筆記

    數(shù)組(array)是一種數(shù)據(jù)格式,能夠存儲(chǔ)多個(gè)同類型的值。每個(gè)值都存儲(chǔ)在一個(gè)獨(dú)立的數(shù)組元素中,計(jì)算機(jī)在內(nèi)存中依次存儲(chǔ)數(shù)組的各個(gè)元素,今天給大家重點(diǎn)介紹C++ Primer Plus復(fù)合類型的實(shí)例詳解,感興趣的朋友一起看看吧
    2021-07-07
  • opencv圖片的任意角度旋轉(zhuǎn)實(shí)現(xiàn)示例

    opencv圖片的任意角度旋轉(zhuǎn)實(shí)現(xiàn)示例

    這篇博客將介紹如何使用OpenCV旋轉(zhuǎn)圖像任意角度,實(shí)現(xiàn)各個(gè)角度的旋轉(zhuǎn),具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06

最新評(píng)論

万年县| 邯郸市| 黄骅市| 泰兴市| 龙海市| 莲花县| 阳原县| 车致| 新绛县| 卢龙县| 博湖县| 富源县| 泾源县| 麟游县| 延安市| 黎平县| 富顺县| 广东省| 合肥市| 翼城县| 崇州市| 静乐县| 洪江市| 二连浩特市| 石狮市| 杭锦后旗| 左贡县| 揭阳市| 东港市| 洞口县| 通道| 肥西县| 武定县| 宁河县| 德安县| 阿克陶县| 独山县| 石河子市| 济源市| 大邑县| 竹北市|