娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

基于FreeRTOS的STM32F103系統—隊列

發布者:和諧的24號最新更新時間:2024-04-22 來源: elecfans關鍵字:FreeRTOS  隊列 手機看文章 掃描二維碼
隨時隨地手機看文章

FreeRTOS中,隊列是實現任務之間同步、互斥和通信的一種重要方法(其他的實現方法有:任務通知、事件組、信號量、互斥量)。


任何任務都可以向隊列里存放任何數據,任何任務也可以從隊列里讀取數據,實現不同任務之間的通信。


1


隊列特性


隊列的數據的操作采用先進先出的方法(FIFO,First In First Out):寫數據時放到尾部,讀數據時從頭部讀,邏輯順序如下圖所示。

8a6e6d5fa90f5ea19b4133588696e9ba_wKgZomVNpTyAXx3cAAGW2jtnoYI649.jpg

使用隊列傳輸數據時有兩種方法:


拷貝:把數據、把變量的值復制進隊列里

引用:把數據、把變量的地址復制進隊列里

FreeRTOS中的隊列一般都使用拷貝的方式傳輸數據,局部變量的值可以發送到隊列中,后續即使函數退出、局部變量被回收,也不會影響隊列中的數據,發送任務、接收任務解耦時,接收任務不需要知道這數據是誰的、也不需要發送任務來釋放數據。


如果數據實在太大,還是可以使用隊列傳輸它的地址。


2


隊列函數


1.創建


隊列的創建有兩種方法:動態分配內存、靜態分配內存。


一般都用動態分配內存的方法,使用函數:xQueueCreate()


QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );

參數解釋:


uxQueueLength :隊列長度

uxItemSize:每個數據的大小,以字節為單位

返回值:非0:成功,返回句柄,以后使用句柄來操作隊列;NULL:失敗,因為內存不足

2.刪除


刪除隊列的函數為 vQueueDelete() ,只能刪除使用動態方法創建的隊列,它會釋放內存。


void vQueueDelete( QueueHandle_t xQueue );

參數解釋:


xQueue:隊列句柄

3.寫隊列


可以把數據寫到隊列頭部,也可以寫到尾部,這些函數有兩個版本:在任務中使用、在 ISR 中使用。


在任務中使用:


BaseType_t xQueueSend( QueueHandle_t xQueue,const void *pvItemToQueue,TickType_t xTicksToWait );

在ISR中使用:


BaseType_t xQueueSendToBackFromISR( QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken );

參數解釋:


xQueue :隊列句柄,要寫哪個隊列

pvItemToQueue : 數據指針,這個數據的值會被復制進隊列

xTicksToWait :如果隊列滿則無法寫入新數據,可以讓任務進入阻塞狀態,xTicksToWait表示阻塞的最大時間(Tick Count)。如果被設為0,無法寫入數據時函數會立刻返回;如果被設為portMAX_DELAY,則會一直阻塞直到有空間可寫

返回值:pdPASS:數據成功寫入了隊列;errQUEUE_FULL:寫入失敗,因為隊列滿了。

4.讀隊列


使用 xQueueReceive() 函數讀隊列,讀到一個數據后,隊列中該數據會被移除。這個函數有兩個版 本:在任務中使用、在ISR 中使用。


BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait );

BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken );

參數解釋:


xQueue :隊列句柄,要寫哪個隊列

pvBuffffer: bufer 指針,隊列的數據會被復制到這個 buffer

xTicksToWait :如果隊列空則無法讀出數據,可以讓任務進入阻塞狀態,xTicksToWait表示阻塞的最大時間(Tick Count)。如果被設為0,無法讀出數據時函數會立刻返回;如果被設為portMAX_DELAY,則會一直阻塞直到有數據可寫

返回值:pdPASS:從隊列讀出數據入;errQUEUE_EMPTY:讀取失敗,因為隊列空了。

5.其他


復位:隊列剛被創建時,里面沒有數據;使用過程中可以調用 xQueueReset() 把隊列恢復為初始狀態。


/* 

pxQueue : 復位哪個隊列; 

 * 返回值: pdPASS(必定成功)

 */ 

BaseType_t xQueueReset( QueueHandle_t pxQueue);

查詢:可以查詢隊列中有多少個數據、有多少空余空間。


/** 返回隊列中可用數據的個數 */ 

UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ); 

/** 返回隊列中可用空間的個數 */ 

UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );

覆蓋:當隊列長度為 1 時,可以使用 xQueueOverwrite() 或 xQueueOverwriteFromISR() 來覆蓋數據。注意,隊列長度必須為1。當隊列滿時,這些函數會覆蓋里面的數據,這也以為著這些函數不會被阻塞。


/* 覆蓋隊列

 * xQueue: 寫哪個隊列

 * pvItemToQueue: 數據地址

 * 返回值: pdTRUE表示成功, pdFALSE表示失敗

 */ 

BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue ); 

BaseType_t xQueueOverwriteFromISR( QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );

偷看:如果想讓隊列中的數據供多方讀取,也就是說讀取時不要移除數據,要留給后來人。那么可以使用' 窺 視' ,也就是 xQueuePeek() 或 xQueuePeekFromISR() 。這些函數會從隊列中復制出數據,但是不移除數據。這也意味著,如果隊列中沒有數據,那么' 偷看 ' 時會導致阻塞;一旦隊列中有數據,以后每次 ' 偷看' 都會成功。


/* 偷看隊列

 * xQueue: 偷看哪個隊列

 * pvItemToQueue: 數據地址, 用來保存復制出來的數據

 * xTicksToWait: 沒有數據的話阻塞一會

 * 返回值: pdTRUE表示成功, pdFALSE表示失敗

 */ 

BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait );

BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void *pvBuffer, );

3


隊列實驗


代碼


/* vSenderTask被用來創建2個任務,用于寫隊列

 * vReceiverTask被用來創建1個任務,用于讀隊列

 */

static void vSenderTask( void *pvParameters );

static void vReceiverTask( void *pvParameters );


/*-----------------------------------------------------------*/


/* 隊列句柄, 創建隊列時會設置這個變量 */

QueueHandle_t xQueue;


int main( void )

{

  prvSetupHardware();


    /* 創建隊列: 長度為5,數據大小為4字節(存放一個整數) */

    xQueue = xQueueCreate( 5, sizeof( int32_t ) );


  if( xQueue != NULL )

  {

    /* 創建2個任務用于寫隊列, 傳入的參數分別是100、200

     * 任務函數會連續執行,向隊列發送數值100、200

     * 優先級為1

     */

    xTaskCreate( vSenderTask, 'Sender1', 1000, ( void * ) 100, 1, NULL );

    xTaskCreate( vSenderTask, 'Sender2', 1000, ( void * ) 200, 1, NULL );


    /* 創建1個任務用于讀隊列

     * 優先級為2, 高于上面的兩個任務

     * 這意味著隊列一有數據就會被讀走

     */

    xTaskCreate( vReceiverTask, 'Receiver', 1000, NULL, 2, NULL );


    /* 啟動調度器 */

    vTaskStartScheduler();

  }

  else

  {

    /* 無法創建隊列 */

  }


  /* 如果程序運行到了這里就表示出錯了, 一般是內存不足 */

  return 0;

}

/*-----------------------------------------------------------*/




/*-----------------------------------------------------------*/


static void vSenderTask( void *pvParameters )

{

  int32_t lValueToSend;

  BaseType_t xStatus;


  /* 我們會使用這個函數創建2個任務

   * 這些任務的pvParameters不一樣

    */

  lValueToSend = ( int32_t ) pvParameters;


  /* 無限循環 */

  for( ;; )

  {

    /* 寫隊列

     * xQueue: 寫哪個隊列

     * &lValueToSend: 寫什么數據? 傳入數據的地址, 會從這個地址把數據復制進隊列

     * 0: 不阻塞, 如果隊列滿的話, 寫入失敗, 立刻返回

     */

    xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 );


    if( xStatus != pdPASS )

    {

      printf( 'Could not send to the queue.rn' );

    }

  }

}

/*-----------------------------------------------------------*/


static void vReceiverTask( void *pvParameters )

{

  /* 讀取隊列時, 用這個變量來存放數據 */

  int32_t lReceivedValue;

  BaseType_t xStatus;

  const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );


  /* 無限循環 */

  for( ;; )

  {

    /* 讀隊列

     * xQueue: 讀哪個隊列

     * &lReceivedValue: 讀到的數據復制到這個地址

     * xTicksToWait: 如果隊列為空, 阻塞一會

     */

    xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );


    if( xStatus == pdPASS )

    {

      /* 讀到了數據 */

      printf( 'Received = %drn', lReceivedValue );

    }

    else

    {

      /* 沒讀到數據 */

      printf( 'Could not receive from the queue.rn' );

    }

  }

}

在這個程序中,有一個接收隊列數據的任務,兩個發送隊列數據的任務,接收隊列數據的任務優先級高,先執行,但是這時隊列為空,觸發該任務阻塞,這時低優先級的任務交替執行,向隊列中發送數據,接收任務發現隊列不為空后(解除觸發的事件),立刻被喚醒從隊列中讀取數據并打印出來,實驗結果和邏輯圖如下:

圖片

圖片


關鍵字:FreeRTOS  隊列 引用地址:基于FreeRTOS的STM32F103系統—隊列

上一篇:STM32H5 DA證書鏈實戰經驗
下一篇:STM32基礎知識:串口通信-DMA方式

推薦閱讀最新更新時間:2025-04-21 01:18

labview棧和隊列
同步控制技術----棧與隊列 (其中有很多圖片不是馬上就能看到的,查看方法是:鼠標右擊不可看圖片,選擇復制圖片地址,然后在瀏覽器中打開即可。因為本文是摘錄的,給各位朋友帶來不便,請多諒解!) 在計算機編程中棧是一個很重要的概念,尤其在匯編語言中,需要不斷進棧和出棧的操作.棧是限定在一個表的尾端進行插入(進堆棧)和刪除(出堆棧)的線性表.是后進先出結構(LIFO). 隊列的定義和棧的定義是類似的,區別是數據是先進先出(FIFO) labview還有一個概念緩沖區BUFFER,典型的比如CHART,它默認保存數據長度是1024.BUFFER的概念和隊列是非常相似的,
[測試測量]
labview棧和<font color='red'>隊列</font>
STM32中斷,及FreeRTOS中斷優先級配置
很多朋友對中斷的一些知識還是不了解,今天就寫點關于Cortex-M3處理器中斷相關,以及FreeRTOS中斷優先級配置的內容。 1寫在前面 寫本文之前,先寫點相關的擴展內容。 STM32屬于ARM中Cortex-M系列處理器,比如:STM32F1數據Cortex-M3,STM32F7數據Cortex-M7。 可以參看我之前分享文章: 從Cortex-M到Cortex-A認識ARM處理器 ,了解一下關于ARM處理器的種類。 本文主要結合Cortex-M3下面STM32F1系列處理器為例來講述中斷控制相關內容。而Cortex-M其它系列,或者說STM32其它系列關于中斷的內容類似。 Cortex
[單片機]
STM32中斷,及<font color='red'>FreeRTOS</font>中斷優先級配置
關于FreeRTOS移植到STM32F103上的步驟以及注意事項
因為最近比較有時間,而且發現自己對于STM上可以跑的操作系統相對陌生。所以選擇幾個操作系統進行移植和玩幾個DEMO理解一下。雖然理解的不是很深入,但是如果項目需要的話,只是移植,進行多任務的操作。應付一下還是綽綽有余的。之前移植了uCosII.后續有需要會總結一下。這里先對FreeRTOS相關的問題進行總結。因為個人能力有限。有什么不對的地方請大家批評,寫這個主要是為了記錄一下自己的移植過程。 1、第一步肯定是先到官網去下載關于FreeRTOS的源碼 下面的網址是官方最新源碼的下載地址: https://sourceforge.net/projects/freertos/files/latest/download?source=
[單片機]
關于<font color='red'>FreeRTOS</font>移植到<font color='red'>STM32F103</font>上的步驟以及注意事項
基于LPC2364的串口轉網口專用協議卡的研制
O 引言 串口轉網口模塊是一個可以讓串口設備立即具備聯網能力的設備聯網服務器。它具有1個可選擇界面串口和1個TCP/IP網絡接口,可讓串口設備立即連接網絡。從而實現工業設備完全自動化聯網管理。該模塊體積小,非常容易整合在系統或設備內,而且可以適應復雜的網絡。為此,本文給出了采用LPC2364、DP83848C、SP3485和H2019等芯片構成一個串口轉網口模塊的軟硬件實現方法。 1 uIP介紹 uIP是由瑞典計算機科學學院(網絡嵌入式系統小組)的Adam Dunkels開發的一種軟件協議棧。該協議棧的源代碼由C語言編寫,并完全公開。uIP協議棧去掉了完整的TCP/IP中不常用的功能,簡化了通訊流程,但保留了網絡通信必須
[單片機]
基于LPC2364的串口轉網口專用協議卡的研制
小廣播
熱門活動
換一批
更多
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

更多每日新聞

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 鹿邑县| 霞浦县| 民县| 剑河县| 金昌市| 安宁市| 衡南县| 全州县| 海兴县| 揭东县| 大余县| 永昌县| 新干县| 泗水县| 曲松县| 平遥县| 连平县| 巴彦淖尔市| 井研县| 城固县| 怀安县| 婺源县| 寻乌县| 武宣县| 同仁县| 行唐县| 瓦房店市| 来凤县| 类乌齐县| 尉犁县| 微博| 玉田县| 周至县| 花垣县| 靖西县| 日土县| 宁南县| 海南省| 米泉市| 潮州市| 儋州市|