自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

消息隊(duì)列在RTOS的應(yīng)用

企業(yè)動(dòng)態(tài)
RTOS是一個(gè)管理CPU的軟件, 即微處理單元(MPU) , 還可能管理高效的DSP。 大多數(shù) RTOS 內(nèi)核是用 c 語言編寫的, 同時(shí)需要用匯編語言編寫一小部分代碼來適應(yīng)不同的 CPU 架構(gòu)。

傳說互聯(lián)網(wǎng)應(yīng)用有兩大利器,一個(gè)是緩存,另一個(gè)就是消息隊(duì)列。 一直相對消息隊(duì)列做一下梳理,希望早日另有成文。 一葉知秋,實(shí)際上消息隊(duì)列在嵌入式系統(tǒng)中同樣有著廣泛的應(yīng)用。 近來致力于IoT和智能硬件,現(xiàn)學(xué)習(xí)一下消息隊(duì)列在RTOS中的應(yīng)用場景。

RTOS是一個(gè)管理CPU的軟件, 即微處理單元(MPU) , 還可能管理高效的DSP。 大多數(shù) RTOS 內(nèi)核是用 c 語言編寫的, 同時(shí)需要用匯編語言編寫一小部分代碼來適應(yīng)不同的 CPU 架構(gòu)。一個(gè) RTOS 內(nèi)核為開發(fā)者提供了許多有用的服務(wù), 如多任務(wù)處理、中斷管理、通過消息隊(duì)列、信號(hào)量、資源管理、時(shí)間管理、內(nèi)存分區(qū)管理等等。

[[227344]]

應(yīng)用程序或者最終地產(chǎn)品基本上會(huì)劃分為多個(gè)任務(wù), 每個(gè)任務(wù)負(fù)責(zé)應(yīng)用程序的一部分。 一個(gè)任務(wù)就是一個(gè)簡單的程序, 它有自己的 CPU使用時(shí)間。 根據(jù)任務(wù)的重要性, 每個(gè)任務(wù)都被賦予了優(yōu)先級(jí)。

RTOS中的消息隊(duì)列

圖1 消息隊(duì)列是用于將內(nèi)容傳遞給任務(wù)的內(nèi)核對象

如圖1所示, 消息隊(duì)列是一個(gè)核心對象(即數(shù)據(jù)結(jié)構(gòu)) , 通過這個(gè)對象, 消息從中斷服務(wù)例程(ISR)或任務(wù)發(fā)送到另一個(gè)任務(wù)。 應(yīng)用程序可以有任意數(shù)量的消息隊(duì)列, 每一個(gè)都有自己的目的和用途。 例如, 消息隊(duì)列可以用來將從通信接口 ISR 接收到的數(shù)據(jù)包傳遞給一個(gè)任務(wù), 而 ISR 則負(fù)責(zé)處理數(shù)據(jù)包。 另一個(gè)隊(duì)列可以用來將內(nèi)容傳遞給顯示任務(wù), 該任務(wù)將負(fù)責(zé)正確地更新顯示的內(nèi)容。

消息通常是指向包含實(shí)際消息存儲(chǔ)區(qū)域的void指針。 這些指針可以指向任何東西, 甚至可以指向接收任務(wù)執(zhí)行的函數(shù)。 因此, 它的實(shí)際含義取決于應(yīng)用程序。 每個(gè)消息隊(duì)列都可以根據(jù)它將保存的存儲(chǔ)量進(jìn)行配置。 消息隊(duì)列可以配置為保存單個(gè)消息或者 n 個(gè)消息。 隊(duì)列的大小取決于應(yīng)用程序以及消費(fèi)者的處理速度。

如果一個(gè)任務(wù)等待一條消息, 并且隊(duì)列中沒有消息, 則該任務(wù)將被掛起, 直到有消息發(fā)送到隊(duì)列中。 等待任務(wù)不消耗 CPU 時(shí)間, RTOS 可以運(yùn)行其他任務(wù)。 如圖1所示, 掛起的任務(wù)可以指定超時(shí)。 如果在指定時(shí)間內(nèi)未收到消息, 則當(dāng)該任務(wù)成為***優(yōu)先任務(wù)時(shí), 將允許任務(wù)恢復(fù)執(zhí)行(即 unblock)。 當(dāng)任務(wù)執(zhí)行時(shí), 基本上會(huì)被告知它恢復(fù)的原因是因?yàn)槌瑫r(shí)。

消息隊(duì)列通常作為先入先出(FIFO)實(shí)現(xiàn), 這意味著收到的***個(gè)消息將是從隊(duì)列中提取的***個(gè)消息。 然而, 有些內(nèi)核允許發(fā)送被認(rèn)為比其他內(nèi)核更重要的消息, 從而排在隊(duì)列的首位。 換句話說, 在"先入先出"順序中, 使該消息成為任務(wù)提取的***條信息。

消息隊(duì)列的另一個(gè)重要方面是, 消息本身需要保持從發(fā)送到處理的時(shí)間范圍。 這意味著不能將指針傳遞給棧變量等等。 為了將消息保持在作用域中, 通常會(huì)填充一個(gè)結(jié)構(gòu), 并從這些消息池中獲取, 如圖2所示。 

圖2 消息池的存儲(chǔ)區(qū)域

發(fā)送消息的 ISR 或任務(wù)將從池中獲取結(jié)構(gòu), 填充結(jié)構(gòu), 并將指針指向隊(duì)列的結(jié)構(gòu)。 接收任務(wù)將從隊(duì)列中提取指針, 處理結(jié)構(gòu), 完成后將結(jié)構(gòu)返回到池中。 當(dāng)然, 發(fā)送方和接收方都需要使用相同的池, 除非數(shù)據(jù)結(jié)構(gòu)中的字段指示使用了哪個(gè)池。

在 RTOS 中的許多消息隊(duì)列實(shí)現(xiàn)中, 如隊(duì)列已滿, 則發(fā)送到隊(duì)列的消息將被丟棄。 通常這不是一個(gè)問題, 應(yīng)用程序的邏輯可以從這種情況中恢復(fù)。 然而, 如圖3所示, 實(shí)現(xiàn)一個(gè)發(fā)送任務(wù)會(huì)發(fā)送消息的機(jī)制是相當(dāng)容易的:

圖3 如果隊(duì)列已滿, 則阻止發(fā)送

  • 計(jì)數(shù)信號(hào)的初始化值與隊(duì)列可接受的***條目數(shù)相對應(yīng)
  • 發(fā)送任務(wù)在允許將消息發(fā)送到隊(duì)列之前檢查信號(hào)量。 如果信號(hào)量值為零, 則發(fā)送方等待。
  • 如果值為非零, 則信號(hào)量減少, 發(fā)送方將消息發(fā)送到隊(duì)列中
  • 消息的接收方像往常一樣將消息隊(duì)列分隔開來
  • 當(dāng)收到消息時(shí), 接收這將指針從隊(duì)列中取出并向信號(hào)量發(fā)出信號(hào), 表示隊(duì)列中的條目已被釋放

如圖所示, 這個(gè)機(jī)制只適用于兩個(gè)任務(wù), 因?yàn)?ISR 不允許在信號(hào)量上分配信號(hào)。

消息隊(duì)列的典型用法

圖4顯示了消息隊(duì)列的不同用法:

1-4. 消息隊(duì)列通常用于從 ISR 發(fā)送消息或?qū)⑷蝿?wù)發(fā)送到另一個(gè)任務(wù), 如前面所討論的那樣

5.但是, 如果消息符合指針的大小, 則不必發(fā)送實(shí)際消息及分配存儲(chǔ)區(qū)域。 例如, 如果一個(gè)32位指針, 那么可以將模擬轉(zhuǎn)換器(ADC)從一個(gè)12位 ADC 讀取到一個(gè)指針, 并通過消息隊(duì)列發(fā)送,只要接收這知道將值返回整數(shù)即可, 這是完全合法的

6-7 一個(gè)任務(wù)如果知道這些消息將不會(huì)發(fā)送給它的,可以使用超時(shí)機(jī)制在一定的時(shí)間內(nèi)延遲自己。 在這種情況下, 一個(gè)能夠保存單個(gè)條目的隊(duì)列就足夠了。 事實(shí)上, 如果另一個(gè)任務(wù)或 ISR 發(fā)送消息, 那么延遲將被終止, 這可能也是想要實(shí)現(xiàn)的行為。

8 消息隊(duì)列可以作為一個(gè)信號(hào)量來簡單地向事件發(fā)生的任務(wù)發(fā)出信號(hào)。 在這種情況下, 信息可以是任何東西。 隊(duì)列的大小取決于應(yīng)用程序需要緩沖多少信號(hào)。

9-10 消息隊(duì)列也可以用作二進(jìn)制信號(hào)量或用于資源共享的計(jì)數(shù)信號(hào)量。 對于二進(jìn)制信號(hào)量, 隊(duì)列將包含單個(gè)消息, 并在隊(duì)列中放置消息(任何值)。 為了訪問資源, 可以在隊(duì)列上分配一個(gè)任務(wù)。 如果隊(duì)列中有消息, 則該任務(wù)將獲得對資源的訪問。 一旦使用了資源, 隊(duì)列就會(huì)被發(fā)布, 從而根據(jù)需要放棄資源, 供其他任務(wù)使用。 同樣的機(jī)制也適用于使用 n 個(gè)資源實(shí)現(xiàn)計(jì)數(shù)信號(hào), 隊(duì)列將預(yù)先填入n個(gè)虛擬消息。

11.消息實(shí)際上可以用來模擬事件標(biāo)志, 其中32位指針大小的變量中,每一位可以代表一個(gè)事件

12.消息隊(duì)列可以用來實(shí)現(xiàn)棧結(jié)構(gòu),這基本上是 LIFO 機(jī)制的另一個(gè)用途。

總而言之,消息隊(duì)列有許多不同方式的使用場景。 事實(shí)上, 通過消息隊(duì)列,可以編寫相當(dāng)復(fù)雜的應(yīng)用程序。 使用消息隊(duì)列可以減少代碼的大小, 可以被模擬(信號(hào)、時(shí)間延遲和事件標(biāo)志)許多其他的服務(wù)。

【本文來自51CTO專欄作者“老曹”的原創(chuàng)文章,作者微信公眾號(hào):喔家ArchiSelf,id:wrieless-com】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2010-04-21 14:49:13

Unix消息隊(duì)列

2010-04-21 12:12:56

Unix 消息隊(duì)列

2017-10-11 15:08:28

消息隊(duì)列常見

2024-03-29 08:33:10

應(yīng)用場景存儲(chǔ)搜索

2024-05-16 08:10:17

RabbitMQ軟件通信機(jī)制

2024-05-29 14:34:07

2021-03-11 06:01:41

Linux消息隊(duì)列

2018-03-29 08:38:10

2023-12-18 08:36:39

消息隊(duì)列微服務(wù)開發(fā)

2022-12-13 09:19:26

分布式消息隊(duì)列

2025-01-02 09:23:05

2023-12-30 13:47:48

Redis消息隊(duì)列機(jī)制

2024-05-10 09:36:36

架構(gòu)消息隊(duì)列

2019-07-19 07:56:13

消息隊(duì)列消息代理消息中間件

2010-04-21 12:39:48

Unix 消息隊(duì)列

2017-02-27 14:25:50

Java隊(duì)列Web

2009-12-07 09:23:05

2022-04-12 11:15:31

Redis消息隊(duì)列數(shù)據(jù)庫

2012-09-24 11:48:05

IBMdw

2009-11-09 11:15:06

WCF消息隊(duì)列
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)