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

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內(nèi)不再提示

FreeRTOS流和緩沖區(qū)簡介及實現(xiàn)

CHANBAEK ? 來源:南山府嵌入式 ? 作者:南山府嵌入式 ? 2022-12-06 16:20 ? 次閱讀

有關(guān)FreeRTOS中的函數(shù)后面都會講到,前面章節(jié)部分主要是說一下原理,看的時候比較乏味,了解即可,沒必要較真。

1-簡介

FreeRTOS流和緩沖區(qū)是任務(wù)和任務(wù)之間、中斷和任務(wù)之間的通信原語。和其他多數(shù)FreeRTOS通信原語不同,他們針對讀和寫的單一性進行了方案的優(yōu)化工作。例如將數(shù)據(jù)從中斷服務(wù)例程傳遞到任務(wù),或在雙核cpu上從一個微控制器內(nèi)核傳遞到另一個微控制器內(nèi)核。數(shù)據(jù)通過拷貝傳遞——發(fā)送端將數(shù)據(jù)復(fù)制到緩沖區(qū),讀取端將數(shù)據(jù)復(fù)制出緩沖區(qū)。

流緩沖區(qū)傳遞連續(xù)的字節(jié)流。消息緩沖區(qū)傳遞大小可變但離散的消息。消息緩沖區(qū)使用流緩沖區(qū)進行數(shù)據(jù)傳輸。

在FreeRTOS對象是惟一的,流緩沖區(qū)的實現(xiàn)(也是消息緩沖區(qū)的實現(xiàn),因為消息緩沖區(qū)是建立在流緩沖區(qū)之上的)假設(shè)只有一個任務(wù)或中斷將寫入緩沖區(qū)(寫入器),并且僅有一個任務(wù)或中斷將從緩沖區(qū)讀取(讀取器)。對不同的任務(wù)或者中斷寫入或者讀取是安全的,但是有多個不同的寫入或者讀取是不安全的。若有多個不同的寫入器,那么程序?qū)懭氡仨毭看螌懭氲腁PI函數(shù)(例如xStreamBufferSend())的調(diào)用都放在臨界區(qū)中,并將發(fā)送阻塞時間設(shè)置為0。同樣,如果有多個不同的讀取器,那么應(yīng)用程序編寫器必須將每次對讀取API函數(shù)(如xStreamBufferReceive())的調(diào)用都放在臨界區(qū)中,并使用0的接收塊時間。

2-中斷服務(wù)到任務(wù)流

2.1 介紹

流緩沖區(qū)允許一個字節(jié)流從中斷服務(wù)程序傳遞到一個任務(wù),或者從一個任務(wù)傳遞到另一個任務(wù)。字節(jié)流可以是任意長度的,而且不一定有開頭或結(jié)尾。一次可以寫入任意數(shù)量的字節(jié),一次可以讀取任意數(shù)量的字節(jié)。數(shù)據(jù)通過復(fù)制傳遞——發(fā)送端將數(shù)據(jù)復(fù)制到緩沖區(qū),讀取端將數(shù)據(jù)復(fù)制出緩沖區(qū)。

與大多數(shù)其他FreeRTOS通信原語不同,流緩沖區(qū)是針對單讀單寫場景進行優(yōu)化的,例如將數(shù)據(jù)從中斷服務(wù)程序傳遞到任務(wù),或在雙核CPU上從一個微控制器內(nèi)核傳遞到另一個微控制器內(nèi)核。

在FreeRTOS/source/stream_buffer.c源文件來啟用流緩沖區(qū)功能。可自行查閱。

流緩沖區(qū)的實現(xiàn)使用了任務(wù)的通知。因此,調(diào)用將調(diào)用任務(wù)置于阻塞狀態(tài)的流緩沖區(qū)API函數(shù)可以更改調(diào)用任務(wù)的通知狀態(tài)和值。

2.2 快速入門

在reeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c源文件 提供了一個示例,說明從中斷服務(wù)程序到任務(wù)使用流緩沖區(qū)傳遞數(shù)據(jù)的例程。在這里我給大家復(fù)制過來了。

1/*
  2* FreeRTOS V202112.00
  3* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4*
  5* Permission is hereby granted, free of charge, to any person obtaining a copy of
  6* this software and associated documentation files (the "Software"), to deal in
  7* the Software without restriction, including without limitation the rights to
  8* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9* the Software, and to permit persons to whom the Software is furnished to do so,
 10* subject to the following conditions:
 11*
 12* The above copyright notice and this permission notice shall be included in all
 13* copies or substantial portions of the Software.
 14*
 15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 17* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 18* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 19* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21*
 22* http://www.FreeRTOS.org
 23* http://aws.amazon.com/freertos
 24*
 25* 1 tab == 4 spaces!
 26*/
 27
 28/*
 29* A simple example that shows a stream buffer being used to pass data from an
 30* interrupt to a task.
 31*
 32* There are two strings, pcStringToSend and pcStringToReceive, where
 33* pcStringToReceive is a substring of pcStringToSend. The interrupt sends
 34* a few bytes of pcStringToSend to a stream buffer ever few times that it
 35* executes. A task reads the bytes from the stream buffer, looking for the
 36* substring, and flagging an error if the received data is invalid.
 37*/
 38
 39/* Standard includes. */
 40#include "stdio.h"
 41#include "string.h"
 42
 43/* FreeRTOS includes. */
 44#include "FreeRTOS.h"
 45#include "task.h"
 46#include "stream_buffer.h"
 47
 48/* Demo app includes. */
 49#include "StreamBufferInterrupt.h"
 50
 51#define sbiSTREAM_BUFFER_LENGTH_BYTES ( ( size_t ) 100 )
 52#define sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 ( ( BaseType_t ) 10 )
 53
 54/*-----------------------------------------------------------*/
 55
 56/* Implements the task that receives a stream of bytes from the interrupt. */
 57static void prvReceivingTask( void * pvParameters );
 58
 59/*-----------------------------------------------------------*/
 60
 61/* The stream buffer that is used to send data from an interrupt to the task. */
 62static StreamBufferHandle_t xStreamBuffer = NULL;
 63
 64/* The string that is sent from the interrupt to the task four bytes at a
 65* time. Must be multiple of 4 bytes long as the ISR sends 4 bytes at a time*/
 66static const char * pcStringToSend = "_____Hello FreeRTOS_____";
 67
 68/* The string to task is looking for, which must be a substring of
 69* pcStringToSend. */
 70static const char * pcStringToReceive = "Hello FreeRTOS";
 71
 72/* Set to pdFAIL if anything unexpected happens. */
 73static BaseType_t xDemoStatus = pdPASS;
 74
 75/* Incremented each time pcStringToReceive is correctly received, provided no
 76* errors have occurred. Used so the check task can check this task is still
 77* running as expected. */
 78static uint32_t ulCycleCount = 0;
 79
 80/*-----------------------------------------------------------*/
 81
 82void vStartStreamBufferInterruptDemo( void )
 83{
 84/* Create the stream buffer that sends data from the interrupt to the
 85* task, and create the task. */
 86xStreamBuffer = xStreamBufferCreate( /* The buffer length in bytes. */
 87sbiSTREAM_BUFFER_LENGTH_BYTES,
 88/* The stream buffer's trigger level. */
 89sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 );
 90
 91xTaskCreate( prvReceivingTask, /* The function that implements the task. */
 92"StrIntRx", /* Human readable name for the task. */
 93configMINIMAL_STACK_SIZE, /* Stack size (in words!). */
 94NULL, /* Task parameter is not used. */
 95tskIDLE_PRIORITY + 2, /* The priority at which the task is created. */
 96NULL ); /* No use for the task handle. */
 97}
 98/*-----------------------------------------------------------*/
 99
100static void prvReceivingTask( void * pvParameters )
101{
102char cRxBuffer[ 20 ];
103BaseType_t xNextByte = 0;
104
105/* Remove warning about unused parameters. */
106( void ) pvParameters;
107
108/* Make sure the string will fit in the Rx buffer, including the NULL
109* terminator. */
110configASSERT( sizeof( cRxBuffer ) > strlen( pcStringToReceive ) );
111
112/* Make sure the stream buffer has been created. */
113configASSERT( xStreamBuffer != NULL );
114
115/* Start with the Rx buffer in a known state. */
116memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) );
117
118for( ; ; )
119{
120/* Keep receiving characters until the end of the string is received.
121* Note: An infinite block time is used to simplify the example. Infinite
122* block times are not recommended in production code as they do not allow
123* for error recovery. */
124xStreamBufferReceive( /* The stream buffer data is being received from. */
125xStreamBuffer,
126/* Where to place received data. */
127( void * ) &( cRxBuffer[ xNextByte ] ),
128/* The number of bytes to receive. */
129sizeof( char ),
130
131/* The time to wait for the next data if the buffer
132* is empty. */
133portMAX_DELAY );
134
135/* If xNextByte is 0 then this task is looking for the start of the
136* string, which is 'H'. */
137if( xNextByte == 0 )
138{
139if( cRxBuffer[ xNextByte ] == 'H' )
140{
141/* The start of the string has been found. Now receive
142* characters until the end of the string is found. */
143xNextByte++;
144}
145}
146else
147{
148/* Receiving characters while looking for the end of the string,
149* which is an 'S'. */
150if( cRxBuffer[ xNextByte ] == 'S' )
151{
152/* The string has now been received. Check its validity. */
153if( strcmp( cRxBuffer, pcStringToReceive ) != 0 )
154{
155xDemoStatus = pdFAIL;
156}
157
158/* Return to start looking for the beginning of the string
159* again. */
160memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) );
161xNextByte = 0;
162
163/* Increment the cycle count as an indication to the check task
164* that this demo is still running. */
165if( xDemoStatus == pdPASS )
166{
167ulCycleCount++;
168}
169}
170else
171{
172/* Receive the next character the next time around, while
173* continuing to look for the end of the string. */
174xNextByte++;
175
176configASSERT( ( size_t ) xNextByte < sizeof( cRxBuffer ) );
177}
178}
179}
180}
181/*-----------------------------------------------------------*/
182
183void vBasicStreamBufferSendFromISR( void )
184{
185static size_t xNextByteToSend = 0;
186const BaseType_t xCallsBetweenSends = 100, xBytesToSend = 4;
187static BaseType_t xCallCount = 0;
188
189/* Is it time to write to the stream buffer again? */
190xCallCount++;
191
192if( xCallCount > xCallsBetweenSends )
193{
194xCallCount = 0;
195
196/* Send the next four bytes to the stream buffer. */
197xStreamBufferSendFromISR( xStreamBuffer,
198( const void * ) ( pcStringToSend + xNextByteToSend ),
199xBytesToSend,
200NULL );
201
202/* Send the next four bytes the next time around, wrapping to the start
203* of the string if necessary. */
204xNextByteToSend += xBytesToSend;
205
206if( xNextByteToSend >= strlen( pcStringToSend ) )
207{
208xNextByteToSend = 0;
209}
210}
211}
212/*-----------------------------------------------------------*/
213
214BaseType_t xIsInterruptStreamBufferDemoStillRunning( void )
215{
216uint32_t ulLastCycleCount = 0;
217
218/* Check the demo is still running. */
219if( ulLastCycleCount == ulCycleCount )
220{
221xDemoStatus = pdFAIL;
222}
223else
224{
225ulLastCycleCount = ulCycleCount;
226}
227
228return xDemoStatus;
229}

2.2 阻塞讀取和觸發(fā)電平

xStreamBufferReceive()用于讀取來自 RTOS 任務(wù)的流緩沖區(qū)的數(shù)據(jù)。xStreamBufferReceiveFromISR())是 用于從中斷服務(wù)例程 (ISR) 從流緩沖區(qū)中讀取數(shù)據(jù)。

下面是這兩個函數(shù)的用法舉例:

1//1-xStreamBufferReceive()
 2void vAFunction( StreamBuffer_t xStreamBuffer )
 3{
 4uint8_t ucRxData[ 20 ];
 5size_t xReceivedBytes;
 6const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
 7
 8/* Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
 9Wait in the Blocked state (so not using any CPU processing time) for a
10maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
11available. */
12xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
13( void * ) ucRxData,
14sizeof( ucRxData ),
15xBlockTime );
16
17if( xReceivedBytes > 0 )
18{
19/* A ucRxData contains another xRecievedBytes bytes of data, which can
20be processed here.... */
21}
22}
23
242--xStreamBufferReceiveFromISR()
25
26/* A stream buffer that has already been created. */
27StreamBuffer_t xStreamBuffer;
28
29void vAnInterruptServiceRoutine( void )
30{
31uint8_t ucRxData[ 20 ];
32size_t xReceivedBytes;
33BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Initialised to pdFALSE. */
34
35/* Receive the next stream from the stream buffer. */
36xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
37( void * ) ucRxData,
38sizeof( ucRxData ),
39&xHigherPriorityTaskWoken );
40
41if( xReceivedBytes > 0 )
42{
43/* ucRxData contains xReceivedBytes read from the stream buffer.
44Process the stream here.... */
45}
46
47/* If xHigherPriorityTaskWoken was set to pdTRUE inside
48xStreamBufferReceiveFromISR() then a task that has a priority above the
49priority of the currently executing task was unblocked and a context
50switch should be performed to ensure the ISR returns to the unblocked
51task. In most FreeRTOS ports this is done by simply passing
52xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
53variables value, and perform the context switch if necessary. Check the
54documentation for the port in use for port specific instructions. */
55taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
56}

xStreamBufferReceive()允許指定阻塞時間如果任務(wù)使用xStreamBufferReceive()從一個空的流緩沖區(qū)中讀取數(shù)據(jù)時指定了一個非零的阻塞時間,那么任務(wù)將被放置到阻塞狀態(tài)(因此它不會消耗任何CPU時間,其他任務(wù)可以運行),直到流緩沖區(qū)中有指定數(shù)量的數(shù)據(jù)可用,或者塊時間到期。在等待數(shù)據(jù)的任務(wù)從阻塞狀態(tài)移除之前,流緩沖區(qū)中必須存在的數(shù)據(jù)量稱為流緩沖區(qū)的觸發(fā)級別。例如:

如果一個任務(wù)在讀取觸發(fā)級別為1的空流緩沖區(qū)時被阻塞,那么當向緩沖區(qū)寫入一個字節(jié)或任務(wù)的阻塞時間到期時,該任務(wù)將被解除阻塞。

如果一個任務(wù)在讀取觸發(fā)級別為10的空流緩沖區(qū)時被阻塞,那么該任務(wù)將不會被解除阻塞,直到流緩沖區(qū)包含至少10個字節(jié)或任務(wù)的阻塞時間到期。

如果讀取任務(wù)的阻塞時間在觸發(fā)級別到達之前超時,那么無論實際可用的字節(jié)數(shù)是多少,該任務(wù)仍然會接收到。

2.3 阻塞寫入

xStreamBufferSend())用于從RTOS任務(wù)向流緩沖區(qū)發(fā)送數(shù)據(jù)。xStreamBufferSendFromISR())用于從中斷服務(wù)例程(ISR)向流緩沖區(qū)發(fā)送數(shù)據(jù)。

如果任務(wù)使用xStreamBufferSend()向流緩沖區(qū)寫入數(shù)據(jù)時指定了一個非零的阻塞時間,那么該任務(wù)將被放置到阻塞狀態(tài)(因此它不會消耗任何CPU時間,其他任務(wù)可以運行),直到流緩沖區(qū)中有空間可用,或者阻塞時間到達。

2.4 發(fā)送和接收的回調(diào)

流和消息緩沖區(qū)在每次發(fā)送和接收操作完成后都會執(zhí)行一個回調(diào):

使用xStreamBufferCreate()和xMessageBufferCreate() API函數(shù)(以及它們靜態(tài)分配的等價函數(shù))創(chuàng)建的流和消息緩沖區(qū)共享相同的回調(diào)函數(shù),這些回調(diào)函數(shù)是使用sbSEND_COMPLETED()和sbRECEIVE_COMPLETED()宏定義的。

使用xStreamBufferCreateWithCallback()和xMessageBufferCreateWithCallback() API函數(shù)(以及它們靜態(tài)分配的等價函數(shù))創(chuàng)建的流緩沖區(qū)和消息緩沖區(qū)都可以有自己唯一的回調(diào)函數(shù)。

sbSEND_COMPLETED() (and sbSEND_COMPLETED_FROM_ISR())

sbSEND_COMPLETED()是一個宏,當數(shù)據(jù)寫入使用xStreamBufferCreate()或xStreamBufferCreateStatic() API創(chuàng)建的流緩沖區(qū)時,會調(diào)用該宏(在FreeRTOS API函數(shù)內(nèi)部)。它接受一個參數(shù),即更新后的流緩沖區(qū)句柄。

默認情況下(如果應(yīng)用程序編寫者沒有提供自己的宏實現(xiàn)),sbSEND_COMPLETED()會檢查是否有任務(wù)阻塞在流緩沖區(qū)上等待數(shù)據(jù),如果有,則從阻塞狀態(tài)中刪除該任務(wù)。

應(yīng)用程序編寫人員可以通過在FreeRTOSConfig.h中提供他們自己的sbSEND_COMPLETED()實現(xiàn)來改變這種默認行為。當使用流緩沖區(qū)在多核處理器的核之間傳遞數(shù)據(jù)時,這很有用。在這種情況下,可以實現(xiàn)sbSEND_COMPLETED()在另一個CPU核心中生成一個中斷,然后中斷的服務(wù)例程可以使用xStreamBufferSendCompletedFromISR() API函數(shù)來檢查(如果必要的話)等待數(shù)據(jù)的任務(wù)。

在FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c文件中有更詳細的應(yīng)用過程。有時間到時候會單獨的把FreeRTOS所有函數(shù)給介紹一下以及應(yīng)用。

sbRECEIVE_COMPLETED() (and sbRECEIVE_COMPLETED_FROM_ISR())

sbRECEIVE_COMPLETED()是與sbSEND_COMPLETED()等價的接收方。當從流緩沖區(qū)讀取數(shù)據(jù)時,它會被調(diào)用(在FreeRTOS API函數(shù)內(nèi)部)。默認情況下(如果應(yīng)用程序編寫人員沒有提供自己的宏實現(xiàn)),宏會檢查流緩沖區(qū)上是否有任務(wù)阻塞,以等待緩沖區(qū)內(nèi)的空間可用,如果有,則將該任務(wù)從阻塞狀態(tài)中移除。

與bSEND_COMPLETED()一樣,應(yīng)用程序編寫人員可以通過在FreeRTOSConfig.h(后續(xù)會單獨講述這個文件)中提供替代實現(xiàn)來更改sbRECEIVE_COMPLETED()的默認行為。如果你需要每個流緩沖區(qū)都有自己的“接收完成”行為,可以使用xStreamBufferCreateWithCallback()或xStreamBufferCreateStaticWithCallback() API函數(shù)來創(chuàng)建流緩沖區(qū)。

3-內(nèi)核到內(nèi)核

3.1 介紹

消息緩沖區(qū)允許不同字節(jié)的離散消息從中斷服務(wù)程序傳遞到一個進程,或從一個進程傳遞到另一個進程。例如,長度為10、20和123字節(jié)的消息都可以寫入和讀取到同一個消息緩沖區(qū)。與使用流緩沖區(qū)不同的是,10字節(jié)的消息只能作為10字節(jié)消息讀取,而不能作為單個字節(jié)讀取。消息緩沖區(qū)建立在流緩沖區(qū)之上(也就是說,它們使用流緩沖區(qū)的實現(xiàn))。

數(shù)據(jù)通過復(fù)制的方式通過消息緩沖區(qū)——發(fā)送方將數(shù)據(jù)復(fù)制到緩沖區(qū)中,讀取方將數(shù)據(jù)復(fù)制出緩沖區(qū)。

在文件目錄FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c下提供了一個從一個MCU到另一個MCU的數(shù)據(jù),可以看看。

3.2消息緩沖區(qū)大小

為了能讓消息緩沖區(qū)能夠處理不同字節(jié)的消息,每個消息的字節(jié)大小在消息之前寫入消息緩沖區(qū)(這在FreeRTOS API函數(shù)內(nèi)部發(fā)生)。字節(jié)長度保存在一個變量中,其類型由FreeRTOSConfig.h中的configMESSAGE_BUFFER_LENGTH_TYPE常數(shù)設(shè)置。

如果沒有額外的定義,configMESSAGE_BUFFER_LENGTH_TYPE默認為size_t類型,,size_t在32位體系結(jié)構(gòu)上通常是4字節(jié)。所以呢,當configMESSAGE_BUFFER_LENGTH_TYPE為4字節(jié)時,向緩沖區(qū)寫入一個10字節(jié)的消息,但是實際上占用的字節(jié)是超過10個字節(jié)的,實際上是占用了14個字節(jié)。同樣,把100個字節(jié)的消息寫入到緩沖區(qū),實際上占用104個字節(jié)空間。

3.3 阻塞的讀取和寫入

xMessageBufferReceive())是用來讀取任務(wù)消息緩沖區(qū)的數(shù)據(jù)的,xMessageBufferReceiveFromISR())是 用于從中斷服務(wù)程序 (ISR) 的消息緩沖區(qū)讀取數(shù)據(jù)。

用于從RTOS任務(wù)的消息緩沖區(qū)中讀取數(shù)據(jù)。用于從中斷服務(wù)例程(ISR)的消息緩沖區(qū)中讀取數(shù)據(jù)xMessageBufferSend()用于發(fā)送 數(shù)據(jù)從 RTOS 任務(wù)發(fā)送到消息緩沖區(qū)。xMessageBufferSendFromISR()是用于將數(shù)據(jù)從中斷服務(wù)程序 (ISR) 發(fā)送到消息緩沖區(qū)。

如果在任務(wù)中使用xMessageBufferReceive()說明了阻塞時間,從消息緩沖區(qū),而這個緩沖區(qū)剛好是空的,則這個函數(shù)置于阻塞狀態(tài)(因此它不會消耗任何CPU時間,其他任務(wù)可以運行),直到數(shù)據(jù)在消息緩沖區(qū)中可用,或阻塞時間到達。)

如果在任務(wù)中使用xMessageBufferSend()函數(shù)寫入到消息緩沖區(qū),這個緩沖區(qū)已經(jīng)滿了,則任務(wù)將會被置位到阻塞狀態(tài)(因此它不消耗任何 CPU 時間,并且可以運行其他任務(wù)) 直到消息緩沖區(qū)中有空間可用或阻塞時間結(jié)束。)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 緩沖區(qū)
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    9107
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4327

    瀏覽量

    62573
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    484

    瀏覽量

    62144
收藏 人收藏

    評論

    相關(guān)推薦

    基于C語言實現(xiàn)環(huán)形緩沖區(qū)/循環(huán)隊列

    這里分享一個自己用純C實現(xiàn)的環(huán)形緩沖區(qū)
    的頭像 發(fā)表于 04-11 10:39 ?3287次閱讀
    基于C語言<b class='flag-5'>實現(xiàn)</b>環(huán)形<b class='flag-5'>緩沖區(qū)</b>/循環(huán)隊列

    基于宏高效實現(xiàn)環(huán)形緩沖區(qū)教程

    來源 | 小麥大叔 循環(huán)緩沖區(qū)是嵌入式軟件工程師在日常開發(fā)過程中的關(guān)鍵組件。 多年來,互聯(lián)網(wǎng)上出現(xiàn)了許多不同的循環(huán)緩沖區(qū)實現(xiàn)和示例。我非常喜歡這個模塊,可以GitHub上找到這個開源的 CBUF.h
    的頭像 發(fā)表于 09-02 09:24 ?6730次閱讀
    基于宏高效<b class='flag-5'>實現(xiàn)</b>環(huán)形<b class='flag-5'>緩沖區(qū)</b>教程

    環(huán)形緩沖區(qū)簡介

    STM32串口數(shù)據(jù)接收 --環(huán)形緩沖區(qū)環(huán)形緩沖區(qū)簡介??在單片機中串口通信是我們使用最頻繁的,使用串口通信就會用到串口的數(shù)據(jù)接收與發(fā)送,環(huán)形緩沖區(qū)方式接收數(shù)據(jù)可以更好的保證數(shù)據(jù)丟幀率第
    發(fā)表于 08-17 06:56

    緩沖區(qū)溢出的危害及避免緩沖區(qū)溢出的三種方法

    1. 蠕蟲病毒簡介2. 緩沖區(qū)溢出3. 緩沖區(qū)溢出舉例4. 緩沖區(qū)溢出的危害5. 內(nèi)存在計算機中的排布方式6. 計算機中越界訪問的后果7. 避免緩沖
    發(fā)表于 03-02 07:55

    緩沖區(qū)溢出的危害及避免緩沖區(qū)溢出的三種方法

    1. 蠕蟲病毒簡介2. 緩沖區(qū)溢出3. 緩沖區(qū)溢出舉例4. 緩沖區(qū)溢出的危害5. 內(nèi)存在計算機中的排布方式6. 計算機中越界訪問的后果7. 避免緩沖
    發(fā)表于 03-30 14:01

    IOS NFC-TAP為什么不讀取FTM緩沖區(qū)

    大家好,我想使用 ST25DV 的 FTM 功能。我開發(fā)了代碼來寫入 FTM 的 EEPROM 和緩沖區(qū),我可以用開發(fā)的套件和 ST25PC-NFC 軟件讀取這個緩沖區(qū)。但我不能將 APP 用于 IOS NFC-TAP,因為它不讀取 FTM
    發(fā)表于 12-26 10:40

    環(huán)形緩沖區(qū)讀寫操作的分析與實現(xiàn)

    環(huán)形緩沖區(qū)是嵌入式系統(tǒng)中一種重要的常用數(shù)據(jù)結(jié)構(gòu)。在多任務(wù)環(huán)境下實現(xiàn)時,如果有多個讀寫任務(wù),一般需要用信號量來保護多個任務(wù)共享的環(huán)形緩沖區(qū)。但是如果只存在1 個讀
    發(fā)表于 04-15 11:35 ?40次下載

    環(huán)形緩沖區(qū)實現(xiàn)原理

    在通信程序中,經(jīng)常使用環(huán)形緩沖區(qū)作為數(shù)據(jù)結(jié)構(gòu)來存放通信中發(fā)送和接收的數(shù)據(jù)。環(huán)形緩沖區(qū)是一個先進先出的循環(huán)緩沖區(qū),可以向通信程序提供對緩沖區(qū)的互斥訪問。
    的頭像 發(fā)表于 03-22 10:03 ?7531次閱讀
    環(huán)形<b class='flag-5'>緩沖區(qū)</b>的<b class='flag-5'>實現(xiàn)</b>原理

    DN263-熱插拔和緩沖區(qū)I<sup>2</sup>C總線

    DN263-熱插拔和緩沖區(qū)I2C總線
    發(fā)表于 04-24 20:51 ?7次下載
    DN263-熱插拔<b class='flag-5'>和緩沖區(qū)</b>I<sup>2</sup>C總線

    緩沖區(qū)是啥意思 STM32串口數(shù)據(jù)接收之環(huán)形緩沖區(qū)

    緩沖區(qū)顧名思義是緩沖數(shù)據(jù)用的。實現(xiàn)緩沖區(qū)最簡單的辦法時,定義多個數(shù)組,接收一包數(shù)據(jù)到數(shù)組A,就把接收數(shù)據(jù)的地址換成數(shù)組B,每個數(shù)據(jù)有個標記字節(jié)用于表示這個數(shù)組是否收到數(shù)據(jù),收到數(shù)據(jù)是否
    的頭像 發(fā)表于 07-22 15:33 ?1.1w次閱讀

    STM32串口數(shù)據(jù)接收 --環(huán)形緩沖區(qū)

    STM32串口數(shù)據(jù)接收 --環(huán)形緩沖區(qū)環(huán)形緩沖區(qū)簡介??在單片機中串口通信是我們使用最頻繁的,使用串口通信就會用到串口的數(shù)據(jù)接收與發(fā)送,環(huán)形緩沖區(qū)方式接收數(shù)據(jù)可以更好的保證數(shù)據(jù)丟幀率第
    發(fā)表于 12-28 19:24 ?31次下載
    STM32串口數(shù)據(jù)接收 --環(huán)形<b class='flag-5'>緩沖區(qū)</b>

    環(huán)形緩沖區(qū)實現(xiàn)思路

    單片機程序開發(fā)一般都會用到UART串口通信,通過通信來實現(xiàn)上位機和單片機程序的數(shù)據(jù)交互。通信中為了實現(xiàn)正常的收發(fā),一般都會有對應(yīng)的發(fā)送和接收緩存來暫存通信數(shù)據(jù)。這里使用環(huán)形緩沖區(qū)的方式來設(shè)計數(shù)據(jù)收發(fā)的緩存,即
    的頭像 發(fā)表于 01-17 15:07 ?1632次閱讀

    STM32進階之串口環(huán)形緩沖區(qū)實現(xiàn)

    STM32進階之串口環(huán)形緩沖區(qū)實現(xiàn)
    的頭像 發(fā)表于 09-19 09:20 ?2288次閱讀
    STM32進階之串口環(huán)形<b class='flag-5'>緩沖區(qū)</b><b class='flag-5'>實現(xiàn)</b>

    C++環(huán)形緩沖區(qū)設(shè)計與實現(xiàn)

    的存儲空間。環(huán)形緩沖區(qū)的特點是其終點和起點是相連的,形成一個環(huán)狀結(jié)構(gòu)。這種數(shù)據(jù)結(jié)構(gòu)在處理數(shù)據(jù)和實現(xiàn)數(shù)據(jù)緩存等場景中具有廣泛的應(yīng)用。 環(huán)形緩沖區(qū)的主要作用是存儲和管理數(shù)據(jù)
    的頭像 發(fā)表于 11-09 11:21 ?2027次閱讀
    C++環(huán)形<b class='flag-5'>緩沖區(qū)</b>設(shè)計與<b class='flag-5'>實現(xiàn)</b>

    交換芯片緩沖區(qū)大小是什么

    交換芯片緩沖區(qū)大小并不一定是固定的。緩沖區(qū)的設(shè)計和實現(xiàn)會根據(jù)芯片的具體型號、規(guī)格以及應(yīng)用場景的不同而有所差異。一些交換芯片可能具有固定大小的緩沖區(qū),以滿足特定的性能需求或成本限制。然而
    的頭像 發(fā)表于 03-18 14:42 ?622次閱讀
    主站蜘蛛池模板: 国产又黄又硬又粗| 久久婷婷五月综合色丁香| 欧美 国产 日产 韩国 在线| 亚洲 欧美 国产 综合五月天| 97视频视频人人碰视频| 国产真实露脸乱子伦| 日韩精品久久久久影院| 最近中文字幕MV免费高清在线| 国产成人免费观看在线视频| 男人团apk| 亚洲一区二区免费看| 国产成人精品电影在线观看| 免费欧美大片| 亚洲人交性视频| 被两根巨大同时进去高H| 酒色.com| 亚洲精品午夜aaa级久久久久| qvod电影网站| 久久理论片| 亚洲 中文 自拍 无码| 俄罗斯aaaa一级毛片| 蜜芽手机在线观看| 在线播放午夜理论片| 国产亚洲精品香蕉视频播放| 日韩AV片无码一区二区三区不卡 | 久久九九精品国产自在现线拍| 无人区乱码区1卡2卡三卡在线| 阿力gv资源| 男人j进女人j一进一出| 伊人久久伊人| 好爽别插了无码视频| 亚洲 欧美 国产 在线 日韩| 高hnp全肉| 日本护士性生活| bl高h文合集| 毛片手机在线| 中国少妇内射XXXX狠干| 九九精彩视频在线观看视频| 亚洲2017天堂色无码| 国产精品爽爽久久久久久蜜桃| 色综合五月激情综合色一区|