22-RTOS 流缓冲区 API 函数

简介: 22-RTOS 流缓冲区 API 函数

xStreamBufferCreate/xStreamBufferCreateWithCallback

stream_buffer.h

1StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes,
2size_t xTriggerLevelBytes );
3
4StreamBufferHandle_t xStreamBufferCreateWithCallback( 
5size_t xBufferSizeBytes,
6size_t xTriggerLevelBytes
7StreamBufferCallbackFunction_t pxSendCompletedCallback,
8StreamBufferCallbackFunction_t pxReceiveCompletedCallback );

创建一个使用动态分配内存的新流缓冲区。流缓冲区 在完成每个发送和接收操作时执行回调。使用 xStreamBufferCreate()API 创建的流缓冲区 共享相同的发送和接收完成回调函数,这些函数是用 sbSEND_COMPLETED() 和 sbRECEIVE_COMPLETED() 宏定义的 。使用 xStreamBufferCreateWithCallback() API 创建的流缓冲区可以有各自独特的发送和接收完成 回调函数。

configSUPPORT_DYNAMIC_ALLOCATION 必须 在 FreeRTOSConfig.h 中设置为 1 或未定义, xStreamBufferCreate () 才可用。此外,configUSE_SB_COMPLETED_CALLBACK 必须在 FreeRTOSConfig.h 中设置为 1,xStreamBufferCreateWithCallback() 才可用。

将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中即可启用流缓冲区功能。

  • 参数:
  • xBufferSizeBytes流缓冲区在任何时候能够容纳的总字节数。xTriggerLevelBytes在流缓冲区中被阻塞以等待数据的任务离开阻塞状态之前, 流缓冲区中必须包含的字节数。例如,如果一个任务在读取触发等级为 1 的空流缓冲区时被阻塞, 那么当单个字节写入缓冲区或该任务的阻塞时间结束时,该任务将被解除阻塞。另一个例子是,如果一个任务在读取触发等级为 10 的空流缓冲区时被阻塞, 那么直到流缓冲区至少包含 10 个字节或该任务的阻塞时间结束之前,该任务将不会被解除阻塞。如果 读任务的阻塞时间在达到触发等级之前过期,那么该任务仍将接收实际可用的字节数 。将触发等级设置为 0 将导致使用触发等级 1。指定 一个大于缓冲区大小的触发等级是无效的。pxSendCompletedCallback当对流缓冲区的数据写入导致缓冲区的字节数超过触发等级时调用的回调函数 。如果参数为 NULL,则使用 sbSEND_COMPLETED 宏所提供的默认实现 。发送完成的回调函数必须具有 StreamBufferCallbackFunction_t 定义的原型,即:
  • void vSendCallbackFunction( StreamBufferHandle_t xStreamBuffer,                            BaseType_t xIsInsideISR,                            BaseType_t * const pxHigherPriorityTaskWoken );
  • pxReceiveCompletedCallback当从流缓冲区读取数据(多于 0 字节)时调用的回调函数。如果参数为 NULL, 则使用 sbRECEIVE_COMPLETED 宏所提供的默认实现。接收完成回调函数必须 具有 StreamBufferCallbackFunction_t 定义的原型,即:
void vReceiveCallbackFunction( StreamBufferHandle_t xStreamBuffer,                               BaseType_t xIsInsideISR,                               BaseType_t * const pxHigherPriorityTaskWoken );
  • Returns:
  • 如果返回 NULL,则说明因为没有足够的堆内存可供 FreeRTOS 分配流缓冲区的数据结构体和存储区域,所以流缓冲区无法被创建。如果返回的值不是 NULL,则说明流缓冲区已经成功创建 ——返回值应该作为所创建流缓冲区的句柄来存储。
  • 用法示例:
1void vSendCallbackFunction(StreamBufferHandle_t xStreamBuffer,
 2BaseType_t xIsInsideISR,
 3BaseType_t *const pxHigherPriorityTaskWoken)
 4{
 5/* Insert code here which is invoked when a data write operation
 6* to the stream buffer causes the number of bytes in the buffer
 7* to be more then the trigger level.
 8* This is useful when a stream buffer is used to pass data between
 9* cores on a multicore processor. In that scenario, this callback
10* can be implemented to generate an interrupt in the other CPU core,
11* and the interrupt's service routine can then use the
12* xStreamBufferSendCompletedFromISR() API function to check, and if
13* necessary unblock, a task that was waiting for the data. */
14}
15
16void vReceiveCallbackFunction(StreamBufferHandle_t xStreamBuffer,
17BaseType_t xIsInsideISR,
18BaseType_t *const pxHigherPriorityTaskWoken)
19{
20/* Insert code here which is invoked when data is read from a stream
21* buffer.
22* This is useful when a stream buffer is used to pass data between
23* cores on a multicore processor. In that scenario, this callback
24* can be implemented to generate an interrupt in the other CPU core,
25* and the interrupt's service routine can then use the
26* xStreamBufferReceiveCompletedFromISR() API function to check, and if
27* necessary unblock, a task that was waiting to send the data. */
28}
29
30void vAFunction(void)
31{
32StreamBufferHandle_t xStreamBuffer, xStreamBufferWithCallback;
33const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
34
35/* Create a stream buffer that can hold 100 bytes and uses the
36* functions defined using the sbSEND_COMPLETED() and
37* sbRECEIVE_COMPLETED() macros as send and receive completed
38* callback functions. The memory used to hold both the stream
39* buffer structure and the data in the stream buffer is
40* allocated dynamically. */
41xStreamBuffer = xStreamBufferCreate(xStreamBufferSizeBytes,
42xTriggerLevel);
43if (xStreamBuffer == NULL)
44{
45/* There was not enough heap memory space available to create the
46stream buffer. */
47}
48else
49{
50/* The stream buffer was created successfully and can now be used. */
51}
52
53/* Create a stream buffer that can hold 100 bytes and uses the
54* functions vSendCallbackFunction and vReceiveCallbackFunction
55* as send and receive completed callback functions. The memory
56* used to hold both the stream buffer structure and the data
57* in the stream buffer is allocated dynamically. */
58xStreamBufferWithCallback = xStreamBufferCreateWithCallback(
59xStreamBufferSizeBytes,
60xTriggerLevel,
61vSendCallbackFunction,
62vReceiveCallbackFunction);
63if (xStreamBufferWithCallback == NULL)
64{
65/* There was not enough heap memory space available to create the
66* stream buffer. */
67}
68else
69{
70/* The stream buffer was created successfully and can now be used. */
71}
72}


xStreamBufferCreateStatic / xStreamBufferCreateStaticWithCallback

stream_buffer.h

1StreamBufferHandle_t xStreamBufferCreateStatic(
 2size_t xBufferSizeBytes,
 3size_t xTriggerLevelBytes,
 4uint8_t *pucStreamBufferStorageArea,
 5StaticStreamBuffer_t *pxStaticStreamBuffer );
 6
 7StreamBufferHandle_t xStreamBufferCreateStaticWithCallback(
 8size_t xBufferSizeBytes,
 9size_t xTriggerLevelBytes,
10uint8_t *pucStreamBufferStorageArea,
11StaticStreamBuffer_t *pxStaticStreamBuffer,
12StreamBufferCallbackFunction_t pxSendCompletedCallback,
13StreamBufferCallbackFunction_t pxReceiveCompletedCallback );


使用静态分配的内存创建一个新的流缓冲区。流缓冲区 在完成每个发送和接收操作时执行回调。使用 xStreamBufferCreateStatic() API 创建的流缓冲区 共享相同的发送和接收完成回调函数,这些函数是用 sbSEND_COMPLETED() 和 sbRECEIVE_COMPLETED() 宏定义的 。使用 xStreamBufferCreateStaticWithCallback() API 创建的流缓冲区可以有各自独特的发送和接收完成 回调函数。

configSUPPORT_STATIC_ALLOCATION 必须在 FreeRTOSConfig.h 中设置为 1, xStreamBufferCreateStatic() 才可用。此外,configUSE_SB_COMPLETED_CALLBACK 必须在 FreeRTOSConfig.h 中设置为 1,xStreamBufferCreateStaticWithCallback() 才可用。

将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中即可启用流缓冲区功能。

  • 参数:
  • xBufferSizeBytespucStreamBufferStorageArea 参数所指向的缓冲区的大小(单位:字节)。xTriggerLevelBytes在流缓冲区中被阻塞以等待数据的任务离开阻塞状态之前, 流缓冲区中必须存在的字节数。例如,如果一个任务在读取触发等级为 1 的空流缓冲区时被阻塞, 那么当单个字节写入缓冲区或该任务的阻塞时间结束时,该任务将被解除阻塞。另一个例子是,如果一个任务在读取触发等级为 10 的空流缓冲区时被阻塞, 那么直到流缓冲区至少包含 10 个字节或该任务的阻塞时间结束之前,该任务将不会被解除阻塞。如果 读取任务的阻塞时间在达到触发等级之前过期,那么该任务仍将接收实际可用的字节数 。将触发等级设置为 0 将导致使用触发等级 1。指定 一个大于缓冲区大小的触发等级是无效的。pucStreamBufferStorageArea必须指向一个大小至少为 xBufferSizeBytes + 1 的 uint8_t 数组。这是一个数组,当将流写入流缓冲区时, 流会被复制到这个数组中。pxStaticStreamBuffer必须指向一个 StaticStreamBuffer_t 类型的变量,它将用于保存流缓冲区的数据结构体。pxSendCompletedCallback当对流缓冲区的数据写入导致缓冲区的字节数超过触发等级时调用的回调函数 。如果参数为 NULL,则使用 sbSEND_COMPLETED 宏所提供的默认实现 。发送完成的回调函数必须具有 StreamBufferCallbackFunction_t 定义的原型,即:
    void vSendCallbackFunction( StreamBufferHandle_t xStreamBuffer,                            BaseType_t xIsInsideISR,                            BaseType_t * const pxHigherPriorityTaskWoken ); pxReceiveCompletedCallback当从流缓冲区读取数据(多于 0 字节)时调用的回调函数。如果参数为 NULL, 则使用 sbRECEIVE_COMPLETED 宏所提供的默认实现。接收完成回调函数必须 具有 StreamBufferCallbackFunction_t 定义的原型,即:
void vReceiveCallbackFunction( StreamBufferHandle_t xStreamBuffer,                               BaseType_t xIsInsideISR,                               BaseType_t * const pxHigherPriorityTaskWoken );
  • Returns:
  • 如果成功创建了流缓冲区,那么将返回一个所创建流缓冲区的句柄。如果 pucStreamBufferStorageArea 或 pxStaticstreamBuffer 为 NULL,则返回 NULL。
  • 用法示例:


1/* Used to dimension the array used to hold the streams. The available
 2* space will actually be one less than this, so 999. */
 3#define STORAGE_SIZE_BYTES 1000
 4
 5/* Defines the memory that will actually hold the streams within the
 6* stream buffer. */
 7static uint8_t ucStreamBufferStorage[STORAGE_SIZE_BYTES];
 8static uint8_t ucStreamBufferWithCallbackStorage[STORAGE_SIZE_BYTES];
 9
10/* The variable used to hold the stream buffer structure. */
11StaticStreamBuffer_t xStreamBufferStruct;
12StaticStreamBuffer_t xStreamBufferWithCallbackStruct;
13
14void vSendCallbackFunction(StreamBufferHandle_t xStreamBuffer,
15BaseType_t xIsInsideISR,
16BaseType_t *const pxHigherPriorityTaskWoken)
17{
18/* Insert code here which is invoked when a data write operation
19* to the stream buffer causes the number of bytes in the buffer
20* to be more then the trigger level.
21* This is useful when a stream buffer is used to pass data between
22* cores on a multicore processor. In that scenario, this callback
23* can be implemented to generate an interrupt in the other CPU core,
24* and the interrupt's service routine can then use the
25* xStreamBufferSendCompletedFromISR() API function to check, and if
26* necessary unblock, a task that was waiting for the data. */
27}
28
29void vReceiveCallbackFunction(StreamBufferHandle_t xStreamBuffer,
30BaseType_t xIsInsideISR,
31BaseType_t *const pxHigherPriorityTaskWoken)
32{
33/* Insert code here which is invoked when data is read from a stream
34* buffer.
35* This is useful when a stream buffer is used to pass data between
36* cores on a multicore processor. In that scenario, this callback
37* can be implemented to generate an interrupt in the other CPU core,
38* and the interrupt's service routine can then use the
39* xStreamBufferReceiveCompletedFromISR() API function to check, and if
40* necessary unblock, a task that was waiting to send the data. */
41}
42
43void MyFunction(void)
44{
45StreamBufferHandle_t xStreamBuffer, xStreamBufferWithCallback;
46const size_t xTriggerLevel = 1;
47
48/* Create a stream buffer that uses the functions defined
49* using the sbSEND_COMPLETED() and sbRECEIVE_COMPLETED()
50* macros as send and receive completed callback functions. */
51xStreamBuffer = xStreamBufferCreateStatic(sizeof(ucStreamBufferStorage),
52xTriggerLevel,
53ucStreamBufferStorage,
54&xStreamBufferStruct);
55
56/* Create a stream buffer that uses the functions
57* vSendCallbackFunction and vReceiveCallbackFunction as send
58* and receive completed callback functions. */
59xStreamBufferWithCallback = xStreamBufferCreateStaticWithCallback(
60sizeof(ucStreamBufferWithCallbackStorage),
61xTriggerLevel,
62ucStreamBufferWithCallbackStorage,
63&xStreamBufferWithCallbackStruct,
64vSendCallbackFunction,
65vReceiveCallbackFunction);
66
67/* As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
68* parameters were NULL, xStreamBuffer and xStreamBufferWithCallback
69* will not be NULL, and can be used to reference the created stream
70* buffers in other stream buffer API calls. */
71
72/* Other code that uses the stream buffers can go here. */


xStreamBufferSend()

  • stream_buffer.h
1size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
2const void *pvTxData,
3size_t xDataLengthBytes,
4TickType_t xTicksToWait );
  • 将字节发送到流缓冲区。字节复制到流缓冲区中。
  • 注意:在 FreeRTOS 对象中唯一的流缓冲区实现 (消息缓冲区实现也是如此,因为消息缓冲区构建在 假定只有一个任务或中断会写到 缓冲区(写入器),而且只有一个任务或中断会从 缓冲区(读取器)读取。写入器和读取器为不同的任务或中断是安全的, 或中断,但与其他 FreeRTOS 对象不同, 拥有多个不同的编写器或多个不同的读取器是不安全的。如果有 多个不同的写入器,那么应用程序写入器必须把对写入 API 函数(如 xStreamBufferSend())的每个调用放在一个临界区内, 并使用发送阻塞时间 0。同样,如果有多个不同的读取器, 那么应用程序必须把对读取 API 函数(如 xStreamBufferReceive())的每个调用放在一个临界区内, 并使用接收阻塞时间 0。
  • 使用 xStreamBufferSend() 从任务写入流缓冲区。使用 xStreamBufferSendFromSISR () 从 中断服务程序 (ISR) 写入流缓冲区。
  • 通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。
  • 参数:
  • xStreamBuffer 作为流发送目标缓冲区的流缓冲区的句柄 。pvTxData 一个指向缓冲区的指针, 该缓冲区用于保存要复制到流缓冲区的字节。xDataLengthBytes 从 pvTxData 复制到流缓冲区的最大字节数 。xTicksToWait 当流缓冲区的空间太小, 无法 容纳 另一个 xDataLengthBytes 的字节时,任务应保持在阻塞状态,以等待流缓冲区中出现足够空间的最长时间。阻塞时间的单位为 tick 周期, 因此,它代表的绝对时间取决于 tick 频率。宏 宏pdMS_TO_TICKS()可以用来将以毫秒为单位的时间 转换为以 tick 为单位的时间。将xTicksToWait设置为portMAX_DELAY会 导致任务无限期地等待(没有超时),前提是 INCLUDE_vTaskSuspend 在 FreeRTOSConfig.h 中设置为 1。如果一个任务 在向缓冲区写入所有 xDataLengthBytes 之前就超时, 它仍然会写入尽可能多的字节数。处于阻塞状态的任务不会使用任何 CPU 时间 。
  • 返回:
  • 写入流缓冲区的字节数。如果一个任务 在向缓冲区写入所有 xDataLengthBytes 之前就超时, 它仍然会写入尽可能多的字节数。
  • 用法示例:
1void vAFunction( StreamBufferHandle_t xStreamBuffer )
 2{
 3size_t xBytesSent;
 4uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
 5char *pcStringToSend = "String to send";
 6const TickType_t x100ms = pdMS_TO_TICKS( 100 );
 7
 8/* Send an array to the stream buffer, blocking for a maximum of 100ms to
 9wait for enough space to be available in the stream buffer. */
10xBytesSent = xStreamBufferSend( xStreamBuffer,
11( void * ) ucArrayToSend,
12sizeof( ucArrayToSend ),
13x100ms );
14
15if( xBytesSent != sizeof( ucArrayToSend ) )
16{
17/* The call to xStreamBufferSend() times out before there was enough
18space in the buffer for the data to be written, but it did
19successfully write xBytesSent bytes. */
20}
21
22/* Send the string to the stream buffer. Return immediately if there is not
23enough space in the buffer. */
24xBytesSent = xStreamBufferSend( xStreamBuffer,
25( void * ) pcStringToSend,
26strlen( pcStringToSend ), 0 );
27
28if( xBytesSent != strlen( pcStringToSend ) )
29{
30/* The entire string could not be added to the stream buffer because
31there was not enough free space in the buffer, but xBytesSent bytes
32were sent. Could try again to send the remaining bytes. */
33}
34}

xStreamBufferSendFromISR()

stream_buffer.h

1size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
2const void *pvTxData,
3size_t xDataLengthBytes,
4BaseType_t *pxHigherPriorityTaskWoken );


向 流缓冲区 发送字节流的中断安全版本 API 函数。

注意:与其他 FreeRTOS 对象都不同的是,流缓冲区的实现 (消息缓冲区的实现也是如此,因为消息缓冲区是建立在流缓冲区之上的) 流缓冲区的实现假定只有一个任务或中断将写入缓冲区(写入程序), 缓冲区(写入器),只有一个任务或中断会从 (读取程序)。写入和读取 不同的任务或中断是安全的,但与其他FreeRTOS对象不同, 有多个不同的写入或多个不同的读取是不安全的。如果 多个不同的写入器, 那么应用程序写入器必须把对写入 API 函数(如 xStreamBufferSend())的每个调用放在一个临界区内, 并使用发送阻塞时间 0。同样,如果有多个不同的读取器, 那么应用程序必须把对读取 API 函数(如 xStreamBufferReceive())的每个调用放在一个临界区内, 并使用接收阻塞时间 0。

使用 xStreamBufferSend() 从任务写入流缓冲区。使用 xStreamBufferSendFromSISR () 从 中断服务程序 (ISR) 写入流缓冲区。

通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。


  • 参数:
  • xStreamBuffer 作为流发送目标缓冲区的流缓冲区的句柄 。pvTxData 一个指向缓冲区的指针, 该缓冲区用于保存要复制到流缓冲区的字节。xDataLengthBytes 从 pvTxData 复制到流缓冲区的最大字节数 。pxHigherPriorityTaskWoken (这是一个可选参数,可以设置为 NULL。) 一个流缓冲区有可能会 有一个在其上阻塞的任务,以等待数据。调用 xStreamBufferSendFromISR() 可以使数据可用,进而导致正在等待数据的任务 离开阻塞状态。如果调用 xStreamBufferSendFromSISR() 导致任务离开阻塞状态,并且 未阻塞任务的优先级高于当前执行的任务( 被中断的任务),那么 xStreamBufferSendFromISR() 将在内部 把 *pxHigherPriorityTaskWoken 设置为 pdTRUE。如果 xStreamBufferSendFromSISR() 将此值设置为 pdTRUE,那么通常应在 退出中断之前执行上下文切换。这将 确保中断直接返回到最高优先级的“就绪” 状态任务。* pxHigherPriorityTaskWoken在传递给函数之前 应将其设置为 pdFALSE。有关示例,请参阅下面的示例代码。
  • Returns:
  • 写入流缓冲区的字节数。如果一个任务 在向缓冲区写入所有 xDataLengthBytes 之前就超时, 它仍然会写入尽可能多的字节数。

用法示例:


1/* A stream buffer that has already been created. */
 2StreamBufferHandle_t xStreamBuffer;
 3
 4void vAnInterruptServiceRoutine( void )
 5{
 6size_t xBytesSent;
 7char *pcStringToSend = "String to send";
 8BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Initialised to pdFALSE. */
 9
10/* Attempt to send the string to the stream buffer. */
11xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
12( void * ) pcStringToSend,
13strlen( pcStringToSend ),
14&xHigherPriorityTaskWoken );
15
16if( xBytesSent != strlen( pcStringToSend ) )
17{
18/* There was not enough free space in the stream buffer for the entire
19string to be written, ut xBytesSent bytes were written. */
20}
21
22/* If xHigherPriorityTaskWoken was set to pdTRUE inside
23xStreamBufferSendFromISR() then a task that has a priority above the
24priority of the currently executing task was unblocked and a context
25switch should be performed to ensure the ISR returns to the unblocked
26task. In most FreeRTOS ports this is done by simply passing
27xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
28variables value, and perform the context switch if necessary. Check the
29documentation for the port in use for port specific instructions. */
30taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
31}


xStreamBufferReceive()

stream_buffer.h

1size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
2void *pvRxData,
3size_t xBufferLengthBytes,
4TickType_t xTicksToWait );

从流缓冲区接收字节。

注意:与其他 FreeRTOS 对象都不同的是,流缓冲区的实现 (消息缓冲区的实现也是如此,因为消息缓冲区是建立在流缓冲区之上的) 流缓冲区的实现假定只有一个任务或中断将写入缓冲区(写入程序), 缓冲区(写入器),只有一个任务或中断会从 (读取程序)。写入和读取 不同的任务或中断是安全的,但与其他FreeRTOS对象不同, 有多个不同的写入或多个不同的读取是不安全的。如果 多个不同的写入器, 那么应用程序写入器必须把对写入 API 函数(如 xStreamBufferSend())的每个调用放在一个临界区内, 并使用发送阻塞时间 0。同样,如果有多个不同的读取器, 那么应用程序必须把对读取 API 函数(如 xStreamBufferReceive())的每个调用放在一个临界区内, 并使用接收阻塞时间 0。

使用 xStreamBufferReceive() 从任务的流缓冲区读取数据。使用 xStreamBufferReceiveFromISR() 从 中断服务程序 (ISR) 的流缓冲区读取数据。

通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 要接收字节来自的流缓冲区的句柄。pvRxData 指向缓冲区的指针,接收的字节将被复制到该缓冲区 。xBufferLengthBytes pvRxData 参数 所指向的缓冲区的长度。这会设置一次调用中 接收的最大字节数。xStreamBufferReceive 将返回尽可能多的字节数, 直到达到由 xBufferLengthBytes 设置的最大字节数为止。xTicksToWait 当流缓冲区为空时, 任务应保持在阻塞状态以等待数据的最长时间 。如果 xTicksToWait 为 0,xStreamBufferReceive() 将立即返回。阻塞时间的单位为 tick 周期, 因此,它代表的绝对时间取决于 tick 频率。宏 pdMS_TO_TICKS() 可以 用来将以毫秒为单位的时间转换成以 tick 为单位的时间 。将 xTicksToWait 设置为 portMAX_DELAY 将 将导致任务无限期等待(不超时),前提是 INCLUDE_vTaskSuspend 在 FreeRTOSConfig.h 中设置为 1。处于阻塞状态的任务不会使用任何 CPU 时间 。
  • Returns:
  • 从流缓冲区读取的字节数。这将为最多等于 xBufferLengthBytes 的可用字节数。例如:如果触发等级为 1 (触发等级是在创建流缓冲区时设置的)-如果 xBufferLengthBytes 为 10,且在调用 xStreamBufferReceive() 时,流缓冲区中包含 5 个字节,则 xStreamBufferReceive() 不会阻塞,从缓冲区中读取 5 个字节,并返回 5如果 xBufferLengthBytes 为 10,且在调用 xStreamBufferReceive() 时,流缓冲区中包含 50 个字节,则 xStreamBufferReceive() 不会阻塞,从缓冲区中读取 10 个字节,并返回 10。如果 xBufferLengthBytes 为 10,且在调用 xStreamBufferReceive() 时,流缓冲区中包含 0 个字节,xTicksToWait 为 100,并且在 50 个 tick 后缓冲区中收到 5 个字节,则 xStreamBufferReceive() 将进入为期 50 个 tick 的阻塞状态(直到数据到达缓冲区为止),之后它将从缓冲区中读取 5 个字节,并返回 5。如果 xBufferLengthBytes 为 10,且在调用 xStreamBufferReceive() 时,流缓冲区中包含 0 个字节,xTicksToWait 为 100,并且在 100 个 tick 内缓冲区中未收到字节,则 xStreamBufferReceive() 将进入为期 100 个 tick (完整阻塞时间)的阻塞状态,之后它将返回 0。如果触发等级为 6 -如果 xBufferLengthBytes 为 10,且在调用 xStreamBufferReceive() 时,流缓冲区中包含 0 个字节,xTicksToWait 为 100,并且在 50 个 tick 后缓冲区中收到 10 个字节,则 xStreamBufferReceive() 将进入为期 50 个 tick 的阻塞状态(直到至少有等于触发等级的字节数到达缓冲区为止),之后它将从缓冲区中读取 10 个字节,并返回 10。如果 xBufferLengthBytes 为 10,且在调用 xStreamBufferReceive() 时,流缓冲区中包含 0 个字节,xTicksToWait 为 100,并且在 50 个 tick 后缓冲区中收到 5 个字节,则 xStreamBufferReceive() 将在完整的 100 个 tick 阻塞周期内保持阻塞状态(因为缓冲区中的数据量永远无法达到触发等级),之后它将从缓冲区中读取 5 个字节,并返回 5。

用法示例:

1void vAFunction( StreamBuffer_t xStreamBuffer )
 2{
 3uint8_t ucRxData[ 20 ];
 4size_t xReceivedBytes;
 5const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
 6
 7/* Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
 8Wait in the Blocked state (so not using any CPU processing time) for a
 9maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
10available. */
11xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
12( void * ) ucRxData,
13sizeof( ucRxData ),
14xBlockTime );
15
16if( xReceivedBytes > 0 )
17{
18/* A ucRxData contains another xRecievedBytes bytes of data, which can
19be processed here.... */
20}
21}

xStreamBufferReceiveFromISR()

stream_buffer.h

1size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
2void *pvRxData,
3size_t xBufferLengthBytes,
4BaseType_t *pxHigherPriorityTaskWoken );

一个从 流缓冲区中接收字节的 API 函数的中断安全版本。

注意:与其他 FreeRTOS 对象都不同的是,流缓冲区的实现 (消息缓冲区的实现也是如此,因为消息缓冲区是建立在流缓冲区之上的) 流缓冲区的实现假定只有一个任务或中断将写入缓冲区(写入程序), 缓冲区(写入器),只有一个任务或中断会从 (读取程序)。写入和读取 不同的任务或中断是安全的,但与其他FreeRTOS对象不同, 有多个不同的写入或多个不同的读取是不安全的。如果 多个不同的写入器, 那么应用程序写入器必须把对写入 API 函数(如 xStreamBufferSend())的每个调用放在一个临界区内, 并使用发送阻塞时间 0。同样,如果有多个不同的读取器, 那么应用程序必须把对读取 API 函数(如 xStreamBufferReceive())的每个调用放在一个临界区内, 并使用接收阻塞时间 0。

使用 xStreamBufferReceive() 从任务的流缓冲区读取数据。使用 xStreamBufferReceiveFromISR() 从 中断服务程序 (ISR) 的流缓冲区读取数据。

通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 要接收字节来自的流缓冲区的句柄。pvRxData 指向缓冲区的指针,接收的字节将被复制到该缓冲区 。xBufferLengthBytes pvRxData 参数 所指向的缓冲区的长度。这会设置一次调用中 接收的最大字节数。xStreamBufferReceive 将返回尽可能多的字节数, 直到达到由 xBufferLengthBytes 设置的最大字节数为止。pxHigherPriorityTaskWoken (这是一个可选参数,可以设置为 NULL。) 一个流缓冲区有可能会 有一个任务阻塞在上面,等待空间可用。调用 xStreamBufferReceiveFromISR() 可以使空间可用,进而导致正在等待空间的任务 离开阻塞状态。如果调用 xStreamBufferReceiveFromISR() 导致任务离开阻塞状态,并且 未阻塞任务的优先级高于当前执行的任务 (被中断的任务),那么在内部, xStreamBufferReceiveFromISR() 将把 *pxHigherPriorityTaskWoken 设置为 pdTRUE。如果 xStreamBufferSendFromSISR() 将此值设置为 pdTRUE,那么通常应在 退出中断之前执行上下文切换。这将 确保中断直接返回到最高优先级的就绪状态 任务。* pxHigherPriorityTaskWoken在传递给函数之前 应该设置为pdFALSE。
  • Returns:
  • 从流缓冲区读取的字节数(如有)。

用法示例:

1/* A stream buffer that has already been created. */
 2StreamBuffer_t xStreamBuffer;
 3
 4void vAnInterruptServiceRoutine( void )
 5{
 6uint8_t ucRxData[ 20 ];
 7size_t xReceivedBytes;
 8BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Initialised to pdFALSE. */
 9
10/* Receive the next stream from the stream buffer. */
11xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
12( void * ) ucRxData,
13sizeof( ucRxData ),
14&xHigherPriorityTaskWoken );
15
16if( xReceivedBytes > 0 )
17{
18/* ucRxData contains xReceivedBytes read from the stream buffer.
19Process the stream here.... */
20}
21
22/* If xHigherPriorityTaskWoken was set to pdTRUE inside
23xStreamBufferReceiveFromISR() then a task that has a priority above the
24priority of the currently executing task was unblocked and a context
25switch should be performed to ensure the ISR returns to the unblocked
26task. In most FreeRTOS ports this is done by simply passing
27xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
28variables value, and perform the context switch if necessary. Check the
29documentation for the port in use for port specific instructions. */
30taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
31}


vStreamBufferDelete()

stream_buffer.h

1void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );

删除之前创建的流缓冲区 (通过调用 xStreamBufferCreate() 或 xStreamBufferCreateStatic() 创建)。如果使用动态内存(即由 xStreamBufferCreate())创建流缓冲区, 则会释放分配的内存。

删除流缓冲区后, 不得使用流缓冲区句柄。

将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中, 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 要删除的流缓冲区的句柄。


xStreamBufferBytesAvailable()

stream_buffer.h

1size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );

查询流缓冲区以查看它包含多少数据, 该值等于在流缓冲区为空之前 可以从流缓冲区读取的字节数。

将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 正在查询的流缓冲区的句柄。
  • Returns:
  • 在流缓冲区为空之前可从流缓冲区读取的 字节数。


xStreamBufferSpacesAvailable()

stream_buffer.h

1size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );

查询流缓冲区以查看有多少可用空间—— 等于在流缓冲区满之前可以向它发送的数据量 。

通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 正在被查询的流缓冲区的句柄。
  • Returns:
  • 在流缓冲区满之前, 可以写入流缓冲区的字节数。


xStreamBufferSetTriggerLevel()

stream_buffer.h

1BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
2size_t xTriggerLevel );

流缓冲区的触发等级是指在流缓冲区上被阻塞以等待数据的任务离开阻塞状态之前,流缓冲区中必须包含的字节数。例如,如果一个任务在读取触发等级为 1 的空流缓冲区时被阻塞,那么当单个字节写入缓冲区或该任务的阻塞时间到期时,该任务将被解除阻塞。另一个示例是,如果一个任务在读取触发等级为 10 的空流缓冲区时被阻塞,那么直到流缓冲区至少包含 10 个字节或该任务的阻塞时间结束,该任务才会被解除阻塞。如果读任务的阻塞时间在达到触发等级之前过期,那么该任务仍将接收实际可用的字节数。将触发等级设置为 0 将导致使用触发等级 1。指定大于缓冲区大小的触发等级是无效的。

触发等级在创建流缓冲区时设置,可使用 xStreamBufferSetTriggerLevel() 进行修改。

将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 正在更新的流缓冲区的句柄。xTriggerLevel 流缓冲区的新触发等级。
  • Returns:
  • 如果 xTriggerLevel 小于或等于流缓冲区的长度,将更新触发等级并返回 pdTRUE。否则,返回 pdFALSE。


xStreamBufferReset()

stream_buffer.h

1BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );

将流缓冲区重置为其初始空状态。任何在流缓冲区的数据 都将被丢弃。只有当没有任务被阻塞以等待向流缓冲区发送或从流缓冲区接收时, 流缓冲区才能被重置 。

通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 正在重置的流缓冲区的句柄。
  • Returns:
  • 如果流缓冲区重置,则返回 pdPASS。如果有 一个任务被阻塞,等待向流缓冲区发送或从流缓冲区读取, 那么流缓冲区将不会被重置,并返回 pdFAIL。


xStreamBufferIsEmpty()

stream_buffer.h

1BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );

查询流缓冲区以查看其是否为空。如果流缓冲区不包含任何数据,则为空。

通过将源文件 FreeRTOS/source/stream_buffer.c包括在内,启用流缓冲区功能 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 正在查询的流缓冲区的句柄。
  • 返回:
  • 如果流缓冲区为空,则返回 pdTRUE。否则 返回 pdFALSE。


xStreamBufferIsFull()

stream_buffer.h

BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );

查询流缓冲区以查看其是否已满。如果一个流缓冲区没有任何可用空间,则该流缓冲区已满,因此无法 接受任何更多数据。

通过将 FreeRTOS/source/stream_buffer.c 源文件纳入构建中, 即可启用流缓冲区功能。

  • 参数:
  • xStreamBuffer 正在被查询的流缓冲区的句柄。
  • Returns:
  • 如果流缓冲区已满,则返回 pdTRUE。否则 返回 pdFALSE。
相关文章
|
6月前
|
存储 JavaScript API
活用 Composition API 核心函数,打造卓越应用(上)
活用 Composition API 核心函数,打造卓越应用(上)
|
6月前
|
缓存 JavaScript 算法
活用 Composition API 核心函数,打造卓越应用(下)
活用 Composition API 核心函数,打造卓越应用(下)
|
2月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
3月前
|
JSON 前端开发 API
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
|
2月前
|
存储 程序员 API
【收藏】非API函数检测操作系统类型
【收藏】非API函数检测操作系统类型
|
6月前
|
人工智能 关系型数据库 Serverless
Serverless 应用引擎常见问题之API生成的函数镜像改为自定义的镜像如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
|
3月前
|
Linux API
Linux源码阅读笔记07-进程管理4大常用API函数
Linux源码阅读笔记07-进程管理4大常用API函数
|
3月前
|
API 开发工具 图形学
PicoVR Unity SDK⭐️五、常用API接口函数一览
PicoVR Unity SDK⭐️五、常用API接口函数一览
|
4月前
|
API 运维
开发与运维函数问题之filter操作符在Gather API中的实现方式如何解决
开发与运维函数问题之filter操作符在Gather API中的实现方式如何解决
24 1
|
4月前
|
API 运维
开发与运维函数问题之Gather API与Stream Collector的区别如何解决
开发与运维函数问题之Gather API与Stream Collector的区别如何解决
30 1
下一篇
无影云桌面