LiteOS 消息队列
生活随笔
收集整理的這篇文章主要介紹了
LiteOS 消息队列
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
參考:【野火】物聯(lián)網操作系統(tǒng) LiteOS 開發(fā)實戰(zhàn)指南
3 LiteOS消息隊列
3.1 消息隊列簡介
3.2 LiteOS消息隊列的特點
3.3 LiteOs消息隊列的運作機制
LiteOs消息隊列運作圖
消息隊列讀寫消息圖
3.4 LiteOs消息隊列的傳輸機制
消息隊列是一種FIFO線性表,也支持LIFO
消息數據傳輸支持值傳遞(拷貝)和引用傳遞
兩種傳遞方式比較
| 拷貝 | 數據量小的場合 | 數據重要性高 |
| 引用方式 | 數據量大的場合 | 重要性一般場合 |
3.5 消息隊列的阻塞機制
- 顧名思義,就是指讀/寫消息隊列時,能夠完整的不受其他任務干擾的完成讀/寫,即阻塞機制
3.5.1 出隊阻塞
- 讀操作,若消息隊列中沒有消息,會有三種選擇
- 該任務繼續(xù)干別的事情,不會進入阻塞狀態(tài)
- 該任務等待消息隊列的消息,等待時間由用戶定制,等待過程即為阻塞狀態(tài),消息隊列有了對應的消息后,該任務轉為就緒狀態(tài),然后根據該任務的優(yōu)先級讀取隊列消息,若超時,則該任務放棄等待,去干別的事情
- 該任務死等,等不到消息就不干別的事情,該任務一直進入阻塞狀態(tài),直到完成讀取隊列的消息
3.5.2 入隊阻塞
- 寫操作,若消息隊列已經滿了,會進行如下處理
- 發(fā)送消息操作的時候,當且僅當隊列被允許入隊時,發(fā)送者才能成功發(fā)送消息
- 隊列中無可用消息空間時,系統(tǒng)會根據用戶指定的阻塞超時時間將任務阻塞,在指定的超時時間內如果還不能完成入隊操作,發(fā)送消息的任務或者中斷服務程序會收到一個錯誤代碼LOS_ERRNO_QUEUE_ISFULL ,然后解除阻塞狀態(tài)
- 只有在任務中發(fā)送消息才允許進行阻塞狀態(tài),在中斷中發(fā)送消息不允許帶有阻塞機制的,否則返回錯誤代碼LOS_ERRNO_QUEUE_READ_IN_INTERRUPT
- 如果有多個任務阻塞在一個消息隊列中,那么這些阻塞的任務將按照任務優(yōu)先級進行排序,優(yōu)先級高的任務將優(yōu)先獲得隊列的訪問權
3.6 常用消息隊列的函數介紹
3.6.1 使用隊列模塊的典型流程
3.6.2 創(chuàng)建消息隊列LOS_QueueCreate()
創(chuàng)建消息隊列的內存空間:
內存空間=消息隊列控制塊大小+(單個消息空間大小+4字節(jié))?消息隊列長度內存空間=消息隊列控制塊大小+(單個消息空間大小+4字節(jié))*消息隊列長度 內存空間=消息隊列控制塊大小+(單個消息空間大小+4字節(jié))?消息隊列長度
當消息隊列被創(chuàng)建時,系統(tǒng)會為控制塊分配對應的內存空間,用于保存消息隊列的(消息存儲位置,頭指針,尾指針,消息大小,以及隊列長度等)
先定義隊列ID,再調用LOS_QueueCreate() 函數創(chuàng)建,才能成功創(chuàng)建消息隊列
3.6.2 消息隊列刪除函數LOS_QueueDelete()
隊列刪除函數是直接根據隊列ID直接刪除的
UINT32 LOS_QueueDelete(UINT32 uwQueueID)隊列在使用或者阻塞中是不能被刪除的
3.6.3 消息隊列寫數據函數
任務或者中斷程序都可以給消息隊列寫入消息
當寫入消息時,
- 如果隊列未滿,LiteOS會將消息拷貝到消息隊列的尾部,
- 若滿,會根據用戶指定的阻塞超時時間進行阻塞,在這段時間中,如果隊列還是滿的,該任務將保持阻塞狀態(tài)以等待有空閑的消息空間,如果其他任務從其等待的隊列中讀取了數據,則消息隊列空出空間,該等待的任務自動由阻塞狀態(tài)轉為就緒態(tài),并寫入消息
- 當任務等待的時間超過指定的阻塞時間,即使隊列中還是滿的,任務也會自動從阻塞狀態(tài)變?yōu)榫途w態(tài),此時發(fā)送消息的任務/中斷程序會收到一個錯誤碼:LOS_ERRNO_QUEUE_ISFULL
不帶拷貝寫入函數LOS_QueueWrite():
UINT32 LOS_QueueWrite(UINT32 uwQueueID, // 隊列IDVOID *pBufferAddr, // 存儲寫入的數據的起始地址UINT32 uwBufferSize, // 存入緩存區(qū)的大小UINT32 uwTimeOut); // 等待時間(0~LOS_WAIT_FOREVER)寫入隊列需要注意幾點:
- 在使用寫入隊列的操作前應先創(chuàng)建要寫入的隊列
- 在中斷上下文環(huán)境中, 必須使用非阻塞模式寫入,也就是等待時間為 0 個 tick
- 在初始化 LiteOS 之前無法調用此 API
- 將寫入由 uwBufferSize 指定大小的數據,其數據存儲在 BufferAddr 指定的地址 ,那么該數據地址必須有效,否則會發(fā)生錯誤
- 寫入隊列節(jié)點中的是數據的地址
帶拷貝寫入LOS_ QueueWriteCopy()
UINT32 LOS_QueueWriteCopy(UINT32 uwQueueID, // 隊列IDVOID *pBufferAddr, // 存儲寫入的數據的起始地址UINT32 uwBufferSize, // 存入緩存區(qū)的大小UINT32 uwTimeOut); // 等待時間(0~LOS_WAIT_FOREVER)3.6.4 消息隊列讀數據函數
LOS_ QueueRead()(不帶拷貝方式讀出)
UINT32 LOS_QueueRead(UINT32 uwQueueID, // 隊列IDVOID *pBufferAddr, // 存儲寫入的數據的起始地址UINT32 uwBufferSize, // 存入緩存區(qū)的大小UINT32 uwTimeOut); // 等待時間(0~LOS_WAIT_FOREVER)注意點:
- 在使用讀取隊列的操作前應先創(chuàng)建要寫入的隊列
- 隊列讀取采用的是先進先出(FIFO)模式, 首先讀取首先存儲在隊列中的數據
- 必須要我們自己定義一個存儲讀取出來的數據的地方,并且把存儲數據的起始地址傳遞給 LOS_ QueueRead()函數,否則,將發(fā)生地址非法的錯誤。
- 在中斷上下文環(huán)境中, 必須使用非阻塞模式寫入,也就是等待時間為 0 個 tick
- 在初始化 LiteOS 之前無法調用此 API
- pBufferAddr里存放的是隊列節(jié)點的地址
- LOS_QueueReadCopy()和 LOS_QueueWriteCopy()是一組接口,LOS_QueueRead()和 LOS_QueueWrite()是一組接口,兩組接口需要配套使用
LOS_ QueueReadCopy()(帶拷貝讀出)
UINT32 LOS_QueueReadCopy(UINT32 uwQueueID, // 隊列 IDVOID * pBufferAddr, // 存儲獲取數據的起始地址UINT32 * puwBufferSize,// 保存讀取之后數據大小的值UINT32 uwTimeOut) // 等待時間- pBufferAddr存放的是消息隊列中的數據
- 需要定義一個空間保存讀取數據的大小
總結
以上是生活随笔為你收集整理的LiteOS 消息队列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python判断队列是否为空_pytho
- 下一篇: 百度地图线路颜色_你是铁路大亨吗?五个值