下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

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

FreeRTOS_write()

[FreeRTOS-Plus-IO API]

FreeRTOS_IO.h
size_t FreeRTOS_write( Peripheral_Descriptor_t const pxPeripheral, 
                       const void *pvBuffer, 
                       const size_t xBytes );
		

将一个或多个字节写入打开的外围设备。

板级支持包 明确规定了可以打开的外围设备。 FreeRTOS_ioctl() 用于在中断驱动模式和轮询写入模式之间进行选择。

参数:

pxPeripheral   与正在写入字节的 外围设备相关联的描述符。 描述符将 从用于开启外围设备的 FreeRTOS_open() 调用中返回。
pvBuffer   指向待写入数据的第一个字节的指针。
xBytes   待写入的字节总数。

当使用中断驱动传输模式时, 如果并非所有字节都能在外围设备的写入超时到期前写入, 则写入外围设备的实际字节数 可能小于请求的 字节数。 FreeRTOS_ioctl() 用于 设置写入超时值。

返回:

使用轮询传输模式时, 返回值为 实际写入外围设备的总字节数。 假定未发生错误, 这就是所请求的总字节数。

使用中断驱动字符队列传输模式 时, 返回值为实际写入写队列的 总字节数。 如果队列中 没有足够空间用于立即写入所有待写字节, 并且外围设备的写入超时 在获取到足够空间之前已过期,则这将小于请求的字节数。 实际数据传输 由 FreeRTOS-Plus-IO 中断服务程序控制, 返回对 FreeRTOS_write() 的调用后即可完成。

使用中断驱动时零拷贝传输模式时, 则:

  • 如果调用 FreeRTOS_write() 的任务保存了写互斥锁 则返回值为待传输的总字节数, 此时假定未发生错误。 实际数据传输 由FreeRTOS-Plus-IO 中断服务程序控制, 返回对 FreeRTOS_write() 的调用后即可完成。

  • 如果调用 FreeRTOS_write() 的任务未保存写 互斥锁,或者如果 FreeRTOSIO Config.h 未配置为包括 外围设备的零拷贝写入传输模式, 则返回零。

FreeRTOS_ioctl() 用于设置 写入超时值。


用法示例:

示例 1 的代码片段展示了当外围设备 被配置为使用轮询传输模式时,应如何进行读取操作。 打开外围设备时 默认采用轮询模式。


/* By default the port is opened in polled mode. Write some bytes in polled
mode. */

xBytesWritten = FreeRTOS_write( xPort, ucBuffer, sizeof( ucBuffer ) );

/* The port is currently in polled mode, so FreeRTOS_write() will only have
returned once all the requested bytes had been written (barring any errors on
the peripheral). Note that because polling mode is being used, the task
making the FreeRTOS_write() call will not have entered the Blocked
state during the write process. The bytes written to the peripheral come from
the ucBuffer buffer. */

configASSERT( xBytes == sizeof( ucBuffer ) );

Example 1: Writing bytes to a peripheral that is configured to use the polled transfer mode.


示例 2 的代码片段展示了当外围设备 被配置为使用中断驱动的字符队列传输模式时如何执行写入。 在此模式下,执行 FreeRTOS_write() 调用的任务会保持在 已阻塞状态(不占用任何 CPU 时间) ,直到请求的所有字节数 均已发送到队列,或者写入超时到期。 FreeRTOS_ioctl() 与 ioctlSET_TX_TIMEOUT 请求代码一起用于配置写入超时, ioctlWAIT_PREVIOUS_WRITE_COMPLETE 请求代码 等待写队列为空。

    
/* Write some bytes in interrupt driven character queue Tx mode. */
xBytesWritten = FreeRTOS_write( xPort, ucBuffer, sizeof( ucBuffer ) );

if( xBytesWritten < sizeof( ucBuffer ) )
{
/* The Tx timeout must have expired before sizeof( ucBuffer ) bytes could
be written to the write queue. */

}
else
{
/* The requested number of bytes were sent to the write queue before
the write timeout expired. */

}

Example 2: Writing bytes to a peripheral that is configured to use the interrupt

driven character queue transfer mode.


示例 3 的代码片段展示了当外围设备 被配置为使用中断驱动的零拷贝传输模式时如何执行写入。 在此模式下,执行 FreeRTOS_write() 调用的任务始终会 立即返回。 如果返回值等于待写入字节数, 则 FreeRTOS_write() 调用成功启动了 中断驱动的传输。 如果返回值为零,则 FreeRTOS_write() 调用无法启动传输, 因为它没有保存写互斥锁,或者 FreeRTOSIO Config.h 的配置不支持。

    
/* As zero copy Tx is being used, a mutex must be obtained before a write can
be requested. This call requests the mutex, and will wait a maximum of 50
milliseconds for the mutex to be obtained. FreeRTOS_ioctl() will return pdPASS
or pdFAIL. */

xMutexObtained = FreeRTOS_ioctl( xPort,
ioctlOBTAIN_WRITE_MUTEX,
( void * ) ( 50 / portTICK_PERIOD_MS ) );

if( xMutexObtained != pdFAIL )
{
/* The mutex was obtained, so a write can be performed. This
time bytes are written directly from ucBuffer. */

xBytesWritten = FreeRTOS_write( xPort, ucBuffer, sizeof( ucBuffer ) );

/* Interrupt driven zero copy Tx is being used, so FreeRTOS_write() should
return the number of requested bytes, even though the FreeRTOS-Plus-IO interrupt
service routine might still be sending the data. */

configASSERT( xBytesWritten == sizeof( ucBuffer ) );

/* The mutex will only be available again after all the data has been
transmitted by the peripheral. Attempting to obtain the mutex again is therefore
a good way of knowing when all the data has been sent, and when the buffer being
written can be updated without corrupting the data transmission. The FreeRTOS_ioctl()
ioctlWAIT_PREVIOUS_WRITE_COMPLETE and ioctlOBTAIN_WRITE_MUTEX can both
be used for this purpose - the difference between the two being that
ioctlWAIT_PREVIOUS_WRITE_COMPLETE will not result in the calling task holding
the mutex if the FreeRTOS_ioctl() call is successful. */

xMutexObtained = FreeRTOS_ioctl( xPort,
ioctlOBTAIN_WRITE_MUTEX,
( void * ) ( 50 / portTICK_PERIOD_MS ) );
/* Or xMutexObtained = FreeRTOS_ioctl( xPort,
ioctlWAIT_PREVIOUS_WRITE_COMPLETE,
( void * ) ( 50 / portTICK_PERIOD_MS ) ); */


if( xMutexObtained != pdFAIL )
{
/* If another write is going to be performed, it can be performed now,
as the write mutex is already held. If a write is not going to be
performed, and another task uses the same peripheral, then the mutex
should be returned, and ioctlWAIT_PREVIOUS_WRITE_COMPLETE would have been
a better request code to use. The second parameter is not used in the
following call. */

FreeRTOS_ioctl( xPort, ioctlRELEASE_WRITE_MUTEX, NULL );
}
}

Example 3: Writing bytes to a peripheral that is configured to use the interrupt

driven zero copy transfer mode.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.