下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

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

中断驱动字符队列传输模式

[FreeRTOS-Plus-IO 传输模式]

数据方向

中断驱动的字符队列传输模式可以与 FreeRTOS_read() 和 FreeRTOS_write() 同时使用。


说明

ioconfigUSE_TX_CHAR_QUEUE 和/或 ioconfigUSE_RX_CHAR_QUEUE 必须 在 FreeRTOSIOConfig.h 中设置为 1, 字符队列传输模式才可分别可用于写入和读取。 此外, 其必须被明确启用于 相同配置文件中使用的 外围设备。

当字符队列传输模式选择为写入时,FreeRTOS_write() 不 直接写入外围设备。 相反,字节会被发送至 一传输队列。 外围设备的 中断服务程序从队列中删除字节, 并将其发送至外围设备。

当字符队列传输模式选择为读取时,FreeRTOS_read() 不 直接从外围设备读取字节,而是从接收队列读取, 接收队列接收到数据时,由 FreeRTOS-Plus-IO 中断服务程序进行填写。

中断服务程序和 FreeRTOS 队列 由 FreeRTOS-Plus-IO 代码实现,无需应用程序 编写器提供。

中断驱动字符队列传输模式
优点 缺点
  • 简单的使用模型
  • 可自动将调用任务设为 阻塞状态,以等待读取或写入操作 完成(在无法立即完成的情况下)。 这 确保了调用 FreeRTOS_read() 或 FreeRTOS_write() 的任务 仅在确有可执行的处理时使用 CPU 时间 。
  • 可以设置读取和/或写入超时值,以 确保 FreeRTOS_read() 和 FreeRTOS_write() 调用不会 无限期阻塞。
  • 由外围设备接收的字节会自动 缓冲而不会丢失,即使当 FreeRTOS_read() 操作在 接收到字节时未执行。
  • 可以随时调用 FreeRTOS_write()。 无需 等待先前的传输完成, 也无需等待外围设备空闲。
  • FreeRTOS-Plus-IO 驱动程序需要为队列提供 RAM。 队列长度由 用于选择传输模式的 FreeRTOS_ioctl() 调用的第三个参数配置。 。
  • 字符队列效率低下,因此应 仅限使用于无需 读取或写入大量数据的应用程序。 举个例子,字符队列提供了非常方便的 传输模式,用于命令行接口,其接收 字符的速度仅可达到人类打字 的速度。
  • FreeRTOS 队列具有内置的互斥 机制,但仅限于单个字符级别。 因而确保了队列数据结构体 在有两个任务同时试图 执行 FreeRTOS_write()(或 FreeRTOS_read()) 时不会损坏,但不能保证 在这种情况下数据不会交错。 应用程序编写者可以通过 使用任务优先级,或在必要时利用外部互斥(例如使用互斥锁)来防范这种可能性 。

在调用 FreeRTOS_ioctl() 时,可使用 ioctlUSE_CHARACTER_QUEUE_TX 和 ioctlUSE_CHARACTER_QUEUE_RX 请求代码 配置外围设备,令其 使用中断驱动字符队列分别进行写入和读取。 请注意,这些请求代码将导致外围设备 启用中断,并且将外围设备的中断优先级设置为 可能的最低值。 可以使用 ioctlSET_INTERRUPT_PRIORITY 请求代码 在必要时提高外围设备的优先级。


示例用法


/* FreeRTOS-Plus-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 recommended
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 interrupt driven character queues for both
reading and writing. The third FreeRTOS_ioctl() parameter sets the
queue length. In this example, the length is set to 20 in both cases.
A successful FreeRTOS_ioctl() call will return pdPASS, for simplicity,
this example does not show the return value being checked. */

FreeRTOS_ioctl( xOpenedPort, ioctlUSE_CHARACTER_QUEUE_RX, ( void * ) 20 );
FreeRTOS_ioctl( xOpenedPort, ioctlUSE_CHARACTER_QUEUE_TX, ( void * ) 20 );

/* By default, a peripheral configured to use an interrupt driven character
queue transfer will have an infinite block time. Lower the block time for
reading and writing to ensure FreeRTOS_read() and FreeRTOS_write() calls
will return, even in the presence of an error. In this example, both
the read and write block times are set to 100ms. Again, for simplicity,
this example does not show the return value being checked. */

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


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


for( ;; )
{
/* Write 10 bytes from ucBuffer to the opened port. Note the
definition of ucBuffer is assumed to be outside of this function. */

xBytesTransferred = FreeRTOS_write( xOpenedPort, ucBuffer, 10 );

/* At this point, 10 bytes will have been written to the Tx queue,
but not necessarily written to the peripheral yet. Check all 10 bytes
were written to the queue - they should have been as the queue is
20 bytes long. */

configASSERT( xBytesTransferred == 10 );

/* Read 10 bytes from the same port into ucBuffer. Note, this will
not read the bytes from the peripheral directly, but from the Rx
queue 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. */

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.