遇到的问题
RS485在收发过程中,一旦close()后,重新open(),无法读写,必须设备发送一次消息才能正常恢复串口读写。
例如:使用modbus_close(ctx);之后必须执行modbus_send_raw_data(ctx,"test",4);
串口才能正常。否则设备串口将一直处于发送状态而无法接收数据。
初步判断
经调试,判断是在关闭串口后发送标志位没有清空。导致重新打开串口后,uart_tx_stopped()函数中的if判断未通过(因为tty->stopped一直等于0,同时硬件流控已经关掉),一直处于发送状态而导致RS485的使能引脚没有打开。
static inline int uart_tx_stopped(struct uart_port *port)
{
struct tty_struct *tty = port->state->port.tty;
if (tty->stopped || port->hw_stopped)
return 1;
return 0;
}
解决方法
文件目录:drivers/tty/serial/nuc980_serial.c
在nuc980serial_shutdown()这个函数中,最后添加两行代码停止rx和tx即可
当然你也可以用nuc980serial_stop_tx()和nuc980serial_stop_rx(),只不过传入的形参需要强制转换一下。
static void nuc980serial_shutdown(struct uart_port *port)
{
struct uart_nuc980_port *up = (struct uart_nuc980_port *)port;
#if defined(CONFIG_ENABLE_UART_PDMA) || defined(CONFIG_USE_OF)
struct nuc980_ip_rx_dma *pdma_rx = &(up->dma_rx);
struct nuc980_ip_tx_dma *pdma_tx = &(up->dma_tx);
#endif
#if defined(CONFIG_ENABLE_UART_PDMA) || defined(CONFIG_USE_OF)
if(up->uart_pdma_enable_flag == 1) {
dma_release_channel(pdma_rx->chan_rx);
dma_release_channel(pdma_tx->chan_tx);
#ifdef USING_SRAM
sram_free((void *)up->dest_mem_p.vir_addr, up->dest_mem_p.size);
#endif
if(up->src_mem_p.vir_addr != 0)
dma_free_writecombine(NULL, up->src_mem_p.size, (void *)up->src_mem_p.vir_addr, up->src_mem_p.phy_addr);
up->dest_mem_p.size = 0;
up->src_mem_p.size = 0;
}
#endif
free_irq(port->irq, port);
/*
* Disable interrupts from this port
*/
serial_out(up, UART_REG_IER, 0);
//以下是添加的两行代码
// the same as using nuc980serial_stop_rx()
serial_out(up, UART_REG_IER, serial_in(up, UART_REG_IER) & ~RDA_IEN);
// the same as using nuc980serial_stop_tx()
__stop_tx(up);
}