下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

中断驱动的循环缓冲区传输模式

[FreeRTOS-Plus-IO 传输模式]

数据方向

中断驱动的循环缓冲区传输模式可与 FreeRTOS_read() 同时使用。


说明

ioconfigUSE_CIRCULAR_BUFFER_RX 须 在 FreeRTOSIOConfig.h 中设置为 1 才能 使用循环缓冲区传输模式。 此外,还须 其必须被明确启用于 相同配置文件中使用的 显式启用。

选择循环缓冲区传输模式时,FreeRTOS_read() 不会 直接从外设读取字节, 而是从 FreeRTOS-Plus-IO 中断服务程序在接收数据时填充的循环缓冲区读取字节。

中断服务程序和 FreeRTOS 循环缓冲区 由 FreeRTOS-Plus-IO 代码提供,无需由 应用程序编写者提供。

中断驱动的循环缓冲区传输模式
优点 缺点
  • 简单的使用模型
  • 可自动将调用任务设为 阻塞 状态,以等待读取或写入操作 完成(在无法立即完成的情况下)。 这 确保了调用 FreeRTOS_read() 的任务 仅在循环缓冲区中有字节时 占用 CPU 时间。
  • 可以设置读取超时值,以 确保 FreeRTOS_READ() 调用不会无限期阻塞。
  • 使用简单的 RAM 缓冲区,从而 产生了一种中等效率的接收方法, 尽管需要在缓冲区来回复制。
  • 由外设接收的字节会自动 缓冲而不会丢失,即使 FreeRTOS_read() 操作在 接收到字节时 未执行。
  • FreeRTOS-Plus-IO 驱动程序需要为循环缓冲区提供 RAM 。 缓冲区长度 由用于选择传输模式 的 FreeRTOS_ioctl() 调用 的第三个参数配置。

在对 FreeRTOS_ioctl() 的调用中使用 ioctlUSE_CIRCULAR_BUFFER_RX 请求代码, 以将外设配置为 使用中断驱动的循环缓冲区传输模式进行读取。 请注意,此请求代码将导致外设 中断被启用,且外围设备的中断优先级被设置为 可能的最低值。 可以使用 ioctlSET_INTERRUPT_PRIORITY 请求代码 在必要时提高外围设备的优先级。


示例用法


/* FreeRTO+IO includes. */
#include "FreeRTOS_IO.h"

void vAFunction( void )
{
/* The Peripheral_Descriptor_t type is the FreeRTOS-Plus-IO equivalent of a descriptor. */
Peripheral_Descriptor_t xOpenedPort;
BaseType_t xReturned;
const uint32_t ulMaxBlock100ms = ( 100UL / portTICK_PERIOD_MS );

/* Open the SPI port identified in the board support package as using the
path string "/SPI2/". The second parameter is not currently used and can
be set to anything, although, for future compatibility, it is recommneded
that it is set to NULL. */

xOpenedPort = FreeRTOS_open( "/SPI2/", NULL );

if( xOpenedPort != NULL )
{
/***************** Configure the port *********************************/

/* xOpenedPort now contains a valid descriptor that can be used with
other FreeRTOS-Plus-IO API functions.

Peripherals default to using Polled mode for both reads and writes.
Change from the default to use the interrupt driven circular buffer
transfer mode for reading. The third FreeRTOS_ioctl() parameter sets the
buffer length. In this example, the length is set to 20. A successful
FreeRTOS_ioctl() call will return pdPASS, for simplicity, this example
does not show the return value being checked. */

FreeRTOS_ioctl( xOpenedPort, ioctlUSE_CIRCULAR_BUFFER_RX, ( void * ) 20 );

/* By default, a peripheral configured to use an interrupt driven circual
buffer transfer will have an infinite block time. Lower the block time
to ensure FreeRTOS_read() calls will return, even in the presense of an
error. In this example the read block time is set to 100ms. Again, for
simplicity, this example does not show the return value being checked. */

FreeRTOS_ioctl( xOpenedPort, ioctlSET_RX_TIMEOUT, ( void * ) ulMaxBlock100ms );


/***************** Use the port ***************************************/


for( ;; )
{
/* Read 10 bytes from the port into ucBuffer. Note, this will
not read the bytes from the peripheral directly, but from the circular
buffer that is populated by the FreeRTOS-Plus-IO peripheral interrupt service
routine. The calling task is held in the Blocked state to wait
for 10 bytes to become available if they are not available immediately,
but the task will not be held in the Blocked state for more than 100ms.
ucBuffer is assumed to be defined outside of this function. */

xBytesTransferred = FreeRTOS_read( xOpenedPort, ucBuffer, 10 );

if( xBytesTransferred == 10 )
{
/* Ten bytes were read from the peripheral before the 100ms block
time expired. */

}
else
{
/* The block time must have expired before ten bytes could be
read from the peripheral. xBytesTransferred could be any value
from 0 to 9. */

}
}
}
else
{
/* The port was not opened successfully. */
}
}

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.