Realtek RL8710bn串口收发处理框架

串口收发处理框架(基于sdk-ameba-v4.0c_180328)
勤基科技 凌秋明

一.包括如下处理函数:

(1)static void uart_irq(uint32_t id, SerialIrq event)该函数主要处理串口有数据产生中断时调用,主要实现:获取收到的字符,并存储到 u->recv_buf 接收buffer 中;当u->recv_buf满时,u->prxwrite 会重新从头部开始写入,并置标志位u->rxoverlap 为 1,表示buffer处于满状态。如果u->prxwrite 大于 u->prxread 的时候,证明已经覆盖旧的未读数据,这时需要 u->prxread = u->prxwrite;。更新超时tick , u->last_update(主要为了记录超出定义的接收时间,视为接收完毕)。

(2)static void uart_send_stream_done(uint32_t id)该函数,串口数据发送完毕时调用,主要实现:清除发送buffer;释放发送相关的block信号量(u->tx_sema ,u->dma_tx_sema)。

(3)static int uart_send_stream(uart_socket_t u, char pbuf, int len)该函数发送串口数据流时调用,主要实现:获取发送信号量u->dma_tx_sema (主要保护正在发送的数据,使之完全发送后再释放信号量u->dma_tx_sema );发送串口数据流serial_send_stream_dma();

(4)static s32 uart_wait_rx_complete(uart_socket_t *u) 该函数接收完毕等待超时,主要实现:当前tick_current与自从接收到数据的u->last_update tick数做比较,达到超出自定义时间值后退出。

(5)static void uart_action_handler(void* param)该函数处理串口数据收发逻辑,主要实现:当获取到u->action_sema信号量的时候,表示有串口数据需要处理,u->rx_start当此变量置1,表示有串口数据需要接收,并置FD_ISSET为真以及ublock select 函数,在应用线程循环里处理接收数据。u->tx_start当此变量置1,表示有串口数据需要发送,调用uart_send_stream 函数进行发送。

(6)uart_socket_t* uart_open(uart_set_str *puartpara)该函数打开串口数据通道,主要实现:串口初始化:/*initial uart /
serial_init(&u->sobj, uart_tx,uart_rx);
serial_baud(&u->sobj,puartpara->BaudRate);
serial_format(&u->sobj, puartpara->number, (SerialParity)puartpara->parity, puartpara->StopBits);串口中断回调注册初始化:/uart irq handle/
serial_irq_handler(&u->sobj, uart_irq, (int)u);
serial_irq_set(&u->sobj, RxIrq, 1);
serial_irq_set(&u->sobj, TxIrq, 1);串口发送完毕回调注册:serial_send_comp_handler(&u->sobj, (void
)uart_send_stream_done, (uint32_t)u);分配串口socket 句柄,主要是为FD_ISSET ,select函数服务:/alloc a socket/
u->fd = lwip_allocsocketsd();初始化串口处理相关信号量:/init uart related semaphore/
rtw_init_sema(&u->action_sema, 0);//串口收发信号量
rtw_init_sema(&u->tx_sema, 1);//串口发送信号量
rtw_init_sema(&u->dma_tx_sema, 1);//DMA数据发送信号量

(7) int uart_close(uart_socket_t u)释放uart_socket: / Close uart socket /
if(lwip_close(u->fd) == -1)
{
uart_printf("%s(): close uart failed!", func);
}
/
Delete uart_action task /
u->fd = -1;释放信号量:rtw_up_sema(&u->action_sema);
rtw_msleep_os(20);

/
Free uart related semaphore /
rtw_free_sema(&u->action_sema);
rtw_free_sema(&u->tx_sema);
rtw_free_sema(&u->dma_tx_sema);释放串口结构体相关的内存资源:/
Free serial */
serial_free(&u->sobj);
rtw_mfree((u8 *)u, sizeof(uart_socket_t));

(8)int uart_read(uart_socket_t *u, void *read_buf, size_t size)根据写(u->prxread)和读(u->prxread)的index,以及溢出的标志位u->rxoverlap 判断 u->recv_buf 当前需要读取的数据,读取的大小由 size 决定。把需要的数据都出来后,清空socket select事件,并把读( u->prxread )的index 重新更新。lwip_setsockrcvevent(u->fd, 0);

if((pread_local + read_bytes) >= UART_RECV_BUFFER_LEN){ //update pread
u->prxread = (pread_local + read_bytes) - UART_RECV_BUFFER_LEN;
u->rxoverlap = 0; //clean overlap flags
} else
u->prxread = pread_local + read_bytes;

(9)int uart_write(uart_socket_t *u, void *pbuf, size_t size)获取信号锁rtw_down_sema(&u->tx_sema) ,并释放收发处理线程信号锁rtw_up_sema(&u->action_sema); 让uart_action_handler 处理串口写操作。

二. 程序逻辑流程图
Realtek RL8710bn串口收发处理框架
Realtek技术讨论,QQ群871600668