韦老师提到的在fputc中不死等而是写入环形缓冲区的改进
我自己实现了一下,核心代码如下,但数据发送到一定量会卡住,无法继续发送
printf
,并且写入数据超过环形缓冲区大小时,会卡死,这种情况应该如何避免?关闭中断时system_tick中断也被关闭了,此时应该如何进行超时处理?txcplt_flag
static volatile int txcplt_flag = 0;
int fputc(int ch, FILE *p)
{
static RingBuffer_t rb;
if (!rb) {
rb = GetUsart1Rb();
}
// 如果环形缓冲区被写满,等环形缓冲区中的数据被发送完再写入数据
if (RingBufferFull(rb)) {
txcplt_flag = 0;
while (txcplt_flag == 0);
}
// 把要发送的数据写入环形缓冲区
RingBufferWrite(rb, (char *)&ch, sizeof(char));
// 如果没有开启发送中断,则开启发送中断
if ((__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_TXE)) == RESET) {
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
}
return ch;
}
void USART1_IRQHandler(void)
{
static RingBuffer_t rb;
char ch = 0;
if (!rb) {
rb = GetUsart1Rb();
}
if ((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE)) != RESET) {
RingBufferReadByte(rb, &ch, 1);
huart1.Instance->DR = ch;
// 当环形缓冲区中的数据全部都发送完成,关闭发送中断,并置位发送完成标志
if (RingBufferEmpty(rb)) {
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);
txcplt_flag = 1;
}
}
HAL_UART_IRQHandler(&huart1);
}