云途 串口发送阻塞与非阻塞API
GaoSheng Lv4

云途MCU串口数据发送常用的有两套API(其实有三套)

1
2
LINFlexD_UART_DRV_SendData
LINFlexD_UART_DRV_SendDataBlocking

下面简要说明一下带blocking的这个API,为了简明,我把API做了一下删减

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
status_t LINFlexD_UART_DRV_SendDataBlocking(uint32_t instance,
const uint8_t * txBuff,
uint32_t txSize,
uint32_t timeout)
{

linflexd_uart_state_t * uartState;
status_t retVal;

uartState = (linflexd_uart_state_t *)s_uartLINFlexDStatePtr[instance];
retVal = STATUS_SUCCESS;

/* Indicates this is a blocking transaction. */
uartState->isTxBlocking = true;
/* Reset signal before transfer */
//这里会尝试获取txcomplete信号量,
(void)OSIF_SemaWait(&(uartState->txComplete), 0);

/* Start the transmission process using DMA */
//真正发送数据的入口API
retVal = LINFlexD_UART_DRV_StartSendUsingDma(instance, txBuff, txSize);

if (retVal == STATUS_SUCCESS)
{
//等待信号量
/* Wait until to transmit is complete. */
retVal = OSIF_SemaWait(&uartState->txComplete, timeout);

/* Finish the transmission if timeout expired */
if (retVal == STATUS_TIMEOUT)
{
uartState->isTxBlocking = false;
uartState->transmitStatus = STATUS_TIMEOUT;

LINFlexD_UART_DRV_CompleteSendUsingDma(((void *)instance), DMA_CHN_NORMAL);

}
}

return retVal;
}

微信图片_20250317222408
在上面这个API中,发送完成后底层驱动会释放信号量txComplete(send前会尝试获取),一般用freertos的都建议用带block的API

补充:之前我在看关于串口回调函数事件的时候有一个点非常困惑,UART_EVENT_TX_EMPTY和UART_EVENT_END_TRANSFER难道不是一个事件吗?TX的fifo为空,应该是代表了传输完成;今天突然看到Linflexd_Uart_Continuous_Transmission_Demo例程才反应过来,tx fifo为空本次传输的的8个字节传输完成了。硬件已准备好接收下一个待发送的字节,一般用在逐字节流式传输。如果是整个传输任务(如多字节发送完成)此时触发的是UART_EVENT_END_TRANSFER事件

1
2
3
4
5
6
7
8
9
typedef enum
{
UART_EVENT_RX_FULL = 0x00U, /*!< Rx buffer is full */
UART_EVENT_TX_EMPTY = 0x01U, /*!< Tx buffer is empty */
UART_EVENT_END_TRANSFER = 0x02U, /*!< The current transfer is ending */
UART_EVENT_ERROR = 0x03U, /*!< An error occured during transfer */
UART_EVENT_TIMEOUT = 0x04U, /*!< Uart TimeOut */

} uart_event_t;

水平有限,有什么疏漏之处欢迎指问

本站由 提供部署服务