Reatek RL8710bn串口收发处理框架

时间:2021-03-07 19:48:46

串口收发处理框架(基于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 处理串口写操作。

 

 

二. 程序逻辑流程图

 

Reatek RL8710bn串口收发处理框架