Board logo

标题: 嵌入式系统应用中实现RS485的方向切换 [打印本页]

作者: 520503    时间: 2014-10-29 22:43     标题: 嵌入式系统应用中实现RS485的方向切换

关键字:RS485   方向切换   嵌入式系统   DM8168  

2.4 Linux代码修改

需要修改的文件:
① arch/arm/machomap2/bordti8168evm.c
② drivers/serial/omapserial.c
③ include/linux/serial_core.h

serial_core.h文件,uart_port结构体中增加set_rs485_direction函数指针,用于执行RS485的方向切换void (*set_rs485_direction)(int rs485_dir);原本考虑在uart_ops结构体中增加的,但是这个结构体是常量类型,对它不作改动,因此加到了uart_port结构体中。在该文件中添加相关宏定义和函数指针类型用于函数注册:
#define SET_RS485_RX0
#define SET_RS485_TX1
typedef void (*set_rs485_direction_t)(int rs485_dir);//用于函数注册

omapserial.c文件主要做了如下几点改动:
① 添加omap_rs485_dir_fun全局的函数指针。
static set_rs485_direction_t omap_rs485_dir_fun[OMAP_MAX_HSUART_PORTS]={NULL, NULL, NULL, NULL, NULL, NULL}

② 外部驱动利用omap_rs485_dir_fun_reg注册函数对omap_rs485_dir_fun进行赋值。

void omap_rs485_dir_fun_reg(int port_num, set_rs485_direction_t rs485_dir_fun){
if (port_num>=OMAP_MAX_HSUART_PORTS)
printk(KERN_ERR “%s, port_num error max is %d, but %d \\n”, __FUNCTION__, OMAP_MAX_HSUART_PORTS-1, port_num);
omap_rs485_dir_fun[port_num]= rs485_dir_fun;
}
EXPORT_SYMBOL(omap_rs485_dir_fun_reg);

③ serial_omap_probe函数中对控制程序中用到的up->port.set_rs485_direction进行赋值。
up->port.set_rs485_direction= omap_rs485_dir_fun[pdev->id];

④ 默认情况下RS485处于接收状态。

⑤ serial_omap_enable_ier_thri函数中把RS485切换为发送状态。
static incline void serial_omap_enable_ier_thri(struct uart_omap_port *up){
if (!(up->ier & UART_IER_THRI)) {
/* rs485 dir change to tx */
if (up->port.set_rs485_direction != NULL)
up->port.set_rs485_direction(SET_RS485_TX);
……//此处代码省略
}
}

⑥ serial_omap_stop_tx函数中把RS485切换为接收状态。
static void serial_omap_stop_tx(struct uart_omap_port *port){
……//此处代码省略
if (up->ier & UART_IER_THRI) {
up->ier &= ~UART_IER_THRI;
serial_out(up, UART_IER, up->ier);
/* rs485 dir change to rx */
if (port->set_rs485_direction != NULL)
port->set_rs485_direction(SET_RS485_RX);
}
}

⑦ transmit_chars更改一下,原先的代码是当没有更多的字符要发送(环形缓冲为空)时需要关闭发送中断,这时串口控制器发送BUF和移位寄存器中还是有数据的,这些数据串口控制器自动发送完成后才算结束,由于已经关闭了发送中断,因此发送结束后就没有中断产生了。但是RS485切换方向需要等到完全发送完成后才能进行。因此对transmit_chars函数做了修改。调用serial_omap_stop_tx函数前判断发送BUF和移位寄存器是否为空,如果为空就可以切换方向了。简而言之,延后了发送中断的关闭时间。
static void transmit_chars(struct uart_omap_port *up){
……//此处代码省略
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
if (up->port.ops->tx_empty(&up->port)==0)
return;//added for last transmit
serial_omap_stop_tx(&up->port);
return;
}
……//此处代码省略
if (uart_circ_empty(xmit)) {
if (up->port.ops->tx_empty(&up->port)==0)
return;//added for last transmit
serial_omap_stop_tx(&up->port);
}
}
⑧ arch/arm/machomap2/boardti8168evm.c文件在ti8168_evm_init函数中调用omap_rs485_dir_fun_reg函数注册RS485切换函数。





欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0