FreeRTOS系列第24篇---FreeRTOS信號量分析

李肖遙 2021-07-01 08:38


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

ID:技術讓夢想更偉大

整理:李肖遙


FreeRTOS的信號量包括二進制信號量、計數信號量、互斥信號量(以后簡稱互斥量)和遞歸互斥信號量(以后簡稱遞歸互斥量)。

關于它們的區別可以參考《 FreeRTOS系列第19篇---FreeRTOS信號量》一文。

信號量API函數實際上都是宏,它使用現有的隊列機制。這些宏定義在semphr.h文件中。如果使用信號量或者互斥量,需要包含semphr.h頭文件。

二進制信號量、計數信號量和互斥量信號量的創建API函數是獨立的,但是獲取和釋放API函數都是相同的;

遞歸互斥信號量的創建、獲取和釋放API函數都是獨立的。

1.信號量創建

在《FreeRTOS高級篇5---FreeRTOS隊列分析》中,我們分析了隊列的實現過程,包括隊列創建、入隊和出隊操作。

在那篇文章中我們說過,創建隊列API函數實際是調用通用隊列創建函數xQueueGenericCreate()來實現的。

其實,不但創建隊列實際調用通用隊列創建函數,二進制信號量、計數信號量、互斥量和遞歸互斥量也都直接或間接使用這個函數,如表1-1所示。

表1-1中紅色字體表示是間接調用xQueueGenericCreate()函數。

表1-1:隊列、信號量和互斥量創建宏與直接(間接)執行函數

1.1.創建二進制信號量

二進制信號量創建實際上是直接使用通用隊列創建函數xQueueGenericCreate()。創建二進制信號量API接口實際上是一個宏,定義如下:

#define xSemaphoreCreateBinary()         \
   xQueueGenericCreate(              \
            ( UBaseType_t ) 1,       \
            semSEMAPHORE_QUEUE_ITEM_LENGTH,  \
            NULL,              \
            NULL,              \
            queueQUEUE_TYPE_BINARY_SEMAPHORE\
            )

通過這個宏定義我們知道創建二進制信號量實際上是創建了一個隊列,隊列項有1個,但是隊列項的大小為0(宏semSEMAPHORE_QUEUE_ITEM_LENGTH定義為0)。

有了隊列創建的知識,我們可以很容易的畫出初始化后的二進制信號量內存,如圖1-1所示。

圖1-1:初始化后的二進制信號量對象內存

或許不止一人像我一樣奇怪,創建一個沒有隊列項存儲空間的隊列,「信號量用什么表示?」

其實二進制信號量的釋放和獲取都是通過操作隊列結構體成員uxMessageWaiting來實現的(圖1-1紅色部分,uxMessageWaiting表示隊列中當前隊列項的個數)。

經過初始化后,變量uxMessageWaiting為0,這說明隊列為空,也就是信號量處于無效狀態。

在使用API函數xSemaphoreTake()獲取信號之前,需要先釋放一個信號量。后面講到二進制信號量釋放和獲取時還會詳細介紹。

1.2.創建計數信號量

創建計數信號量間接使用通用隊列創建函數xQueueGenericCreate()。創建計數信號量API接口同樣是個宏定義:

#define xSemaphoreCreateCounting(uxMaxCount, uxInitialCount )             \
       xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ), (NULL ) )

創建計數信號量API接口有兩個參數,含義如下:

  • 「uxMaxCount」:最大計數值,當信號到達這個值后,就不再增長了。

  • 「uxInitialCount」:創建信號量時的初始值。

我們來看一下函數xQueueCreateCountingSemaphore()如何實現的:

QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_tuxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue )
{
QueueHandle_t xHandle;
 
  configASSERT( uxMaxCount != 0 );
  configASSERT( uxInitialCount <= uxMaxCount );

  /*調用通用隊列創建函數*/
  xHandle =xQueueGenericCreate(
        uxMaxCount,
        queueSEMAPHORE_QUEUE_ITEM_LENGTH,
        NULL,
        pxStaticQueue,
        queueQUEUE_TYPE_COUNTING_SEMAPHORE );

  if( xHandle != NULL )
  {
      ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount;
  }
  configASSERT( xHandle );
  return xHandle;
}

從代碼可以看出,創建計數信號量仍然調用通用隊列創建函數xQueueGenericCreate()來創建一個隊列,隊列項的數目由參數uxMaxCount指定,每個隊列項的大小由宏queueSEMAPHORE_QUEUE_ITEM_LENGTH指出,我們找到這個宏定義發現,這個宏被定義為0,也就是說創建的隊列只有隊列數據結構存儲空間而沒有隊列項存儲空間。

如果隊列創建成功,則將隊列結構體成員uxMessageWaiting設置為初始計數信號量值。初始化后的計數信號量內存如圖1-2所示。

圖1-2:初始化后的計數信號量對象內存

1.3創建互斥量

創建互斥量間接使用通用隊列創建函數xQueueGenericCreate()。創建互斥量API接口同樣是個宏,定義如下:

#define xSemaphoreCreateMutex()             \
          xQueueCreateMutex( queueQUEUE_TYPE_MUTEX, NULL )

其中,宏queueQUEUE_TYPE_MUTEX用于通用隊列創建函數,表示創建隊列的類型是互斥量,在文章《FreeRTOS高級篇5---FreeRTOS隊列分析》關于通用隊列創建函數參數說明中提到了這個宏。

我們來看一下函數xQueueCreateMutex()是如何實現的:

#if ( configUSE_MUTEXES == 1 )
    QueueHandle_t xQueueCreateMutex( const uint8_tucQueueType, StaticQueue_t *pxStaticQueue )
    {
    Queue_t *pxNewQueue;
    const UBaseType_tuxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0;
 
        /* 防止編譯器產生警告信息 */
        ( void ) ucQueueType;
       
        /*調用通用隊列創建函數*/
        pxNewQueue = ( Queue_t * )xQueueGenericCreate( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType );
 
        /* 成功分配新的隊列結構體? */
        if( pxNewQueue != NULL )
        {
            /*xQueueGenericCreate()函數會按照通用隊列的方式設置所有隊列結構體成員,但是我們是要創建互斥量.因此需要對一些結構體成員重新賦值. */
            pxNewQueue->pxMutexHolder = NULL;
          
            pxNewQueue->uxQueueType =queueQUEUE_IS_MUTEX;  //NULL
 
            /* 用于遞歸互斥量創建 */
            pxNewQueue->u.uxRecursiveCallCount = 0;
 
            /* 使用一個預期狀態啟動信號量 */
            ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK);
        }
 
        return pxNewQueue;
    }
#endif /* configUSE_MUTEXES */

這個函數是帶條件編譯的,只有將宏configUSE_MUTEXES定義為1才會編譯這個函數。

函數首先調用通用隊列創建函數xQueueGenericCreate()來創建一個隊列,隊列項數目為1,隊列項大小為0,說明創建的隊列只有隊列數據結構存儲空間而沒有隊列項存儲空間。

如果隊列創建成功,通用隊列創建函數還會按照通用隊列的方式 初始化所有隊列結構體成員。

但是這里要創建的是互斥量,所以有一些結構體成員必須重新賦值。

在這段代碼中,可能你會疑惑,隊列結構體成員中,并沒有pxMutexHolderuxQueueType

其實這兩個標識符只是宏定義,是專門為互斥量而定義的,如下所示:

#define pxMutexHolder              pcTail
#define uxQueueType                pcHead
#define queueQUEUE_IS_MUTEX        NULL

當隊列結構體用于互斥量時,成員pcHead和pcTail指針就不再需要,并且將pcHead指針設置為NULL,表示pcTail指針實際指向互斥量持有者任務TCB(如果有的話)。

最后調用函數xQueueGenericSend()釋放一個互斥量,相當于互斥量創建后是有效的,可以直接使用獲取信號量API函數來獲取這個互斥量。

如果某資源同時只準一個任務訪問,可以用互斥量保護這個資源。

這個資源一定是存在的,所以創建互斥量時會先釋放一個互斥量,表示這個資源可以使用。

任務想訪問資源時,先獲取互斥量,等使用完資源后,再釋放它。

也就是說互斥量一旦創建好后,要先獲取,后釋放,要在同一個任務中獲取和釋放。

這也是互斥量和二進制信號量的一個重要區別,二進制信號量可以在隨便一個任務中獲取或釋放,然后也可以在任意一個任務中釋放或獲取。

「互斥量不同于二進制信號量的還有」:互斥量具有優先級繼承機制,二進制信號量沒有,互斥量不可以用于中斷服務程序,二進制信號量可以。

初始化后的互斥量內存如圖1-3所示。

圖1-3:初始化后的互斥量對象內存

1.4創建遞歸互斥量

創建遞歸互斥量間接使用通用隊列創建函數xQueueGenericCreate()。創建遞歸互斥量API接口同樣是個宏,定義如下:

#definexSemaphoreCreateRecursiveMutex()                 \
          xQueueCreateMutex(queueQUEUE_TYPE_RECURSIVE_MUTEX, NULL )

其中,宏queueQUEUE_TYPE_RECURSIVE_MUTEX用于通用隊列創建函數,表示創建隊列的類型是遞歸互斥量,在文章《FreeRTOS高級篇5---FreeRTOS隊列分析》關于通用隊列創建函數參數說明中提到了這個宏。

創建互斥量和創建遞歸互斥量是調用的同一個函數xQueueCreateMutex();

至于參數queueQUEUE_TYPE_RECURSIVE_MUTEX,我們在FreeRTOS一文中已經知道,它只是用于可視化調試;

因此創建互斥量和創建遞歸互斥量可以看作是一樣的,初始化后的遞歸互斥量對象內存也和互斥量一樣,如圖1-3所示。

2.釋放信號量

無論二進制信號量、計數信號量還是互斥量,它們都使用相同的獲取和釋放API函數。釋放信號量用于使信號量有效,分為不帶中斷保護和帶中斷保護兩個版本。

2.1 xSemaphoreGive()

用于釋放一個信號量,不帶中斷保護。被釋放的信號量可以是二進制信號量、計數信號量和互斥量。

注意遞歸互斥量并不能使用這個API函數釋放。其實信號量釋放是一個宏,真正調用的函數是xQueueGenericSend(),宏定義如下:

#definexSemaphoreGive( xSemaphore )                    \
              xQueueGenericSend(                       \
                     ( QueueHandle_t ) ( xSemaphore ), \
                     NULL,                \
                     semGIVE_BLOCK_TIME,  \
                     queueSEND_TO_BACK )

可以看出釋放信號量實際上是一次入隊操作,并且阻塞時間為0(由宏semGIVE_BLOCK_TIME定義)。

對于二進制信號量和計數信號量,根據上一章的內容可以總結出,釋放一個信號量的過程實際上可以簡化為兩種情況:

「第一」,如果隊列未滿,隊列結構體成員uxMessageWaiting加1,判斷是否有阻塞的任務,有的話解除阻塞,然后返回成功信息(pdPASS);

「第二」,如果隊列滿,返回錯誤代碼(err_QUEUE_FULL),表示隊列滿。

對于互斥量要復雜些,因為互斥量具有優先級繼承機制。

「優先級繼承是個什么過程呢?」

我們舉個例子。某個資源X同時只能有一個任務訪問,現在有任務A和任務C都要訪問這個資源,任務A的優先級為1,任務C的優先級為10,所以任務C的優先級大于任務A的優先級。

我們用互斥量保護資源X,并且當前任務A正在訪問資源X。

在任務A訪問資源X的過程中,來了一個中斷,中斷事件使得任務C執行。

任務C執行的過程中,也想訪問資源X,但是因為資源X還被任務A獨占著,所以任務C無法獲取互斥量,會進入阻塞狀態。

此時,低優先級任務A會繼承高優先級任務C的優先級,任務A的優先級臨時的被提升,優先級變成10。這個機制能夠將已經發生的優先級反轉影響降低到最小。

「那么什么是優先級反轉呢?」

還是看上面的例子,任務C的優先級高于任務A,但是任務C因為沒有獲得互斥量而進入阻塞,只能等待低優先級的任務A釋放互斥量后才能運行,這種情況就是優先級反轉。

「那為什么優先級繼承可以降低優先級反轉的影響呢?」

還是看上面的例子,不過我們再增加一個優先級為5的任務B,這三個任務都處于就緒狀態。

如果沒有優先級繼承機制,三個任務的優先級順序為任務C>任務B>任務A。

當任務C因為得不到互斥量而阻塞后,任務B會獲取CPU權限,等到任務B主動或被動讓出CPU后,任務A才會執行,任務A釋放互斥量后,任務C才能得到運行。

再看一下有優先級繼承的情況,當任務C因為得不到互斥量而阻塞后,任務A繼承任務C的優先級,現在三個任務的優先級順序為任務C=任務A>任務B。

當任務C因為得不到互斥量而阻塞后,任務A會獲得CPU權限,等到任務A釋放互斥量后,任務C就會得到運行。看,任務C等待的時間變短了。

有了上面的基礎理論,我們就很好理解為什么釋放互斥量會比較復雜了。

「還是可以簡化為兩種情況:」

「第一」,如果隊列未滿,除了隊列結構體成員uxMessageWaiting加1外,還要判斷獲取互斥量的任務是否有優先級繼承,如果有的話,還要將任務的優先級恢復到原始值。當然,恢復到原來值也是有條件的,就是該任務必須在沒有使用其它互斥量的情況下,才能將繼承的優先級恢復到原始值。然后判斷是否有阻塞的任務,有的話解除阻塞,最后返回成功信息(pdPASS);

「第二」,如果如果隊列滿,返回錯誤代碼(err_QUEUE_FULL),表示隊列滿。

2.2xSemaphoreGiveFromISR()

用于釋放一個信號量,帶中斷保護。被釋放的信號量可以是二進制信號量和計數信號量。

和普通版本的釋放信號量API函數不同,它不能釋放互斥量,這是因為互斥量不可以在中斷中使用!

互斥量的優先級繼承機制只能在任務中起作用,在中斷中毫無意義。帶中斷保護的信號量釋放其實也是一個宏,真正調用的函數是xQueueGiveFromISR (),宏定義如下:

#definexSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )     \
            xQueueGiveFromISR(                     \
                ( QueueHandle_t ) ( xSemaphore),  \
                ( pxHigherPriorityTaskWoken ) )

我們看真正被調用的函數源碼(經過整理后的):

BaseType_t xQueueGiveFromISR(
            QueueHandle_t xQueue,
            BaseType_t * constpxHigherPriorityTaskWoken )
{
BaseType_t xReturn;
UBaseType_t uxSavedInterruptStatus;
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
uxSavedInterruptStatus =portSET_INTERRUPT_MASK_FROM_ISR();
  {
    /*當隊列用于實現信號量時,永遠不會有數據出入隊列,但是任然要檢查隊列是否為空 */
    if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
    {
      /* 一個任務可以獲取多個互斥量,但是只能有一個繼承優先級,如果任務是互斥量的持有者,則互斥量不允許在中斷服務程序中釋放.因此這里不需要判斷是否要恢復任務的原始優先級值,只是簡單更新隊列項計數器. */
      ++( pxQueue->uxMessagesWaiting );

      /* 如果列表上鎖,不能改變隊列的事件列表. */
      if( pxQueue->xTxLock == queueUNLOCKED )
      {
        if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive) ) == pdFALSE )
        {
          if(xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive) ) != pdFALSE )
          {
            /* 解除阻塞的任務有更高優先級,因此記錄上下文切換請求*/
            if(pxHigherPriorityTaskWoken != NULL )
            {
              *pxHigherPriorityTaskWoken= pdTRUE;
            }
          }
        }
      }
      else
      {
        /* Increment thelock count so the task that unlocks the queue
        knows that data wasposted while it was locked. */
        ++( pxQueue->xTxLock );
      }

      xReturn = pdPASS;
    }
    else
    {
      xReturn = errQUEUE_FULL;
    }
  }
  portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus );

  return xReturn;
}

因為不涉及互斥量,不涉及阻塞,函數xQueueGiveFromISR()異常簡單,如果隊列滿,直接返回錯誤代碼(err_QUEUE_FULL);

如果隊列未滿,則將隊列結構體成員uxMessageWaiting加1,然后視隊列是否上鎖而決定是否解除任務阻塞(如果有得話)。

如果你覺得難以理解,則需要先看看《FreeRTOS高級篇5---FreeRTOS隊列分析》。

3.獲取信號量

無論二進制信號量、計數信號量還是互斥量,它們都使用相同的獲取和釋放API函數。

釋獲取信號量會消耗信號量,如果獲取信號量失敗,任務可能會阻塞,阻塞時間由函數參數xBlockTime指定,如果為0,則直接返回,不阻塞。

獲取信號量分為不帶中斷保護和帶中斷保護兩個版本。

3.1 xSemaphoreTake

用于獲取信號量,不帶中斷保護。獲取的信號量可以是二進制信號量、計數信號量和互斥量。

注意遞歸互斥量并不能使用這個API函數獲取。其實獲取信號量是一個宏,真正調用的函數是xQueueGenericReceive (),宏定義如下:

#definexSemaphoreTake( xSemaphore, xBlockTime )        \
              xQueueGenericReceive(                    \
             ( QueueHandle_t ) ( xSemaphore ),         \
              NULL,                                    \
             ( xBlockTime ),                           \
              pdFALSE )

通過上面的宏定義可以看出,獲取信號量實際上是執行出隊操作。

「對于二進制信號量和計數信號量,可以簡化為三種情況:」

「第一」,如果隊列不為空,隊列結構體成員uxMessageWaiting減1,判斷是否有因入隊而阻塞的任務,有的話解除阻塞,然后返回成功信息(pdPASS);

「第二」,如果隊列為空并且阻塞時間為0,則直接返回錯誤碼(errQUEUE_EMPTY),表示隊列為空;

「第三」,如果隊列為空并且阻塞時間不為0,則任務會因為等待信號量而進入阻塞狀態,任務會被掛接到延時列表中。

「對于互斥量,也可以簡化為三種情況」,但是過程要復雜一些:

「第一」,如果隊列不為空,隊列結構體成員uxMessageWaiting減1、將當前任務TCB結構體成員uxMutexesHeld加1,表示任務獲取互斥量的個數、將隊列結構體成員指針pxMutexHolder指向任務TCB、判斷是否有因入隊而阻塞的任務,有的話解除阻塞,然后返回成功信息(pdPASS);

「第二」,如果隊列為空并且阻塞時間為0,則直接返回錯誤碼(errQUEUE_EMPTY),表示隊列為空;

「第三」,如果隊列為空并且阻塞時間不為0,則任務會因為等待信號量而進入阻塞狀態,在將任務掛接到延時列表之前,會判斷當前任務和擁有互斥量的任務優先級哪個高,如果當前任務優先級高,則擁有互斥量的任務繼承當前任務優先級。

3.2xSemaphoreTakeFromISR()

用于獲取信號量,帶中斷保護。獲取的信號量可以是二進制信號量和計數信號量。

和普通版本的獲取信號量API函數不同,它不能獲取互斥量,這是因為互斥量不可以在中斷中使用!

互斥量的優先級繼承機制只能在任務中起作用,在中斷中毫無意義。

帶中斷保護的獲取信號量其實也是一個宏,真正調用的函數是xQueueReceiveFromISR (),宏定義如下:

#definexSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )   \
              xQueueReceiveFromISR(              \
             ( QueueHandle_t ) ( xSemaphore ),   \
              NULL,                              \
             ( pxHigherPriorityTaskWoken ) )

同樣因為不涉及互斥量,不涉及阻塞,函數xQueueReceiveFromISR ()同樣異常簡單:如果隊列為空,直接返回錯誤代碼(pdFAIL);

如果隊列非空,則將隊列結構體成員uxMessageWaiting減1,然后視隊列是否上鎖而決定是否解除任務阻塞(如果有得話)。

4.釋放遞歸互斥量

函數xSemaphoreGiveRecursive()用于釋放一個遞歸互斥量。

已經獲取遞歸互斥量的任務可以重復獲取該遞歸互斥量。

使用xSemaphoreTakeRecursive() 函數成功獲取幾次遞歸互斥量,就要使用xSemaphoreGiveRecursive()函數返還幾次,在此之前遞歸互斥量都處于無效狀態。

比如,某個任務成功獲取5次遞歸互斥量,那么在它沒有返還5次該遞歸互斥量之前,這個互斥量對別的任務無效。

像其它信號量一樣,xSemaphoreGiveRecursive()也是一個宏定義,它最終使用現有的隊列機制,實際執行的函數是xQueueGiveMutexRecursive(),這個宏定義如下所示:

#definexSemaphoreGiveRecursive( xMutex )            \
                xQueueGiveMutexRecursive( (xMutex ) )  

我們重點來看函數xQueueGiveMutexRecursive()的實現過程。經過整理后(去除跟蹤調試語句)的源碼如下所示:

#if ( configUSE_RECURSIVE_MUTEXES == 1 )
    BaseType_txQueueGiveMutexRecursive( QueueHandle_t xMutex )
    {
    BaseType_t xReturn;
    Queue_t * const pxMutex = ( Queue_t * ) xMutex;

   /* 互斥量和遞歸互斥量要在同一個任務中獲取和釋放,當獲取互斥量或遞歸互斥量時,隊列結構體成員指針pxMutexHolder指向獲取互斥量或遞歸互斥量的任務TCB,所以在釋放遞歸互斥量時需要檢查這個指針指向的TCB是否是和當前任務TCB相同,如果不相同是不能釋放這個遞歸互斥量的! 注:釋放互斥量時,這個檢查不是必須的,FreeRTOS的作者將這個檢查放在了斷言中(configASSERT( pxTCB == pxCurrentTCB);).*/
        if( pxMutex->pxMutexHolder == ( void * )xTaskGetCurrentTaskHandle() )
        {
            /* 每當任務獲取遞歸互斥量時,隊列結構體成員u.uxRecursiveCallCount會加1,互斥量不會使用這個變量,它用來保存遞歸次數.所以,在釋放遞歸互斥量的時候要將它減1*/
            ( pxMutex->u.uxRecursiveCallCount)--;
 
            /* 遞歸計數器為0? */
            if( pxMutex->u.uxRecursiveCallCount == ( UBaseType_t ) 0 )
            {
                /* 調用入隊函數釋放一個互斥量,注意阻塞時間(由宏queueMUTEX_GIVE_BLOCK_TIME定義)為0 */
                ( void ) xQueueGenericSend( pxMutex, NULL,queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
            }
 
            xReturn = pdPASS;
        }
        else
        {
            /* 如果不是本任務擁有這個互斥量,則直接返回錯誤碼 */
            xReturn = pdFAIL;
        }
 
        return xReturn;
    }
#endif /* configUSE_RECURSIVE_MUTEXES */

這個函數是帶條件編譯的,只有將宏configUSE_RECURSIVE_MUTEXES定義為1才會編譯這個函數。

互斥量和遞歸互斥量的最大區別在于一個遞歸互斥量可以被已經獲取這個遞歸互斥量的任務重復獲取,這個遞歸調用功能是通過隊列結構體成員u.uxRecursiveCallCount實現的。

這個變量用于存儲遞歸調用的次數,每次獲取遞歸互斥量后,這個變量加1,在釋放遞歸互斥量后,這個變量減1。

只有這個變量減到0,即釋放和獲取的次數相等時,互斥量才能再次有效,使用入隊函數釋放一個遞歸互斥量。

5.獲取遞歸互斥量

函數xSemaphoreTakeRecursive()用于獲取一個遞歸互斥量。像其它信號量一樣,xSemaphoreTakeRecursive()也是一個宏定義,它最終使用現有的隊列機制,實際執行的函數是xQueueTakeMutexRecursive(),這個宏定義如下所示:

#definexSemaphoreTakeRecursive( xMutex, xBlockTime )       \
               xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )

獲取遞歸互斥量具有阻塞超時參數,如果互斥量正被別的任務使用,可以阻塞設定的時間。

我們重點來看函數xQueueTakeMutexRecursive()的實現過程。經過整理后(去除跟蹤調試語句)的源碼如下所示:

#if ( configUSE_RECURSIVE_MUTEXES == 1 )
    BaseType_txQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_txTicksToWait )
    {
    BaseType_t xReturn;
    Queue_t * const pxMutex = ( Queue_t * ) xMutex;
    /*互斥量和遞歸互斥量要在同一個任務中獲取和釋放,遞歸互斥量可以在一個任務中多次獲取,當第一次獲取遞歸互斥量時,隊列結構體成員指針pxMutexHolder指向獲取遞歸互斥量的任務TCB,在此獲取這個遞歸互斥量時,如果這個指針指向的TCB和當前任務TCB相同,只需要將遞歸次數計數器u.uxRecursiveCallCount加1即可,不需要再操作隊列.*/
        if( pxMutex->pxMutexHolder == ( void * )xTaskGetCurrentTaskHandle() )
        {
            ( pxMutex->u.uxRecursiveCallCount)++;
            xReturn = pdPASS;
        }
        else
        {
            /*調用出隊函數*/
            xReturn =xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE );
 
            /* 成功獲取遞歸互斥量后,要將遞歸次數計數器加1*/
            if( xReturn != pdFAIL )
            {
                ( pxMutex->u.uxRecursiveCallCount)++;
            }
        }
 
        return xReturn;
    }
#endif /* configUSE_RECURSIVE_MUTEXES */

這個函數是帶條件編譯的,只有將宏configUSE_RECURSIVE_MUTEXES定義為1才會編譯這個函數。

程序邏輯比較簡單,如果是第一次獲取這個遞歸互斥量,直接使用出隊函數,成功后將遞歸次數計數器加1;

如果是第二次或者更多次獲取這個遞歸互斥量,則只需要將遞歸次數計數器加1即可。

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

推薦閱讀:


嵌入式編程專輯
Linux 學習專輯
C/C++編程專輯
Qt進階學習專輯

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


點擊“閱讀原文”查看更多分享。

李肖遙 公眾號“技術讓夢想更偉大”,作者:李肖遙,專注嵌入式,只推薦適合你的博文,干貨,技術心得,與君共勉。
評論
  • 我在唯創知音做門鎖語音方案這幾年,常被廠商問到一個看似簡單的問題,門鎖里的語音到底要做什么。門鎖語音在門鎖里早就不是加個喇叭那么回事。它要管門鈴、提示音、貓眼對講、藍牙配網播報、離線喊一聲開門,還有大屏上的菜單動效。這些功能分散在前板、后板、貓眼和 APP 四個部位,芯片怎么選,各部位完全不一樣。最基礎的一塊是門鈴和固定提示音。很多走量機型到現在還是一顆小容量語音芯片扛著,像 WTN 系列里的 WTN6006、WTN6020,Flash 從 低時長到高時長都有不同的芯片,協議相同可以無縫切換。它
    唯創知音語音芯片 2026-08-12 17:34 195瀏覽
  • 100 字導語廠區停機檢修、設備長期靜置存放,防爆航插易受潮、積塵、膠圈老化、觸點氧化。本文針對停機復工場景,制定 3 針 3 孔、5PIN、8 芯圓形防爆連接器全套檢測保養流程,明確絕緣、導通、密封、屏蔽復工核驗標準,避免復工跳閘、信號異常。關鍵詞:圓形防爆連接器,復工檢測,防爆航空插頭,防爆法蘭插座,防爆接插件,IP67, 靜置保養,5PIN,8 芯1 產品概述設備長期停機靜置,防爆連接器腔體密閉不通風,極易積聚潮氣、凝結水汽;密封件長期靜態受壓出現永久形變;鍍金觸點鈍化氧化。直接通電復工極
    kyfbest科迎法電氣 2026-08-12 13:32 290瀏覽
  • 導語:根據CINNO ? ePaper Insight數據,2026年上半年,全球電子紙終端總銷量約2.9億臺(枚),同比增長25%。其中,電子紙價簽終端銷量2.8億枚,同比增長27%,繼續成為產業增長的核心動力;電子紙平板銷量610萬臺,同比下降超過16%,較2025年上半年730萬臺有所回落。細分市場看,閱讀器銷量480萬臺,辦公本銷量130萬臺。整體來看,電子紙應用結構進一步向智慧零售集中,價簽高景氣與平板階段性調整形成明顯分化。全球終端銷量同比增長25%,價簽貢獻主要增量CINNO ?
    CINNOResearch 2026-08-12 11:05 235瀏覽
  • 100 字導語工業防爆鎧裝線纜硬度高、結構特殊,普通圓形防爆連接器密封結構難以適配,極易出現夾不緊、滲水、線纜滑脫問題。本文針對鎧裝線纜特性,匹配 4 芯、5PIN、8 芯防爆法蘭插座安裝工藝,明確鎧裝固定、密封壓緊、應力釋放全套施工標準。關鍵詞:圓形防爆連接器,鎧裝線纜,防爆法蘭插座,防爆防水連接器,IP67,8 芯,防爆電源接頭,防爆接插件1 產品概述鎧裝線纜自帶金屬保護層,硬度大、不可隨意彎折,常規塑料密封套無法有效抱緊。很多現場直接使用普通格蘭密封鎧裝線,導致尾部密封失效、鎧裝層懸空松動
    kyfbest科迎法電氣 2026-08-12 12:48 269瀏覽
  • 在國內大量通用制造產線與工業場站里,智能化升級正普遍面臨著的現實困境:小到產線外觀質檢、設備狀態監測終端,大到站房智能網關、工業人機交互設備,企業既想落地本地AI推理、多設備聯網協同等智能化功能,又難以承擔高端工控方案的高昂部署成本;既要求硬件能適應高低溫、粉塵、電磁干擾的復雜工業環境,又受制于預算門檻退而選擇消費級主控,最終往往陷入“改得起、用不住”的尷尬局面。這是當前工業智能化向中端下沉過程中的共性痛點。一方面,高端算力方案性能過剩、單價居高不下,多設備批量部署時成本壓力陡增,而入門級主控又
    飛凌嵌入式 2026-08-12 08:52 213瀏覽
  • 導語:進入8月,全球LCD TV面板采購需求受年底大促備貨、以價換量策略雙重拉動呈現邊際回暖,但修復力度整體有限。由于頭部面板廠持續維持高稼動生產,行業供需格局仍處寬松區間,面板價格整體延續小幅回落態勢,尺寸結構性分化特征持續顯現。CINNO Research 簡評今年8月,全球 LCD TV面板市場呈現需求弱修復、供給高位運行的特征,整體價格延續下行且結構性分化顯著。需求端受年底大促備貨、以價換量策略拉動邊際回暖,但修復力度有限且建立在以價換量的基礎上;供給端高世代線稼動率維持85%以上,供需
    CINNOResearch 2026-08-12 11:00 151瀏覽
  • 一只光模塊在出廠前,要在-40℃的極寒、25℃的常溫、85℃的高溫之間反復“渡劫”。稍有不慎,輕則參數漂移,重則整批報廢——這就是三溫測試,高速光模塊量產前的最后一道生死線。引言:AI越熱,測試越難AI數據中心的爆發式增長,讓400G、800G甚至1.6T光模塊的需求如火箭般躥升。但鮮為人知的是:光模塊速率每翻一番,測試時間卻不降反升。一組殘酷的數據對比:速率單只模塊測試耗時測試設備帶寬要求400G約15-20分鐘50GHz800G約20-30分鐘50GHz1.6T約40-60分鐘≥65GHz設
    用戶1774416745629 2026-08-12 13:36 292瀏覽
  • 100 字導語現場防爆航插頻繁出現插拔卡頓、沙沙異響、對位卡死等問題,大多不是產品質量問題,而是粉塵進腔、觸點氧化、防呆鍵位磨損導致。本文結合 3 針 3 孔、4 芯、5PIN、8 芯圓形防爆連接器運行特性,梳理異響卡頓故障根源,制定標準化清潔修復流程,保障防爆航空插頭對接順暢、密封到位。關鍵詞:圓形防爆連接器,防爆航空插頭,防爆端子接頭,防爆接插件,插拔卡頓,IP67,5PIN,8 芯,防爆傳感器航插接頭1 產品概述圓形防爆連接器公母頭依靠精密鍵位、冠簧插孔、密封面精準配合實現對接。現場粉塵堆
    kyfbest科迎法電氣 2026-08-12 11:43 243瀏覽
  • 信息摘要:很多做智能硬件的工程師都遇到過這種情況,產品語音控制一聯網,用戶喊完要等上一兩秒才有反應,網絡一抖就失靈,斷網直接變磚。離線語音識別芯片把整套識別流程搬到設備本地,不依賴網絡,響應快還保隱私。本文用三分鐘講清楚離線語音識別在芯片里到底走了哪幾步,以及本地識別為什么比云端快。一、語音識別在設備上到底走了哪幾步不管云端還是離線,一段語音從被聽到被理解,都要經過一條固定的流水線。麥克風把聲音變成微弱電信號,芯片內部的運算放大器先做前置放大,再由模數轉換器轉成數字信號。接下來是降噪和端點檢測,
    唯創知音語音芯片 2026-08-11 15:11 173瀏覽
  • 隨著AI算力需求的爆發式增長,400G、800G乃至1.6T高速光模塊正加速走向商用部署。在這場速率競賽的背后,一個不容忽視的挑戰正浮出水面——硅光模塊對溫度的“敏感體質” ,正在成為可靠性驗證領域的新課題。一、為什么硅光模塊如此“怕熱怕冷”?傳統光模塊主要采用III-V族化合物半導體材料(如InP、GaAs),而硅光模塊則以硅基材料為核心,借助CMOS兼容工藝實現光電器件的單片集成。這種技術路線帶來了成本低、集成度高、功耗小的優勢,但也埋下了溫度敏感性的隱患。根源在于材料的熱膨脹系數
    用戶1774416745629 2026-08-13 09:40 232瀏覽
  • 文:侯煜編輯:cc孫聰穎在巴西,油價的每一次起伏,都直接牽動數十萬網約車司機的收入。受全球地緣局勢影響,國際油價常年高位震蕩,燃油成本成為當地全職司機最剛性的營運支出。正常營運節奏下,一臺燃油車每月油費高達3000雷亞爾(折合人民幣近3960元)。疊加保養、車輛損耗等成本,很多司機看似每日單量穩定,月末實際到手利潤卻十分有限。隨著中國新能源車持續落地巴西,當地司機最棘手的營運難題正在逐步消解。圣保羅網約車司機Elio是較早換車嘗鮮的從業者。2023年,他購入一臺比亞迪海豚全職接單,兩年累計營運里
    華爾街科技眼 2026-08-11 15:38 169瀏覽
  • 報警語音在工業設備里的難題做工業設備的工程師多半遇到過這種事。設備上要播的語音條數越來越多,正常開機提示、運行狀態播報、故障報警、維護提醒、安全警告,加起來幾十條甚至上百條。一開始用小容量 OTP 芯片還能應付,條數一多就不夠用了。換大容量芯片,成本又上去了。更大的麻煩在報警優先級上。工業設備運行時,語音芯片可能正在播放一段正常運行狀態提示,比如"設備運行中,請勿靠近"。這時候突然檢測到故障,需要立刻插播一條緊急報警語音"溫度過高,請立即停機檢查"。傳統語音芯片做不到這件事。它要么得先發停止命令
    唯創知音語音芯片 2026-08-12 17:50 231瀏覽
  • 8月8日,國聯民生證券發布了一則公告,內容表明公司董事會收到了非執行董事楊振興提交的辭職報告,其因個人原因辭去公司非執行董事這一職務。而且在辭職之后,楊振興將不再擔任國聯民生證券以及其控股子公司的任何職務。僅僅兩天之后,公司第六屆董事會第7次會議召開,這次會議一口氣通過了多項議案,包括審議通過《國聯民生證券股份有限公司“十五五”發展規劃(2026-2030)》、1億至2億元A股回購方案以及為子公司民生證券提供不超過40億元的動態凈資本擔保承諾等等。同時,為優化資源配置,公司還擬減少民生證券注冊資
    用戶1782919753097 2026-08-13 00:00 229瀏覽
我要評論
0
點擊右上角,分享到朋友圈 我知道啦
請使用瀏覽器分享功能 我知道啦
主站蜘蛛池模板: 夏家三千金27| 女欢女爱第一季| 爱你几何130| 古惑仔5之龙争虎斗粤语版免费 | 拒绝爆冷 大头王者归来打疯了| 潍坊科技学院女生跳舞 | 孤儿 电影| 那年花开月正圆 迅雷下载| 私家车跑滴滴怎么加入| 女版战狼14免费观看完整版| 游客借位拍照与大佛击掌| 致美丽的你插曲| XL司令第二季无马赛第八集免费观看| 孤独摇滚动漫在线观看免费| 男生和女生在一起愁愁愁在线观30集| 谢娜魏大勋去看张杰演唱会| 电视剧光荣岁月| 浮之手2| 电视剧刘老根三部全集2019| 美容室的特殊待遇6| 幻影行动| 制服诱惑在线播放| 两个人的二人世界原声| 小日子全部免费播放电视剧| 电影美乃雀主演的电影在线观看| 素鸡豆腐| 仙逆全集完整版免费看| 《美容院:特殊待遇》免费观看| 快乐星球第五部| 猪猪侠之囧囧危机| 邻居换娶妻1完整版中文| 亚洲无mate20pro麻豆| 修理工的艳遇在线| 我家的一件珍品| 大嫂查之女百度影音| 天乩之白蛇传说电视剧全集免费| 敢死队1电影| 《美味快递员2》| 《黑寡妇》电影| 双女任务在线免费观看| 黑帮老大歌我的365天| 异次元骇客电影| 生殖按摩电影美国片高清未删减讯雷下载| 金瓶梅电影百度影音| 小少女性启蒙的电影有哪些| 御岭秘录电影| 喋血街头电影| 人间中毒无删减在线| 富爸爸大预言| 我的邻居长不大免费阅读| 美式保罗4中文版| 《赘婿》| 济公传 郭德纲2013| 年请的母亲4| yy11111光电影院| 美容院特殊待遇1| 红豆女之恋| 四位大学位按摩记PDF免费下载 | 飞驰人生在线观看完整版 | 小先知电视剧| 上门瑜伽性按摩| 美景之屋2女老板娘的名字| 罗马欲乐园| 雪烟追逐未删减| 桥隆飙2| 小英雄雨来电影| 《总统》星克莱尔1997年满天星在| 500篇艳妇短篇合换爱小说| 插曲30免费高清完整版| 金装鬼打鬼未删减版观看| 陷阱韩剧完整版免费观看| 黑崎先生停不下来的专一之爱电视剧 | 你是我的姐妹| 敌人英语| 斗罗大陆193集免费完整观看| omoflow第一季全集免费| 闪婚大佬后免费全集在线观看| xl司令第一季全集免费观看动漫 | 名侦探柯普通话免费观看 | 神印王座免费完整观看| 白峰电影免费播放| 煎饼侠 电影| 神奇四侠2国语版| 善良的女秘书视频| 西西里的美丽传说 高清| 三年大片大全高清免费国语版| 老师的秘密 韩国| 《女超人》麦乐迪版剧情| 高清《血疫》电影| 刀郎演唱会首站成都| 美国恐怖故事第六季| 一盘大棋电影| 刺杀据点下载| 婿事待发全集免费观看全集| 女超人满天星版在线观看| 唐诡事录之西行| 小蜜桃6观看免费高清版电视剧97| 足球小将粤语版全集| 十二生肖电视剧全集| 《热带雨》完整版| 楚汉骄雄30集国语版高清免费观看| 《部长出差的日子》演员| 超神学院第7集| 需要爸爸播种手机播放美国电影的软件 | 乡村爱情13部全集免费刘能| 本乡爱电影合集在线观看完整版| 金蝉脱壳| 三年中文高清免费观看| 百度战曲| 天芒传奇| 杨三姐告状评剧全剧| 《大鱼海棠》| 烧包谷云南方言版| 麦蒂自抛自扣| 韩剧女友的母亲双字ID| 死亡笔记电影1| 黑白配hd1080免费观看下载| 桃花运电视剧全集观看| 免费播放白峰美羽救赎治愈电影视频下载| 电影花样年华| 孤胆飞鹰| 傈僳族怎么读| 电视剧破冰行动48集免费完整版| 未成年之欲免费观看-嘟嘟韩剧网 沧元图免费在线观看 | 《战士》凯登克罗斯| 宁夏杀人案| 21世纪性格爱情指南俄罗斯| 美景之屋2迅雷下载| 我的战鹰绕着宝岛飞原唱| 地球脸红了| 李立群个人资料简介| 终极一班3部第一集| 摩绪电视剧| 《极乐宝鉴》2徐少强| 美国荷尔蒙免费观看高清| 美国电影《小辣椒3》| 鬼打鬼 电影| 特殊的游泳教练在线观看| 新生电视剧在线观看免费完整版 | 非诚勿扰最有钱的男嘉宾| 重庆废弃红太阳幼儿园发生了什么| 高清火烧天堂镇未删减| 燃冬免费观看完整版电视剧全集| 千金女贼 电视剧| 青青草原影视| eeuss| 综艺免费观看| 战狼6免费观看在线播放下载电影视频 | 张悦楷免费粤语讲古大全| 日本小妞| 新包青天之七侠五义| 激战丛林电影| 陆弃娘短剧全集免费观看| 《善良的女邻居》4| 昴宿七星| 姐妹牙医1986在线| 恶魔少爷别吻我第二季| 俄罗斯卖车子销售和老板电影| 湖南黑山羊价格| 《年轻的女保险销售员》电影全集在线播放 - 泡剧网 | 黑街舞男高清版免费观看| 男女一起愁愁愁免费在线观看| 许我荣耀电视剧更新| 坠落的女律师日剧免费观看| 艾曼纽在线观看免费完整原声| 电影金瓶梅电视剧免费观看全集| 男神爱上:暗恋成真全集免费| 大家族国语| 挡不住的风情 下载| 水浒传2011| 新加坡国花| 正义之剑| 法律与秩序特殊受害者| 我的老婆姐姐免费播放| 密室大逃脱第二季| 外出孙艺珍电影| 韩国女空调维修工| 哪吒降妖记电视剧| 插曲的痛第60集全部剧情| 大内密探零零发电影| 情事为了| 插曲30集全集免费播放在线观看 | 老婆6电视剧免费播放| 需要爸爸播种籽2全集免费看| 遮天 全集| 三姐妹电影版| 多大点事啊电视剧在线观看,天海翼香汗女教师在线播放,剧情片全集免费播放免费 | 陈静仪喜爱夜蒲2| 维修工的艳遇在线观看完整版免费| 国产真人做爰免费视频| 盛夏晚晴天电视剧| 《初体验5》电影完整版在线观看 爱我几何电影完整版在线播放高清 | 同盟国语版全集免费观看| 《屠宰森林》在线观看| 电影铁原阻击战在线观看| 无敌破坏王1| 牙医姐妹在线观看免费观看| 十日游戏电视剧免费观看| 3d金瓶梅在线观看| 河北彩花陪上司出差mv| 长征五b首飞成功| 美好的时光电视剧| 大邱庄卖钢管女视频完整版| 同学的妈妈5观整有限中字| 向东是大海百度影音| 明珠奇谭| 《美丽妻子替丈夫还债》 | 三生三世十里桃花在线观看| 国际刑警粤语| 《瓜达卢佩玫瑰》在线播放 | 归去来剧情| 狮子王国语版| 爱情鸟在线论坛1在线观看| 愤怒的小孩电影全集 | 地心游记3| 商务旅行戴绿帽子在线观看 | 1995版人猿泰山hr版本内蒙古| 恐怖片女佣| 长相思第一季全集免费完整版高清| 男女愁愁愁视频在线观看| 老年钢琴班| 平安365| 义姐是| 92午夜神器1000| 小离别电视剧免费全集观看| 插曲的痛30全集免费观看高清版在线观看 | 人生路不熟免费| 大开眼界剧情深度解析| 蝙蝠侠与罗宾| 战狼6免费观看在线播放| 尼古拉斯凯奇电影| 与僧侣交合| 阿朱外卖三部曲| 无限动漫在线观看免费| 日本三国电视剧| 赌圣周星驰国语高清| 人狗大战8集全集观看免费西瓜 | 猛鬼佛跳墙国语| 大长今之尚宫天下| 朱莉安妮监狱| 我结中国版| 不扣纽扣的女孩qvod| 花子vs倔强驱魔师全集免费观看高清 | 有求必应在线观看| 无法无天满天星完整版| 专家称女生游泳私密贴是智商税| 走火电视剧40集免费完整版| 喀喇沁旗| 职业替身泰剧免费观看| 五十八天| 战狼6欧氏少女全部剧情介绍大全视频 | 韩国电影维修工的艳遇| 金瓶梅1-5电影观看完整版丿| 无法传达给你在线观看日剧| 鼠来宝3电影完整版| 商务旅行戴帽子的老板同行百度云| 终结者1免费高清电影| 爱情魔发师免费全集高清在线观看| 英国纪录片《老二》| 爱情有烟火电视剧| 隋唐英雄108| 战狼6免费全部完整版下载| 快穿之爱爱做不停H| 游击兵工厂全集| 我的错误电影免费观看| 《无颜之月》完整版在线播放| 单身首尔电影| 魔角侦探| 《外卖员外遇》| 《赶尸艳谈》无删减版| 私人女性| 最美情侣在线播放观看| 女技师| 同学的母亲电影| 西西里159分钟无删减bt| 熟男有惑 粤语| 高清《圣墟》动漫 | jiqingwang| 女朋友的新妈妈双字ID| 扫黑风暴在线观看| 电视剧时尚女编辑| 《家庭矛盾》麦乐迪在线播放| 造梦西游2五官王| 泼天富贵短剧免费观看| 我要上你1978法国原版| 战狼5免费观看完整版| 瑜伽学院 电影| 超级女警察| 黑白配电影在线| 一个好妈妈如如2| 诺曼底大风暴| 爱我几何完整版播放| 扫黑风暴26| 燕窝多少钱一斤2023年价格| 陈雅伦曹查理《我为卿痴狂》在哪里 | 是妈妈是女儿2综艺| 白夜追凶第三季| 追球在线观看免费完整版| 因法之名电视剧全集在线观看| 鬼灭之刃无限城篇免费完整版| 真心电影网| 女机械人在线| 终女武神第三季在线看| 延禧攻略免费70集| 国产真人做爰视频免费| 需要爸爸播| 我们十七岁| 姐姐的朋友5在完整4视频带翻译| 《和讨厌的部长出差旅》 | 牙医姐妹在线观看 赤子板栗| 囧妈高清在线观看| 处女膜电影| jiZz日本| 人类我们的故事全集| 男生女生免费完整版在线观看| 林晓峰电影| 女超人麦乐迪在线完整版2013| 新生电视剧剧情介绍| 新妈妈朋友| 韩国女战狼| 雪豹39| 《初中小女孩》完整版| 五夜天| 高清《天国与地狱》电影| 2008金银梅1-5普通话| 《文豪野犬第四季》动漫| 《二对一的商务模式2》中文| 飞利浦显示器维修| 阳光姐妹| 站着再来一次26集全在线观看| 韩国电视剧宫全集| 不怕开水烫| 《千金爱上佣人》完整版| 逆天成仙电视剧| 挣扎吧亚当君第二季| 结过一次了电视剧| 恶灵骑士2在线看| 入室暴行3在线观看| 广州挂图大师| 夜光神杯全集| 特殊治疗室护士| 朱孝天版楚留香传奇| 海洋之恋番外篇| 大唐诡事录2电视剧免费观看全集| tube 8| 舒淇三圾片在线观看| 因为爱情晴天结局40| 美国女儿需要爸爸播种2023年上映时间 | 女友的妈妈双字id推荐| 爱的二八定律在线观看| 电影《售楼小姐》免费观看| 千王之王重出江湖电视剧| 重生弃少全集免费| 双鱼陨石在线观看| 童颜不老三公主| 特殊美容室| 爱情真善美全集80| 《胶囊旅馆动画第一季》| 部长夫人25| 开放的家庭| 画皮之阴阳法王| 向井蓝之特殊治疗医护工作内容与背 | 黎明前的黑暗免费观看| 小小水蜜6电视剧免费观看高清 | 暗花国语| 名侦探柯南724| 我的漂亮的小瘦子3完整版| 沧元图动漫免费全集| 黑白配在线高清观看免费| 黄沙武士2| 《年轻的女保险销售员》电影全集在线播放 - 泡剧网 | 魔法坏女巫2未删减| 啄木鸟满天星电影壮志凌云成人版在| 阿姨大小姐| 三妻四妾免费观看完整版高清,皇家女 | 越策越开心| 《赘婿》免费完整版在线观看西瓜| 金银悔5一1| 樊振东爆冷出局事件| 《售楼小姐的秘密》| 我家三爷宠短剧免费观看| 长风镖局高清| 《修女也疯狂2》电影| 双枪李向阳| 《艾拉妮丝》电影| 夏娃韩剧完整版| 少年包青天2部| 小小水蜜桃6| 高清《依然闪亮》电视剧| 电锯惊魂7高清版| 鬼吹灯之天星术完整版免费观看| 死神来了3的d9版| 异形庇护所| 隔壁邻居很美味免费版| 破地狱粤语| 七台河市| 喜爱夜蒲演员| 契约婚姻高清在线观看| 不雅空乘2在线观看| 银魂188| 《法国空乘5》| 高清《月老》电影完整剧情| 斗罗大陆212| 《房屋销售的秘密》日本 | 健身瑜伽2国语中字版| 朝鲜美女bbwbbw撒尿| 傻王闯天下全集| 私人航空手机在线观看| 地下九英里| 月光宝盒私人免费影院| 战狼6高清完整免费观看下载| 花姐的个人资料| 无限春光27 豆瓣| 我的父亲母亲免费| 宝贝计划 成龙| 《维修师傅艳遇》韩国在线观看| 银魂137| 澄城县| 怪物大学国语| 黑白配国语版在线播放| 丹麦女孩未删减版| 拜登又双叒叕口误| 特殊饿游泳池在线观看| 关东棋王| 天海翼搜查官在线观看| 狐妖小红娘电视剧免费观看完整版| 《五十度灰3》三部曲在线观看| 唐朝禁宫秘史电影| 冲上云霄1主题曲| 《满天星版·波斯女人》百度| 大丈夫电视剧全集48| 女子护卫队满天星版在线播放| 胜者即是正义2| 命中注定我爱你演员表| 受益人 电影| 仙逆113| xl司令动漫全集| 樱桃嘴与大鼻子| 兔子先生视频第一季免费观看全集高清 | 老师让我趴在讲台H| 爱情雨大结局| 《高血压监狱3》电影法国版在线观看| 《柑橘味香气》动漫| 舒克和贝塔电影| 屋顶的散步者| 斗破阴阳宅电影免费观看| 婚礼前婚闹先上车在线观看| 湄公河行动在线观看| 临江仙在线观看| 电影三人一次性体检| 一站到底2018| 日本搞笑整人节目| 电影《千金》郝板栗免费播放| 吉它兄弟| 善良的老师3完有限中字木瓜| 意大利女超人| 鬼吹灯有声小说在线收听| 庆元县| 东北往事黑道风云20| 哥哥姐姐的花样年华电视剧| 色九月在线观看| 秘密潜入2完整版| 傻瓜猫全集| 晚安为我而眠的妹妹在线观看 | 两个好媳妇中文在线观看| 铁血昆仑关电影| 酒店实生3美国 | 最后的战士电视剧免费观看| 塔日酒店在线观看| 雪中悍刀行第二部免费| 咱们结婚吧26| 中国匣电影| 欧美开船的电影原声| 楼顶的大象| 捉妖记电影在线观看| 花与蛇1全集百度影音| 小蜜挑5| 娜妲莉的情人| 暗香 电视剧| 一女大战七个黑人到喷浆| 八戒8电影在线观看播放 | 日本剧情片修理工的艳遇| 乡情电影| 嗅觉神探| 黑白配免费播放高清完整版| 需要爸爸来播种在线播放| 抉择在线观看| 九河龙蛇| 粉红大白菜经典版丹麦| 都市战神短剧全集| 长津湖战役3免费观看| 关于爱情的英文诗| 三年大片国语版在线看| 上海滩全集| 一路向西 主演| 韩国演艺圈悲惨1-33集| 游泳的秘密| 《新生》完整版在线播放| 宿醉2百度影音| 爱人电影免费观看韩国| xl司第二季真人版| 七十二春免费观看播放| 我不受欢迎都是你们的错| 《爱我几何》电影免费| 三年中文在线观看免费观看第三集| 鬼吹灯之昆仑神宫电视剧免费观看| 咒术回战第二季在线观看免费观看| 哇嘎电影免费观看高清国语| 罪恶六芒星1979| 天师钟馗金超群| 唐朝豪放女电视剧完整版| 安斋拉拉下雨天免费观看英文版| 狄仁杰第一部完整版全集| 天下无双张靓颖| 吾岸更新至15集| 2对一商务服务| 古剑奇谭迅雷下载| 绝品邪医的桃花劫短剧免费观看 | 插曲30免费高清完整版| 17岁在线观看完整版| 少年张三丰张卫健电视剧免费观看| 精灵俏女巫| 秘密女搜查官影视先锋播放| 壮志凌云2011| 李桢航资料| 马戏小子| 白峰电影观看| 甄嬛传免费全集观看完整版在线| 浪漫满屋泰国版11| 牧神记39集免费观看| 八戒电影观看8| 上海地铁内男子耍刀| 公交车艳妇系列1一40| 度华年全40集免费观看| 玄好心经9| 闪婚顶流爱豆:是我老公短剧全集 | 《修理工的艳遇》接丈夫电话还在做爱 | 韩剧《蓝色生死恋》国语 | 《女医生4》免费观看全集完整版| 聊斋艳谈之灯草和尚| 你不懂电视剧网| 霍元甲哪一年播出的| 插曲的痛60全集免费观看高清版无马| 《绝对臣服》短剧赵振栋| 我是刑警34集全免费| 虎鹤妖师录| 公媳韩国| 王力宏什么歌好听| 墓穴迷城迅雷下载| 另一个贝内特家的姐妹全集观看| 伦理剧场黛比浪漫女家教| 真假学园| 记忆女神的女儿们下载| 青禾男高电影| 电影《水手服的饲养》| 妖精的尾巴全集| 灌篮高手特别篇| 旺角监狱在线观看| 安姨售楼女王电影在线观看| 情人的眼泪简谱| 杀生在线观看| 新三国粤语| 特殊房产销售5| 十七岁的天空插曲| 非诚勿扰聂倩| 电影恋爱的味道| 妈妈爱上儿子的同学完整版电影| 《maruzzella》完整版在线观看| 三百勇士帝国崛起| 姑娘高清完整版在线观看免费| 契卡 高清下载| 《特殊游泳教练》完整版| 吞噬星空171| 甄嬛传63集剧情| 无名高地电视剧| 女超人麦乐迪2013| 法国电影《女流氓》的剧情简介| 识骨寻踪第一季高清在线观看| 锦绣安宁免费全集完整版| 需要爸爸的播放| 万王之王电影| 铁马寻桥粤语| 神马电影《女销售》| 亲爱的老师6中文版完整版| 美国伦理蜜桃5| 兽兽门种子| 肉食日未删减| 法国少女农场高清在线看| 古惑仔电影全集国语| 爱的勘探法电视剧| 好姑娘1免费观看| 年轻的小姐姐| 我朋友的母亲2完整视频有翻译吗 新妹魔王的契约者第二季无修版 胜女的代价 第2季 | 刘青云第三次获金像奖影帝| 司令XL第一季真人版| 私藏浪漫在线观看| 初恋时间第一集在线观看免费高清| 需要爸爸播种美国第二季| 霹雳神州iii之天罪| 无尽情爱双男主泰剧在线观看| 鸣鸟不飞| 八尺夫人意大利免费观看全集高清 | 壮志凌云女版满天星法版免费观看 | 满天星《律师事务所》| 李采潭在线观看| 猎场下载| 爱丫爱丫影院最新电视剧免费观看 | 比基尼勇士| 猎杀行动第一季| 我想爱着你| 雾散之时短剧免费观看| 自治县| 幸福满院电视剧全集在线观看 | 璀璨人生65集| 特别酒店l984美国| 乱世丽人行50集电视剧免费观看 | 《花与蛇·1》| 策驰影视免费大全在线观看| 新审死官 电视剧| 《新金银悔1—5普通话》第21集| 侠探杰克高清| 韩国电影出轨| 电影《第八日》凯登克罗斯| 十八岁完整版在线观看高清| 法国版《安全出口》| 麦乐迪满天星| 上流社会免费完整版电影韩国| 纵情欲海电影无删完整版| 篠田あゆみ| 动漫二人生猴子免费观看动漫视频| 沙漠女性治疗营2| 正播:巴黎奥运会开幕式| 五福星系列| 宋孝敏在《露营地》里扮演谁| 灌篮高手粤语| 美国伦理眉睫膏2| 铁血战士3| 丁巴度电影在线免费观看| 《万能遥控器2》女主角是谁| 《法官李汉英》| 妖怪都市免费观看完整版在线播放| 美国式保罗2原版电影在线观看| 酒店1-90集免费观看高凊| 高清危情蜻蜓未删减| 风信子开花后怎么处理| 《力王》电影完整版在线观看| 花子vs倔强驱魔在线观看| 爱情有点蓝第二部| 蝴蝶效应1| 盗亦有道百度影音| 娃娃脸9在线观看完整| bastard暗黑破坏神| 变相怪杰| 《黏黏糊糊的你》第1集| 牧化师4污染的讲台1-6剧情介绍| 我的美好时代| 妻子的姐姐在线| 浴血黑帮全季在哪能看| 女保镖满天星免费观看| 情人十八岁| 妻子的谎言 电视剧剧情免费观看| 铿锵铿锵锵锵锵免费观看电视剧| 永不妥协| 我和我的三个姐姐| 成年秘密免费版电视剧在线观看| 电影《酒店温存》| 比天堂还美丽 电视剧| 羞耻电影完整版| 巩留县| 军事不当行为完整版| 奥本海默在线原版免费| 红尘恋歌| 两个小婕子和我做愛| 妻子6免费完整高清电视剧看5| 儿媳妇长的太漂亮是什么电视剧啊| 断箭行动免费| 苍井空电影网| 马永贞电视剧| 落魄贵族琉璃川动漫全集免费观看| 亲爱的x| 余味毛豆豆| 谢霆锋演唱会2012| 临西县| 360天大佬爱上第二季| 野蛮女友2插曲| 野兽刑警| 肩上芭蕾| 战狼6欧美版免费资源下载| 电影需要爸爸的播种子| 那曲在线| 杀生在线观看| 高清十一未删减| 成熟的麦子2| 熟睡中被义子中出6次在线观看| 刘青云电影| 离婚律师结局| 特利迦奥特曼普通话| 《北越暴行》3| 360大佬爱上我第三季免费观看| 亲兄热弟剧情| 漂亮的保姆韩国电影观看免费版| 给我免费观看片在线电影的| 义子的无理侵犯| 野外强伦轩女教师HD| 杉杉来了 电视剧| 韩国2013歌谣大战| 恶少的毒爱| 行政助理2014免费完整版| 黑白配电影免费高清在线观看国语| 马克斯·维斯塔潘:新征途电视剧| 潘石屹是谁| 巡回检察组免费看| 《高血压监狱3》电影法国版在线观看| 孤岛猎鹰电视剧全集| 杨贵妃免费观看| 刀郎经纪公司回应新歌争议| 门不当户不对全集完整版| g点电影完整版在线观看| 电影《焦点》完整版免费观看| 超异能族 电视剧| 我的老婆是学生会长第一季| 阳东县| 《法国空乘5》在线免费观看 | 小瘦的宝藏| 邵氏电影《聊斋奇谭》| 潜行狙击之潜罪犯| 李丽莎无圣光原图| 法国空乘1980版在线播放| 素描少女 电影| 漂亮的保姆中文字幕完整版| 柘荣县| 社长与下属妻子韩国| 北上电视剧13| 阿虎视频免费观看| 长相思第一季多少集| 《日本公与媳5》筱田优| 《太太们的假期》意大利| 反击国产电视剧全集| 酒店第1-100集免费观看下载| 高清《潜渊》电视剧全集免费观看 | 珍惜彼此感情的句子| 大牛影库战狼6免费观看| 娘家的故事第3部| 好妈妈5国语在线观看| 欲望中的女人电影| 伦理《法国护士长》高清电影| 快递员的特殊待遇| 新浪潮全集观看| 姐妹牙医免费| 向天再借五百年简谱| 男女在线观看免费高清电视剧推荐| 木下檀檩子电影在线观看2023年上映时 | 儿子与情人视频完整版在线观看| 欧美女人ooozzzxxx| 英雄本色4| 一刀不剪| 临沂新闻综合频道| 电影《美容院的特殊待遇| 你是我的荣耀27集在线观看| 污性福宝| 《激战丛林》完整版美国在线播放| 刺客伍六七第三季玄武国篇免费观看 | 藏珠电视剧在线观看| shoeplay| 男与女 电影 2016| 法国空乘5完整版免费看| 三星手机广告曲| 黑帮老大和我的365天| 希要爸爸的种子| 天域战士2| 《野花》电影| 台湾局势最新消息| 情圣终结者下载| 电影《姐妹牙医》赤子板栗| 无法拥抱的你第二季电视剧| 伊人网站在线观看| 陆小凤之大金鹏王| 澡屋先生| 墨西哥呱达卢佩的玫瑰在线观看完整版 | 萌宝寻爹全集免费| 赛尔号大电影5| 黑白配2018| 播放米老鼠| 心理测量者| 啄木鸟:女版《壮志凌云》音译成中文| 玉蒲团3之初入桃源洞| 龙猫电影完整免费普通话在线观看| 足球尤物高清完整版在线观看| 安斋拉拉出演的电影| 为何是你在线观看| 征服人妻第1-52集资源请求| 老男孩电影高清在线观看完整版 | 一个好妈妈高清完整版| 急诊护士完整版在线观看| 吸血鬼日记第四季快播| 黑客帝国1| 小白船舞蹈| aj视频电视剧大全| 小千的开发日记| 金瓶梅1-5电影观看完整版丿| 一起来看流星雨在线观看免费高清| 女保险公司的推销员8中| 误杀原版| 搞批视频| 抽曲的痛免费高清观看| 花开有声电视剧全集 | 姐妹牙医| 流水迢迢电视剧免费观看全集高清 | 恶女教师百度影音| 武装特警| 华丽的外出电影在线| 林州市| 需要爸爸播种子 在线| 钻石大劫案电影张浩| 网民发布辱国等不当言论被刑拘| 电影《恋爱之瘾》免费观看| 诱人的秘书在线观看| 《激战丛林》-罗莎·卡拉乔洛免费观| 小凤结婚| 跨界歌王第三季| 宇宙星神全集2| 《芬芳喜事》今日开播| 韩国电影女教师| 金银瓶1-5hd普通话2| 无名卫士电视剧全集免费播放| 金瓶梅bmp3视频| 上海滩简谱| 狠狠地撸2015最新版| 用一生去爱你电视剧| 黑白配HD1080电影免费版 | 西出玉门几点更新| 《蜜桃成熟时》| 生生世世爱简谱| 丰满的继牳小早川怜子| 安吉拉怀特透视电影免费观看2023年上| 剧场版佐佐木与宫野电影| 风雷影音电影| 勾魂绮梦在线观看| 昼颜电影完整版高清免费在线观看| xl司令第2季无马赛免费观看高清初级 | 女房东的味道3| 出轨电视剧在线观看完整版高清 | 凯帕克在线观看| 八零弃少重生:搞钱宠媳妇全集免费| 致命弯道5 电影| 电影《官人我要》在线观看| 一边面摸一30分钟| 香瓜七兄弟全集| 喜爱夜蒲快播观看| 麻辣豆腐在线观看| 巜女超人》1979|