<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          FreeRTOS多任務之間的通信——四種信號燈

          共 7178字,需瀏覽 15分鐘

           ·

          2022-05-27 16:55

          ????關注、星標公眾號,直達精彩內容

          來源:網(wǎng)絡素材

          整理:技術讓夢想更偉大?|?李肖遙


          四種信號燈的介紹

          1.計數(shù)信號燈:計數(shù)信號燈可以看成是長度大于 1 的隊列

          2.二值型信號燈:二進制信號燈可以認為長度是 1 的隊列,二值型信號燈是種特殊的計數(shù)信號燈,二值信號燈和互斥鎖十分相像,不過二值型信號燈適合用于同步。

          3.互斥信號燈:互斥鎖和二元信號量十分相像,不過兩者間有細微的差別,互斥鎖包含一個優(yōu)先級繼承機制,互斥鎖適合用于互斥

          4.遞歸互斥:這個我很少用,只對其API進行介紹

          計數(shù)信號燈

          API

          創(chuàng)建一個計數(shù)信號量:xSemaphoreCreateCounting() 函數(shù)

          xSemaphoreHandle xSemaphoreCreateCounting (
          unsigned portBASE_TYPE uxMaxCount,
          unsigned portBASE_TYPE uxInitialCount
          )
          uxMaxCount:可以達到的最大計數(shù)值。
          uxInitialCount:信號量創(chuàng)建時分配的初始值
          返回:已創(chuàng)建的信號量句柄,為xSemaphoreHandle 類型,如果信號量無法創(chuàng)建則為NULL

          刪除信號量void vSemaphoreDelete()

          void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
          xSemaphore:信號量句柄
          Demo

          一個初始化函數(shù),一個獲取函數(shù)


          static SemaphoreHandle_t xSemaphore_count_by = NULL;
          void count_semaphore_init(void *param)
          {
          /*信號量的計數(shù)最大值將為5,初始值為1*/
          xSemaphore_count_by=xSemaphoreCreateCounting(5,1);
          /*再來一個*/
          xSemaphoreGive( xSemaphore_count_by );
          if(xSemaphore_count_by == NULL)
          {
          /*創(chuàng)建互斥信號量失敗,可以寫自己的處理機制*/
          printf("[%s]can't create count_semaphore_init!\n",__func__);
          }
          vTaskDelete( NULL );
          }
          void count_semaphore_demo(void *param)
          {
          for(;;)
          {
          /*判斷這個互斥信號量是不是被創(chuàng)建*/
          if(xSemaphore_count_by != NULL)
          {
          /*如果信號量無效,則最多等待10個系統(tǒng)節(jié)拍周期。*/
          if( xSemaphoreTake( xSemaphore_count_by,(TickType_t)10) == pdTRUE )
          {
          /*獲取了信號量可以進行邏輯操作*/
          printf("[%s] Success!\n",__func__);
          /*釋放互斥信號量*/
          #if 0
          if(xSemaphoreGive( xSemaphore_count_by )==pdFALSE)
          {
          /*錯誤處理*/
          printf("[%s]xSemaphoreGive error!\n",__func__);
          }
          #endif
          }
          else
          {
          /*錯誤處理*/
          printf("[%s] error!\n",__func__);
          }
          }
          vTaskDelay(500);
          }
          vTaskDelete( NULL );
          }

          main函數(shù)(只寫了主要的函數(shù))

          if(xTaskCreate(count_semaphore_init, "count_semaphore_init", 512, NULL,2, NULL) != pdPASS){
          printf("[%s] count_semaphore_init error\n",__func__);
          }
          if(xTaskCreate(count_semaphore_demo, "mutex_semaphore_demo", 512, NULL,1, NULL) != pdPASS){
          printf("[%s] count_semaphore_demo error\n",__func__);
          }
          Log

          可以在這里看到獲取了兩次信號量

          [count_semaphore_demo] Success!
          [count_semaphore_demo] Success!
          [count_semaphore_demo] error!
          [count_semaphore_demo] error!

          二值型信號燈

          對API的介紹

          創(chuàng)建二值型信號量vSemaphoreCreateBinary()

          void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
          xSemaphore :創(chuàng)建的二值型信號量

          或者是下面的一種方式

          xSemaphoreHandle  xSemaphoreCreateBinary()
          返回值:創(chuàng)建的二值型信號量

          觸發(fā)二值型信號量:xSemaphoreGive() (我在這里用的是觸發(fā)這兩個字我覺得這個比較合適)

          xSemaphoreGive (
          xSemaphoreHandle xSemaphore )
          xSemaphore 即將釋放的信號量的句柄,在信號量創(chuàng)建是返回
          返回值:如果信號量成功釋放返回pdTRUE,如果發(fā)生錯誤則返回pdFALSE。

          獲取二值型信號量xSemaphoreTake()

          xSemaphoreTake (
          xSemaphoreHandle xSemaphore,
          portTickType xBlockTime
          )
          xSemaphore,:將被獲得的信號量句柄,此信號量必須已經(jīng)被創(chuàng)建
          xBlockTime :等待信號量可用的時鐘滴答次數(shù)
          返回值:如果成功獲取信號量則返回pdTRUE, 超時則返回pdFALSE
          Demo

          構建三個任務,一個初始化的任務,一個發(fā)送信號的任務,一個進行接收的任務

          static SemaphoreHandle_t xSemaphore_by = NULL;
          void semaphore_init(void *param)
          {
          /*初始化資源*/
          xSemaphore_by=xSemaphoreCreateBinary();
          if(xSemaphore_by == NULL)
          {
          /*創(chuàng)建二值信號量失敗,可以寫自己的處理機制 我這里做的打印*/
          printf("[%s]can't create xSemaphore!\n",__func__);
          }
          vTaskDelete( NULL );
          }
          void semaphore_send(void *param)
          {
          for(;;)
          {
          /*判斷是否創(chuàng)建了這個二值信號量*/
          if( xSemaphore_by != NULL )
          {
          /*做個延時這樣可以方便從log看出結果*/
          vTaskDelay(4000);
          if(xSemaphoreGive( xSemaphore_by )==pdFALSE)
          {
          /*錯誤處理*/
          }
          }
          vTaskDelay(500);
          }
          vTaskDelete( NULL );
          }

          void semaphore_achieve(void *param)
          {
          for(;;)
          {
          if( xSemaphore_by != NULL )
          {
          /*如果信號量無效,則最多等待10個系統(tǒng)節(jié)拍周期。*/
          if( xSemaphoreTake( xSemaphore_by,(TickType_t)10) == pdTRUE )
          {

          printf("[%s]achieve Success!\n",__func__);
          }
          else
          {
          /*錯誤處理*/
          printf("[%s]achieve error!\n",__func__);
          }
          }
          vTaskDelay(100);
          }
          vTaskDelete( NULL );
          }

          構建一個main函數(shù):創(chuàng)建三個任務(這個是偽代碼沒有對內核啟動等操作)

          if(xTaskCreate(semaphore_init, "semaphore_init", 1024, NULL,2, NULL) != pdPASS){
          printf("[%s] semaphore_init error\n",__func__);
          }
          if(xTaskCreate(semaphore_achieve, "semaphore_achieve", 1024,NULL,1, NULL) != pdPASS){
          printf("[%s] semaphore_achieve error\n",__func__);
          }
          if(xTaskCreate(semaphore_send, "semaphore_send", 1024,NULL,1, NULL) != pdPASS){
          printf("[%s] semaphore_send error\n",__func__);
          }
          log:(在這里只打印一部分log)
          [semaphore_achieve]achieve error!
          [semaphore_achieve]achieve error!
          [semaphore_achieve]achieve error!
          [semaphore_achieve]achieve error!
          [semaphore_achieve]achieve Success!

          互斥信號燈

          API

          xSemaphoreHandle xSemaphoreCreateMutex(void)

          返回:已創(chuàng)建的互斥鎖信號量句柄,需要為xSemaphoreHandle類型

          獲取和釋放信號量和上面的二值信號燈是一致的

          Demo

          構建兩個任務,一個初始化任務,一個獲取和釋放的任務

          static SemaphoreHandle_t xSemaphore_mutex_by = NULL;
          void mutex_semaphore_init(void *param)
          {
          xSemaphore_mutex_by=xSemaphoreCreateMutex();
          if(xSemaphore_mutex_by == NULL)
          {
          /*創(chuàng)建互斥信號量失敗,可以寫自己的處理機制*/
          printf("[%s]can't create xSemaphore!\n",__func__);
          }
          vTaskDelete( NULL );
          }
          void mutex_semaphore_demo(void *param)
          {
          for(;;)
          {
          /*判斷這個互斥信號量是不是被創(chuàng)建*/
          if(xSemaphore_mutex_by != NULL)
          {
          /*如果信號量無效,則最多等待10個系統(tǒng)節(jié)拍周期。*/
          if( xSemaphoreTake( xSemaphore_mutex_by,(TickType_t)10) == pdTRUE )
          {
          /*獲取了信號量可以進行邏輯操作*/
          printf("[%s] Success!\n",__func__);
          /*釋放互斥信號量*/
          if(xSemaphoreGive( xSemaphore_mutex_by )==pdFALSE)
          {
          /*錯誤處理*/
          printf("[%s]xSemaphoreGive error!\n",__func__);
          }
          }
          else
          {
          /*錯誤處理*/
          printf("[%s] error!\n",__func__);
          }
          }
          vTaskDelay(500);
          }
          vTaskDelete( NULL );
          }

          Mian函數(shù):

          int main()
          {
          if(xTaskCreate(mutex_semaphore_init, "mutex_semaphore_init", 512, NULL,2, NULL) !=pdPASS)
          {
          printf("[%s] mutex_semaphore_init error\n",__func__);
          }
          if(xTaskCreate(mutex_semaphore_demo, "mutex_semaphore_demo", 512, NULL,1, NULL) != pdPASS)
          {
          printf("[%s] mutex_semaphore_demo error\n",__func__);
          }
          vTaskStartScheduler();
          for(;;);
          }
          log:(在這里只打印一部分log)
          [mutex_semaphore_demo] Success!
          [mutex_semaphore_demo] Success!
          [mutex_semaphore_demo] Success!
          [mutex_semaphore_demo] Success!
          [mutex_semaphore_demo] Success!
          [mutex_semaphore_demo] Success!

          遞歸互斥

          API

          創(chuàng)建:

          xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
          返回:已創(chuàng)建的互斥鎖信號量為xSemaphoreHandle類型句柄

          接收的釋放和上面的三個不相同

          接收:
          xSemaphoreTakeRecursive( xSemaphoreHandle xMutex, portTickType xBlockTime )
          參數(shù):
          xMutex 將被獲得的互斥鎖句柄,此句柄由xSemaphoreCreateRecursiveMutex()返回
          xBlockTime 等待信號量可用的時鐘滴答次

          返回值:
          如果成功獲取信號量則返回pdTRUE,如果xBlockTime超時而信號量還未可用則返回pdFALSE
          釋放:
          xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
          參數(shù):
          xMutex:將被釋放的互斥鎖的句柄,由 xSemaphoreCreateRecursiveMutex()返回

          返回值:
          如果信號量成功釋放則為pdTRUE


          版權聲明:本文來源網(wǎng)絡,免費傳達知識,版權歸原作者所有。如涉及作品版權問題,請聯(lián)系我進行刪除。

          ???????????????? ?END ????????????????

          關注我的微信公眾號,回復“加群”按規(guī)則加入技術交流群。


          點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。

          瀏覽 30
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  豆花综合网| 中文字幕成人无码 | 免费看一级黄色片 | 蜜臀av无码精品一区二区三区 | 在线观看三级视频 |