色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于FreeRTOS的STM32F103系統—隊列

冬至子 ? 來源:月月望歸鳥 ? 作者:K.Fire ? 2023-11-10 11:37 ? 次閱讀

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

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

1

隊列特性

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

圖片

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

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

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
    +關注

    關注

    12

    文章

    484

    瀏覽量

    62773
  • STM32F103
    +關注

    關注

    33

    文章

    480

    瀏覽量

    64254
  • ISR
    ISR
    +關注

    關注

    0

    文章

    38

    瀏覽量

    14532
  • FIFO存儲
    +關注

    關注

    0

    文章

    103

    瀏覽量

    6073
  • 調度器
    +關注

    關注

    0

    文章

    98

    瀏覽量

    5350
收藏 人收藏

    評論

    相關推薦

    基于STM32F103的SVPWM算法實現

    基于STM32F103的SVPWM算法實現
    發表于 03-22 12:12 ?90次下載

    基于STM32F103的振動監測系統設計

    基于STM32F103的振動監測系統設計。
    發表于 11-09 17:49 ?43次下載

    STM32F103例程

    STM32F103例程。
    發表于 03-23 14:57 ?0次下載

    STM32F103封裝方式與功能配置

    本文介紹STM32F103封裝方式和STM32F103管腳功能的配置。
    發表于 08-03 17:44 ?2.2w次閱讀
    <b class='flag-5'>STM32F103</b>封裝方式與功能配置

    STM32F103的振動監測系統設計

    STM32F103的振動監測系統設計
    發表于 09-28 14:45 ?49次下載
    <b class='flag-5'>STM32F103</b>的振動監測<b class='flag-5'>系統</b>設計

    STM32F103的汽車遠程防盜系統設計

    STM32F103的汽車遠程防盜系統設計
    發表于 09-28 15:12 ?17次下載
    <b class='flag-5'>STM32F103</b>的汽車遠程防盜<b class='flag-5'>系統</b>設計

    STM32F103使用總結

    STM32F103使用總結
    發表于 10-24 10:22 ?152次下載

    stm32f103移植

    stm32f103移植
    發表于 10-27 09:03 ?43次下載
    <b class='flag-5'>stm32f103</b>移植

    STM32F103教程之STM32F103單片機的使用心得資料免費下載

    本文檔的主要內容詳細介紹的是STM32F103教程之STM32F103單片機的使用心得資料免費下載目前很火的設計STM32教程。
    發表于 09-26 08:00 ?254次下載

    STM32F103 CAN模板程序

    STM32F103 CAN模板程序
    發表于 11-09 11:08 ?84次下載
    <b class='flag-5'>STM32F103</b> CAN模板程序

    stm32f030和stm32f103功能差異

    stm32f030和stm32f103功能差異主要表現在哪?
    的頭像 發表于 07-22 09:35 ?2.2w次閱讀

    STM32F103 模擬IIC時序

    STM32F103 模擬IIC時序
    發表于 11-25 09:51 ?35次下載
    <b class='flag-5'>STM32F103</b>  模擬IIC時序

    GD32F103STM32F103的區別 2021.6.2

    GD32F103STM32F103區別介紹關鍵詞Key words:GD32F103STM32F103摘要Abstract:本文主要是GD32F
    發表于 12-08 11:06 ?83次下載
    GD32<b class='flag-5'>F103</b>與<b class='flag-5'>STM32F103</b>的區別 2021.6.2

    RT-Thread系統移植到STM32f103

    RT-Thread系統移植到STM32f103
    發表于 12-09 12:51 ?26次下載
    RT-Thread<b class='flag-5'>系統</b>移植到<b class='flag-5'>STM32f103</b>

    STM32F103開源分享

    電子發燒友網站提供《STM32F103開源分享.zip》資料免費下載
    發表于 08-22 10:42 ?108次下載
    <b class='flag-5'>STM32F103</b>開源分享
    主站蜘蛛池模板: CHINESE老阿姨免费视频 | 狠狠色色综合网站 | 欧美人与动牲交XXXXBBBB免费 | 久久婷婷五月综合色丁香花 | 69国产精品人妻无码免费 | 久久久擼擼擼麻豆 | 影音先锋男人资源813. | 国产 亚洲 日韩 欧美 在线观看 | BL低喘贯穿顶弄老师H | 亚洲黄色免费在线观看 | 水蜜桃亚洲一二三四在线 | 父亲在线日本综艺免费观看全集 | 99精品免费久久久久久久久日本 | 海角国精产品一区一区三区糖心 | 国产成人精品视频免费大全 | 欧洲兽交另类AVXXX | 兔费看少妇性L交大片免费 偷偷要色偷偷 | 亚洲人成网站7777视频 | 最近更新2019中文字幕免费 | 看美女大腿中间的部分 | 九九热视频免费 | 亚洲男女羞羞无遮挡久久丫 | 草莓视频在线看免费高清观看 | 亚洲欲色欲色XXXXX在线AV | 内射少妇三洞齐开 | 国产AV精品国语对白国产 | 在线亚洲色拍偷拍在线视频 | 户外露出野战hd | 沙发上小泬12P | 久久久无码AV精品亚洲A片软件 | 渔夫床满艳史bd高清在线直播 | 日本护士hd| 中文字幕AV在线一二三区 | 久久午夜宫电影网 | 欧美视频精品一区二区三区 | 好爽别插了无码视频 | 亚洲AV人无码综合在线观看蜜桃 | 爱做久久久久久 | 国产亚洲福利在线视频 | 国产精自产拍久久久久久蜜 | 一本色道久久综合亚洲精品蜜桃冫 |