A20串口的调试,特殊波特率
由于特殊要求,把A20的uart tx4的波特率设置为31250.查看了很多资料,发现问题比较复杂,有人提到Linux里面有一个客户定制的操作流程,就是通过ioctl命令来设定。http://blog.chinaunix.net/uid-28786874-id-4257399.htmlhttp://www.360doc.com/content/13/0514/11/7918060_
由于特殊要求,把A20的uart tx4的波特率设置为31250.
查看了很多资料,发现问题比较复杂,有人提到Linux里面有一个客户定制的操作流程,就是通过ioctl命令来设定。
http://blog.chinaunix.net/uid-28786874-id-4257399.html
http://www.360doc.com/content/13/0514/11/7918060_285322275.shtml
这2个页面里有相关的说明。
但我查看内核的代码,好像并没有执行到这个地方。
于是针对这种情况,我的思路是先把波特率设置为较为接近的38400,然后通过修改底层38400的参数,把真实的参数改为31250.这样可以暂时达到目的,当然这样只是作为实验,因为一旦改了,就不再兼容原先的系统了。
在drivers/tty/serial/sw_uart.c里的:
sw_uart_set_termios函数,这个函数里实现波特率的设置。
/* set buadrate */
baud = uart_get_baud_rate(port, termios, old,
port->uartclk / 16 / 0xffff,
port->uartclk / 16);
sw_uart_check_baudset(port, baud);
quot = uart_get_divisor(port, baud);
dll = quot & 0xff;
dlh = quot >> 8;
SERIAL_DBG("set baudrate %d, quot %d\n", baud, quot);
spin_lock_irqsave(&port->lock, flags);
uart_update_timeout(port, termios->c_cflag, baud);
通过uart_get_divisor得到dll duh这2个数。
/*
* if lcr & baud are changed, reset controller to disable transfer
*/
if (lcr != sw_uport->lcr || dll != sw_uport->dll || dlh != sw_uport->dlh) {
t1 = 1;
// SERIAL_DBG("LCR & BAUD changed, reset controller...\n");
sw_uart_reset(sw_uport);
}
sw_uport->dll = dll;
sw_uport->dlh = dlh;
if (serial_in(port, SW_UART_LCR) != (sw_uport->lcr|SW_UART_LCR_DLAB)) {
lcr_fail = 1;
} else {
sw_uport->lcr = lcr;
<span style="color:#ff0000;">serial_out(port, sw_uport->dll, SW_UART_DLL);
serial_out(port, sw_uport->dlh, SW_UART_DLH);</span>
serial_out(port, sw_uport->lcr, SW_UART_LCR);
if (serial_in(port, SW_UART_LCR) != sw_uport->lcr) {
lcr_fail = 2;
}
}
这样就实现了波特率的设置。
如果要改变波特率,只需要在uart_get_divisor之前,把baud的值修改成32150即可做到,当然为了避免影响其他的端口,可以利用sw_uport->id这个值来限定只有端口4才修改。
更多推荐
所有评论(0)