对串口接收FIFO处理机制的解读
内容提要
FIFO队列是一种常见的队列数据结构,主要用于不同时钟域之间的数据传输。它的作用是作为一个缓冲区,在数据传输过程中防止数据丢失,并且可以减少频繁的总线操作。FIFO队列的处理机制包括初始化FIFO、获取数据长度、进出处理、置位记录量等。同时,文章还介绍了UART串口的处理机制和相关函数的使用。
延伸解读
两种FIFO实现方式的对比
文章展示了两种FIFO处理机制:第一种是通用FIFO结构体,使用uint32_t类型的in和out计数,通过取模运算实现环形缓冲;第二种是专门为UART设计的结构体,包含发送和接收缓冲区,使用读写指针和计数变量,并集成了回调函数。第一种更简洁,但计数类型可能溢出;第二种更贴近实际串口驱动,支持非阻塞传输和RS485控制。读者可根据应用场景选择或借鉴。
回调函数在串口驱动中的作用
文章解释了回调函数是通过函数指针调用的函数,并区分了指针函数和函数指针。在UART驱动中,回调函数用于处理特定事件,例如接收新数据时调用ReciveNew,发送完成时调用SendOver(常用于RS485切换方向)。这种设计将硬件中断与上层应用解耦,提高代码可维护性。但需注意回调函数应尽量简短,避免阻塞中断。
中断服务程序中的关键处理逻辑
文章详细描述了UART中断服务程序的处理顺序:读取中断标志,处理接收中断(将数据存入接收FIFO并更新写指针和计数),处理发送缓冲区空中断(从发送FIFO取数据写入TDR,并在数据取完时切换中断使能),以及处理发送完成中断(调用SendOver回调并清除Sending标志)。这些逻辑确保了数据非阻塞传输,但需注意临界区保护,例如在读写共享变量时禁用中断。
FIFO计数溢出的潜在风险
文章指出第一种FIFO机制使用uint32_t类型记录输入和输出计数,在极端情况下可能超出数据极限导致通信异常。虽然该类型极限较大,但长期运行或高速数据流下仍可能发生。第二种机制使用uint16_t计数,同样存在溢出可能,但通过环形缓冲和计数变量管理,风险相对可控。开发者应根据数据速率和运行时间评估计数类型是否足够,必要时使用更大类型或定期清零。
Q&A
串口接收FIFO的主要作用是什么?
FIFO作为缓冲区,用于不同时钟域之间的数据传输,防止数据丢失,并减少频繁的总线操作,也适合支持DMA操作。
FIFO的宽度和深度分别指什么?
宽度指一次读写操作的数据位数;深度表示FIFO队列可以存储多少个宽度的数据。例如深度为8的FIFO可以存储8个16位宽度的数据。
如何计算FIFO中当前已存储的数据长度?
已存储的数据长度等于输入计数减去输出计数(p->in - p->out)。
UART串口中断服务程序如何处理接收到的数据?
在USART1_IRQHandler中调用UartIRQ,当接收到数据时,从数据寄存器读取字节存入接收FIFO,更新写指针和计数,并调用ReciveNew回调函数通知应用程序。
什么是回调函数?在UART中有什么用途?
回调函数是通过函数指针调用的函数。在UART中,用于处理特定事件,如发送前/后切换RS485模式、接收到新数据时通知应用层。
串口发送数据时如何实现非阻塞传输?
发送数据时,将数据填入发送FIFO缓冲区后立即返回,由中断服务程序在后台完成发送。例如comSendBuf调用UartSend将数据放入缓冲区并启动发送中断。