概述
/*
* Macro to mark a queue as locked. Locking a queue prevents an ISR from
* accessing the queue event lists.
*/
#define prvLockQueue( pxQueue )
taskENTER_CRITICAL();
{
if( ( pxQueue )->cRxLock == queueUNLOCKED )
{
( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED;
}
if( ( pxQueue )->cTxLock == queueUNLOCKED )
{
( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED;
}
}
taskEXIT_CRITICAL()
/*-----------------------------------------------------------*/
/* Constants used with the cRxLock and cTxLock structure members. */
#define queueUNLOCKED ( ( int8_t ) -1 )
#define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 )
1 static void prvUnlockQueue( Queue_t * const pxQueue )
2 {
3 /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
4
5 /* The lock counts contains the number of extra data items placed or
6 removed from the queue while the queue was locked. When a queue is
7 locked items can be added or removed, but the event lists cannot be
8 updated. 上锁计数器在队列上锁之后进行计数统计,但事件队列中两个列表(WaitToSend/Rcv)的那些任务的事件列表项不会更新变动*/
9 taskENTER_CRITICAL();
10 {
11 int8_t cTxLock = pxQueue->cTxLock;
12
13 /* See if data was added to the queue while it was locked. 【】*/
14 while( cTxLock > queueLOCKED_UNMODIFIED )
15 {
16 /* Data was posted while the queue was locked. Are any tasks
17 blocked waiting for data to become available? */
18 #if ( configUSE_QUEUE_SETS == 1 )
19 { 57 }
58 #else /* configUSE_QUEUE_SETS */
59 {
60 /* Tasks that are removed from the event list will get added to
61 the pending ready list as the scheduler is still suspended. */
62 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
63 {
64 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
//将任务从列表xTaskWaitToRcv中移除
65 {
66 /* The task waiting has a higher priority so record that
67 a context switch is required. */
68 vTaskMissedYield(); //就一句 xYieldPending = pdTRUE;
69 }
70 else
71 {
72 mtCOVERAGE_TEST_MARKER();
73 }
74 }
75 else
76 {
77 break;
78 }
79 }
80 #endif /* configUSE_QUEUE_SETS */
81
82 --cTxLock;
83 }
84
85 pxQueue->cTxLock = queueUNLOCKED;
86 }
87 taskEXIT_CRITICAL();
88
89 /* Do the same for the Rx lock. */
90 taskENTER_CRITICAL();
91 {
92 int8_t cRxLock = pxQueue->cRxLock;
93
94 while( cRxLock > queueLOCKED_UNMODIFIED )
95 {
96 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
97 {
98 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
99 {
100 vTaskMissedYield();
101 }
102 else
103 {
104 mtCOVERAGE_TEST_MARKER();
105 }
106
107 --cRxLock;
108 }
109 else
110 {
111 break;
112 }
113 }
114
115 pxQueue->cRxLock = queueUNLOCKED;
116 }
117 taskEXIT_CRITICAL();
118 }
119 /*-----------------------------------------------------------*/
解锁过程:
先处理 TxLock,
while(根据TxLock的值,看看队列上锁期间是否有“入队操作”,如果有)
{
则观察事件等待列表,有任务在等待则,
将这个任务从事件等待列表WaitToRcv中踢掉,加入就绪列表 或 Pending就绪列表(函数TaskRemoveFromEventList的操作)
置位PendSV准备切换任务,之后TxLock值减一。
}
修改 TxLock 为 queueUNLOCKED。
RxLock类似。
留白
最后
以上就是还单身草莓为你收集整理的freeRTOS 队列3 上锁解锁的全部内容,希望文章能够帮你解决freeRTOS 队列3 上锁解锁所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复