FreeRTOS 任務排程 List 組織

2021-07-23 09:11:11 字數 2916 閱讀 6271

@(嵌入式)

freertos

前面了解了 freertos 的記憶體管理,接下來看看任務排程,這也是乙個作業系統中最重要的一部分,而其任務排程大量使用了鍊錶(list.c 實現),排程器使用鍊錶跟蹤不同狀態下的任務(就緒、掛起、延時的任務,都會被掛接到各自的鍊錶中),所以這裡用一定篇幅介紹下主要供排程使用的鍊錶檔案是如何組織的。

我目前使用的原始碼版本是v9.0.0

freertos 鍊錶中主要的資料結構是鍊錶(xlist)和煉表項(xlist_item),以及乙個低配的煉表項(xmini_list_item)包含於鍊錶中,具體定義和作用下面介紹。定義內容在source/include/list.h

煉表項就是鍊錶每個節點的資料結構,其每個成員的具體作用如注釋所示。

其中開頭和結尾兩個巨集的作用是檢查資料是否完整,當設定source/include/projdefs.hconfiguse_list_data_integrity_check_bytes 為1的時候,以下結構體會在開始和結尾新增兩個變數儲存 magic number(0x5a5a…)供校驗。

(後面說明假設沒有開啟校驗)

struct xlist_item

;

鍊錶包含多個煉表項(節點),鍊錶資料結構中包含乙個簡單的列表項用於表示其尾部(前面提到的低配版列表項)用於標記鍊錶的結束(包含指向第乙個節點)

struct xmini_list_item

;typedef

struct xmini_list_item minilistitem_t;

/* * definition of the type of queue used by the scheduler.

*/typedef

struct xlist

list_t;

每個鍊錶的結構如下所示,通過其成員 xlistend 的指標指向其他煉表項,組織成乙個完整的鍊錶。

結合 list.c, 看看 freertos 的鍊錶是如何實現的。

在使用鍊錶前,需要呼叫 freertos 提供的初始化函式進行初始化

void vlistinitialise( list_t * const pxlist )

初始化結束後,鍊錶組織如下圖所示。

相應地準備插入新節點前,需要對新節點進行初始化,可以呼叫函式 :

void vlistinitialiseitem( listitem_t * const pxitem )

主要功能是檢測新節點是否可用(如果開啟檢測)

完成鍊錶初始化後,在需要插入新節點的時候,可以呼叫插入函式完成,新節點按照其xitemvalue的值逆序插入鍊錶中。

void vlistinsert( list_t * const pxlist, 

listitem_t * const pxnewlistitem )

else

}// 插入節點 如下圖 : 1步2步3步4步..(牽著手)

pxnewlistitem->pxnext = pxiterator->pxnext;

pxnewlistitem->pxnext->pxprevious = pxnewlistitem;

pxnewlistitem->pxprevious = pxiterator;

pxiterator->pxnext = pxnewlistitem;

// 更新插入節點所屬鍊錶

pxnewlistitem->pvcontainer = ( void * ) pxlist;

// 借點統計

( pxlist->uxnumberofitems )++;

}

插入乙個xitemvalue == 1的節點 xlist_item_1 :

再插入乙個xitemvalue == 2的節點 xlist_item_2, 按照鍊錶的排序規則(遞減),得到如下 鍊錶 :

freertos 提供另外乙個插入節點的函式,可以直接把新節點插入到鍊錶的尾部。

void vlistinsertend( list_t * const pxlist, listitem_t * const pxnewlistitem )

相比一般插入需要按值查詢插入位置,從尾部插入更為簡單。

由於節點中包含指向所屬鍊錶的指標,所以移除節點時只需傳遞該節點即可。

ubasetype_t uxlistremove( listitem_t * const pxitemtoremove )

else

// 清除所屬關係

pxitemtoremove->pvcontainer = null;

// 更新統計

( pxlist->uxnumberofitems )--;

return pxlist->uxnumberofitems;

}

到此,結束,還有一些簡單的巨集定義這裡不做詳細介紹,基本都是鍊錶的操作,這裡介紹下,避免後續 task 排程分析帶來一些不必要的困惑。

原始碼

freertos作業系統 任務排程

一 任務建立 目的 應用程式中如何給各任務分配處理時間 任意時刻,os如何使任務投入執行 優先順序如何影響系統行為 任務狀態 如何實現任務 建立乙個或多個任務的例項 任務引數的使用 right 改變任務優先順序 刪除任務 週期性處理 空閒任務何時執行,可以用來幹什麼 解決 任務實現 任務函式 voi...

FreeRTOS簡單任務排程實現

ifndef rtos h define rtos h include freertos.h include task.h define pex rtos start rtos start void rtos start void void freertos task1 void pvparamet...

freertos學習之任務排程切換

freertos 的任務具有如下幾種狀態 執行running 就緒ready 阻塞blocked 掛起suspended 除了執行狀態之外的狀態統稱為非執行狀態。因為 freertos 是為單cpu設計的系統,在任何時刻最多只能允許乙個任務處在執行狀態,哪怕看起來好像有多個任務同時在執行 這只是多個...