日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

同优先级时间片运行

發布時間:2025/4/5 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 同优先级时间片运行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 同優先級時間片運行
      • 1.1 設計目標
      • 1.2 設計原理
      • 1.3 設計實現

1 同優先級時間片運行

1.1 設計目標

構建一個允許多任務具備相同優先級,且同優先級任務按時間片占用CPU運行的系統。

1.2 設計原理

當前設計:每個優先級只允許一個任務。

新的設計:

1.3 設計實現

配置優先級列表:

任務鏈接結點:

修改獲取最高優先級任務的方式:

時鐘節拍處理:增加時間片輪轉。

主要代碼實現如下:

/*************************************** Copyright (c)****************************************************** ** File name : main.c ** Latest modified Date : 2016-06-01 ** Latest Version : 0.1 ** Descriptions : 主文件,包含應用代碼 ** **-------------------------------------------------------------------------------------------------------- ** Created by : 01課堂 lishutong ** Created date : 2016-06-01 ** Version : 1.0 ** Descriptions : The original version ** **-------------------------------------------------------------------------------------------------------- ** Copyright : 版權所有,禁止用于商業用途 ** Author Blog : http://ilishutong.com **********************************************************************************************************/ #include "tinyOS.h" #include "ARMCM3.h"// 當前任務:記錄當前是哪個任務正在運行 tTask * currentTask;// 下一個將即運行的任務:在進行任務切換前,先設置好該值,然后任務切換過程中會從中讀取下一任務信息 tTask * nextTask;// 空閑任務 tTask * idleTask;// 任務優先級的標記位置結構 tBitmap taskPrioBitmap;// 所有任務的指針數組:簡單起見,只使用兩個任務 tList taskTable[TINYOS_PRO_COUNT];// 調度鎖計數器 uint8_t schedLockCount;// 延時隊列 tList tTaskDelayedList;/********************************************************************************************************** ** Function name : tTaskInit ** Descriptions : 初始化任務結構 ** parameters : task 要初始化的任務結構 ** parameters : entry 任務的入口函數 ** parameters : param 傳遞給任務的運行參數 ** Returned value : 無 ***********************************************************************************************************/ void tTaskInit (tTask * task, void (*entry)(void *), void *param, uint32_t prio, uint32_t * stack) {// 為了簡化代碼,tinyOS無論是在啟動時切換至第一個任務,還是在運行過程中在不同間任務切換// 所執行的操作都是先保存當前任務的運行環境參數(CPU寄存器值)的堆棧中(如果已經運行運行起來的話),然后再// 取出從下一個任務的堆棧中取出之前的運行環境參數,然后恢復到CPU寄存器// 對于切換至之前從沒有運行過的任務,我們為它配置一個“虛假的”保存現場,然后使用該現場恢復。// 注意以下兩點:// 1、不需要用到的寄存器,直接填了寄存器號,方便在IDE調試時查看效果;// 2、順序不能變,要結合PendSV_Handler以及CPU對異常的處理流程來理解*(--stack) = (unsigned long)(1<<24); // XPSR, 設置了Thumb模式,恢復到Thumb狀態而非ARM狀態運行*(--stack) = (unsigned long)entry; // 程序的入口地址*(--stack) = (unsigned long)0x14; // R14(LR), 任務不會通過return xxx結束自己,所以未用*(--stack) = (unsigned long)0x12; // R12, 未用*(--stack) = (unsigned long)0x3; // R3, 未用*(--stack) = (unsigned long)0x2; // R2, 未用*(--stack) = (unsigned long)0x1; // R1, 未用*(--stack) = (unsigned long)param; // R0 = param, 傳給任務的入口函數*(--stack) = (unsigned long)0x11; // R11, 未用*(--stack) = (unsigned long)0x10; // R10, 未用*(--stack) = (unsigned long)0x9; // R9, 未用*(--stack) = (unsigned long)0x8; // R8, 未用*(--stack) = (unsigned long)0x7; // R7, 未用*(--stack) = (unsigned long)0x6; // R6, 未用*(--stack) = (unsigned long)0x5; // R5, 未用*(--stack) = (unsigned long)0x4; // R4, 未用task->slice = TINYOS_SLICE_MAX; // 初始化任務的時間片計數task->stack = stack; // 保存最終的值task->delayTicks = 0;task->prio = prio; // 設置任務的優先級task->state = TINYOS_TASK_STATE_RDY; // 設置任務為就緒狀態tNodeInit(&(task->delayNode)); // 初始化延時結點tNodeInit(&(task->linkNode)); // 初始化鏈接結點tListAddLast(&taskTable[prio], &(task->linkNode)); // 插入對應的優先級隊列中tBitmapSet(&taskPrioBitmap, prio); // 標記優先級位置中的相應位 }/********************************************************************************************************** ** Function name : tTaskHighestReady ** Descriptions : 獲取當前最高優先級且可運行的任務 ** parameters : 無 ** Returned value : 優先級最高的且可運行的任務 ***********************************************************************************************************/ tTask * tTaskHighestReady (void) {uint32_t highestPrio = tBitmapGetFirstSet(&taskPrioBitmap);tNode * node = tListFirst(&taskTable[highestPrio]);return (tTask *)tNodeParent(node, tTask, linkNode); }/********************************************************************************************************** ** Function name : 初始化調度器 ** Descriptions : 無 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSchedInit (void) {int i = 0;schedLockCount = 0;tBitmapInit(&taskPrioBitmap);for (i = 0; i < TINYOS_PRO_COUNT; i++){tListInit(&taskTable[i]);} }/********************************************************************************************************** ** Function name : tTaskSchedDisable ** Descriptions : 禁止任務調度 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSchedDisable (void) {uint32_t status = tTaskEnterCritical();if (schedLockCount < 255) {schedLockCount++;}tTaskExitCritical(status); }/********************************************************************************************************** ** Function name : tTaskSchedEnable ** Descriptions : 允許任務調度 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSchedEnable (void) {uint32_t status = tTaskEnterCritical();if (schedLockCount > 0) {if (--schedLockCount == 0) {tTaskSched(); }}tTaskExitCritical(status); }/********************************************************************************************************** ** Function name : tTaskSchedRdy ** Descriptions : 將任務設置為就緒狀態 ** input parameters : task 等待設置為就緒狀態的任務 ** output parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSchedRdy (tTask * task) {tListAddLast(&taskTable[task->prio], &(task->linkNode));tBitmapSet(&taskPrioBitmap, task->prio); }/************************************************************************************************************ Function name : tSchedulerUnRdyTask ** Descriptions : tTaskSchedUnRdy ** Descriptions : 將任務從就緒列表中移除 ** input parameters : task òaò?3yμ?è????é ** output parameters : None ** Returned value : None ***********************************************************************************************************/ void tTaskSchedUnRdy (tTask * task) {tListRemove(&taskTable[task->prio], &(task->linkNode));// 隊列中可能存在多個任務。只有當沒有任務時,才清除位圖標記if (tListCount(&taskTable[task->prio]) == 0){tBitmapClear(&taskPrioBitmap, task->prio);} }/********************************************************************************************************** ** Function name : tTaskSched ** Descriptions : 任務調度接口。tinyOS通過它來選擇下一個具體的任務,然后切換至該任務運行。 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSched (void) { tTask * tempTask;// 進入臨界區,以保護在整個任務調度與切換期間,不會因為發生中斷導致currentTask和nextTask可能更改uint32_t status = tTaskEnterCritical();// 如何調度器已經被上鎖,則不進行調度,直接退bmif (schedLockCount > 0) {tTaskExitCritical(status);return;}// 找到優先級最高的任務。這個任務的優先級可能比當前低低// 但是當前任務是因為延時才需要切換,所以必須切換過去,也就是說不能再通過判斷優先級來決定是否切換// 只要判斷不是當前任務,就立即切換過去tempTask = tTaskHighestReady();if (tempTask != currentTask) {nextTask = tempTask;tTaskSwitch(); }// 退出臨界區tTaskExitCritical(status); }/********************************************************************************************************** ** Function name : tTaskDelayedInit ** Descriptions : 初始化任務延時機制 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskDelayedInit (void) {tListInit(&tTaskDelayedList); }/********************************************************************************************************** ** Function name : tTimeTaskWait ** Descriptions : 將任務加入延時隊列中 ** input parameters : task 需要延時的任務 ** ticks 延時的ticks ** output parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTimeTaskWait (tTask * task, uint32_t ticks) {task->delayTicks = ticks;tListAddLast(&tTaskDelayedList, &(task->delayNode)); task->state |= TINYOS_TASK_STATE_DELAYED; }/********************************************************************************************************** ** Function name : tTimeTaskWakeUp ** Descriptions : 將延時的任務從延時隊列中喚醒 ** input parameters : task 需要喚醒的任務 ** output parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTimeTaskWakeUp (tTask * task) {tListRemove(&tTaskDelayedList, &(task->delayNode));task->state &= ~TINYOS_TASK_STATE_DELAYED; }/********************************************************************************************************** ** Function name : tTaskSystemTickHandler ** Descriptions : 系統時鐘節拍處理。 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSystemTickHandler (void) {tNode * node;// 進入臨界區,以保護在整個任務調度與切換期間,不會因為發生中斷導致currentTask和nextTask可能更改uint32_t status = tTaskEnterCritical();// 檢查所有任務的delayTicks數,如果不0的話,減1。for (node = tTaskDelayedList.headNode.nextNode; node != &(tTaskDelayedList.headNode); node = node->nextNode){tTask * task = tNodeParent(node, tTask, delayNode);if (--task->delayTicks == 0) {// 將任務從延時隊列中移除tTimeTaskWakeUp(task);// 將任務恢復到就緒狀態tTaskSchedRdy(task); }}// 檢查下當前任務的時間片是否已經到了if (--currentTask->slice == 0){// 如果當前任務中還有其它任務的話,那么切換到下一個任務// 方法是將當前任務從隊列的頭部移除,插入到尾部// 這樣后面執行tTaskSched()時就會從頭部取出新的任務取出新的任務作為當前任務運行if (tListCount(&taskTable[currentTask->prio]) > 0){tListRemoveFirst(&taskTable[currentTask->prio]);tListAddLast(&taskTable[currentTask->prio], &(currentTask->linkNode));// 重置計數器currentTask->slice = TINYOS_SLICE_MAX;}}// 退出臨界區tTaskExitCritical(status); // 這個過程中可能有任務延時完畢(delayTicks = 0),進行一次調度。tTaskSched(); }/********************************************************************************************************** ** Function name : tTaskDelay ** Descriptions : 使當前任務進入延時狀態。 ** parameters : delay 延時多少個ticks ** Returned value : 無 ***********************************************************************************************************/ void tTaskDelay (uint32_t delay) {// 進入臨界區,以保護在整個任務調度與切換期間,不會因為發生中斷導致currentTask和nextTask可能更改uint32_t status = tTaskEnterCritical();// 設置延時值,插入延時隊列tTimeTaskWait(currentTask, delay);// 將任務從就緒表中移除tTaskSchedUnRdy(currentTask);// 然后進行任務切換,切換至另一個任務,或者空閑任務// delayTikcs會在時鐘中斷中自動減1.當減至0時,會切換回來繼續運行。tTaskSched();// 退出臨界區tTaskExitCritical(status); }/********************************************************************************************************* ** 系統時鐘節拍定時器System Tick配置 ** 在我們目前的環境(模擬器)中,系統時鐘節拍為12MHz ** 請務必按照本教程推薦配置,否則systemTick的值就會有變化,需要查看數據手冊才了解 **********************************************************************************************************/ void tSetSysTickPeriod(uint32_t ms) {SysTick->LOAD = ms * SystemCoreClock / 1000 - 1; NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);SysTick->VAL = 0; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |SysTick_CTRL_TICKINT_Msk |SysTick_CTRL_ENABLE_Msk; }/********************************************************************************************************** ** Function name : SysTick_Handler ** Descriptions : SystemTick的中斷處理函數。 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void SysTick_Handler () {tTaskSystemTickHandler(); }/********************************************************************************************************** ** 應用示例 ** 有兩個任務,分別執行task1Entry和task2Entry ** 其中task1Entry的優先級更高,只要它不處于延時狀態,那么就運行它 ** task2Entry和task3Entry相同優先級,按時間片切換運行,且在task1Entry延時時才能運行 **********************************************************************************************************/ int task1Flag; void task1Entry (void * param) {tSetSysTickPeriod(10);for (;;) {task1Flag = 1;tTaskDelay(1);task1Flag = 0;tTaskDelay(1);} }void delay () {int i;for (i = 0; i < 0xFF; i++) {} }int task2Flag; void task2Entry (void * param) {for (;;) {task2Flag = 1;delay();task2Flag = 0;delay();} }int task3Flag; void task3Entry (void * param) {for (;;){task3Flag = 1;delay();task3Flag = 0;delay();} }// 任務1和任務2的任務結構,以及用于堆棧空間 tTask tTask1; tTask tTask2; tTask tTask3; tTaskStack task1Env[1024]; tTaskStack task2Env[1024]; tTaskStack task3Env[1024];// 用于空閑任務的任務結構和堆棧空間 tTask tTaskIdle; tTaskStack idleTaskEnv[1024];void idleTaskEntry (void * param) {for (;;){// 空閑任務什么都不做} }int main () {// 優先初始化tinyOS的核心功能tTaskSchedInit();// 初始化延時隊列tTaskDelayedInit();// 初始化任務1和任務2結構,傳遞運行的起始地址,想要給任意參數,以及運行堆棧空間tTaskInit(&tTask1, task1Entry, (void *)0x11111111, 0, &task1Env[1024]);tTaskInit(&tTask2, task2Entry, (void *)0x22222222, 1, &task2Env[1024]);tTaskInit(&tTask3, task3Entry, (void *)0x33333333, 1, &task3Env[1024]);// 創建空閑任務tTaskInit(&tTaskIdle, idleTaskEntry, (void *)0, TINYOS_PRO_COUNT - 1, &idleTaskEnv[1024]);// 這里,不再指定先運行哪個任務,而是自動查找最高優先級的任務運行nextTask = tTaskHighestReady();// 切換到nextTask, 這個函數永遠不會返回tTaskRunFirst();return 0; }

參考資料:

  • 【李述銅】從0到1自己動手寫嵌入式操作系統
  • 總結

    以上是生活随笔為你收集整理的同优先级时间片运行的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 中文字幕一区二区av | 日本婷婷 | 亚洲免费专区 | 在线观看黄色大片 | 国产女人18毛片18精品 | 成年丰满熟妇午夜免费视频 | 国产孕妇一区二区三区 | 久久在线免费 | 韩日av一区二区 | 性猛交xxxx | 日韩欧美在线观看视频 | 久久精品99 | 蜜桃99视频一区二区三区 | 免费成人在线观看视频 | 天天干天天做 | 国产乱来 | 亚洲女优视频 | 国内自拍偷拍视频 | 5级黄色片| 97人妻精品一区二区三区动漫 | 福利网址在线 | 国产精品入口 | 日本在线视频不卡 | 久久性生活片 | 学生调教贱奴丨vk | 国产裸体无遮挡 | 91精产国品 | 丰满岳乱妇在线观看中字无码 | 精品无码一区二区三区 | 黄色综合网| 三级黄色片免费 | 日日操夜夜骑 | 成年人在线视频观看 | 国产精品99精品无码视亚 | 丰满少妇高潮久久三区 | 一区二区在线视频播放 | 亚洲麻豆一区二区三区 | 美女扒开粉嫩尿口 | 精品视频大全 | 黄色成人在线观看 | 黄色一级免费网站 | 2020国产精品| 懂色一区二区三区 | 日韩成人免费电影 | 黄色资源网 | 国产高清在线观看视频 | 波多野结衣一级 | 中文字幕一区二区三区在线播放 | 网站久久 | 2018自拍偷拍 | 女人裸体又黄 | 亚洲 激情| 亚洲第一色网 | 国产 第1190页| 羞羞软件 | 亚洲欧美成人一区二区 | 精品国产乱码久久久久久蜜臀 | 中文字幕一区二区三区久久久 | 亚洲国产一二三 | 狗爬女子的视频 | 一级片国产 | 肉丝美足丝袜一区二区三区四 | 一区不卡在线观看 | 国产精品美女 | 欧美激情在线观看 | 国产一区二区三区四区hd | 亚洲天堂99 | www日韩精品 | 天天摸天天干天天操 | 综合久久网 | 97视频一区二区三区 | av番号网| 亚洲激情网| 日韩av网站在线播放 | 亚洲视频 欧美视频 | 男女视频一区 | 国产精欧美一区二区三区蓝颜男同 | 欧美高清性 | 三级全黄做爰龚玥菲在线 | 三级在线看中文字幕完整版 | 中文久久精品 | 色眯眯影视 | 中文字幕日产av | 日韩精品一区二区三区视频在线观看 | 国产亚洲视频一区 | 亚洲国产精华液网站w | 蜜桃色一区二区三区 | 激情女主播 | 国产精品久久久久久久久久小说 | 欧美日韩国产区 | 亚洲视频1| 午夜神马影院 | 三上悠亚ssⅰn939无码播放 | 国产欧美一区二区 | 无码一区二区三区视频 | 国产日韩精品中文字无码 | 欧美日韩免费网站 | 欧美精品二区三区 | 色网在线视频 |