UART驱动调试方法

从收发方向调试,数据从App -> 行规程 -> serial_core -> 硬件驱动 -> TXD
行规程和serial_core是linux提供的代码,基本很少出错。这样就就可以比较开始和结束的数据,判断驱动是否正确。

从接收方向,RX -> 触发中断,驱动读取数据 -> 把数据读取到行规程 -> App
对于读取的数据,行规程需要设置成RAW模式。

一、怎么得到UART硬件上手法的数据

1.1 接收到的原始数据

可以在接收中断函数里把它打印出来,这些数据也会存入UART对应的tty_port的buffer里:

static inline int tty_insert_flip_char(struct tty_port *port,
                    unsigned char ch, char flag)
{
    
       
    struct tty_buffer *tb = port->buf.tail;		//这个buf是接收到的数据
    int change;

    change = (tb->flags & TTYB_NORMAL) && (flag != TTY_NORMAL);
    if (!change && tb->used < tb->size) {
    
    
        if (~tb->flags & TTYB_NORMAL)
            *flag_buf_ptr(tb, tb->used) = flag;
        *char_buf_ptr(tb, tb->used++) = ch;
        return 1;
    }
    return __tty_insert_flip_char(port, ch, flag);
} 

1.2 发送出去的数据

所有要发送出去的串口数据,都会通过uart_write函数发送,所有可以在uart_write中把她们打印出来:

static int uart_write(struct tty_struct *tty,
					const unsigned char *buf, int count)		//这个buf是发送前的buf
{
    
    
	struct uart_state *state = tty->driver_data;
	struct uart_port *port;
	struct circ_buf *circ;
	unsigned long flags;
	int c, ret = 0;

	/*
	 * This means you called this function _after_ the port was
	 * closed.  No cookie for you.
	 */
	if (!state) {
    
    
		WARN_ON(1);
		return -EL3HLT;
	}

	port = uart_port_lock(state, flags);
	circ = &state->xmit;
	if (!circ->buf) {
    
    
		uart_port_unlock(port, flags);
		return 0;
	}

	while (port) {
    
    
		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
		if (count < c)
			c = count;
		if (c <= 0)
			break;
		memcpy(circ->buf + circ->head, buf, c);
		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
		buf += c;
		count -= c;
		ret += c;
	}

	__uart_start(tty);
	uart_port_unlock(port, flags);
	return ret;
}

二、proc文件

2.1 /proc/interrupts

查看中断次数

cat /proc/interrupts 
           CPU0       
 16:    2017356       GPC  55 Level     i.MX Timer Tick
 18:       2486       GPC  26 Level     2020000.serial
 19:          0       GPC  98 Level     sai
 20:          0       GPC  50 Level     2034000.asrc
 35:          0       GPC   4 Level     20cc000.snvs:snvs-powerkey
 36:      55327       GPC 120 Level     20b4000.ethernet
 37:          0       GPC 121 Level     20b4000.ethernet
 38:          0       GPC  80 Level     20bc000.wdog
 44:          0       GPC  19 Level     rtc alarm
 50:       1556       GPC   2 Level     sdma
 55:      57709       GPC  43 Level     2184000.usb
 56:          0       GPC  42 Level     2184200.usb
 57:     309252       GPC 118 Level     2188000.ethernet
 58:          0       GPC 119 Level     2188000.ethernet
 59:      19073       GPC  22 Level     mmc0
 60:      32527       GPC  23 Level     mmc1
 61:          1       GPC 100 Level     2198000.adc
 62:        626       GPC  36 Level     21a0000.i2c
 63:        124       GPC  37 Level     21a4000.i2c
 65:         52       GPC   5 Level     21c8000.lcdif
 66:          0       GPC   8 Level     pxp-dmaengine-legacy
 67:          0       GPC  18 Level     pxp-dmaengine-std
 68:          0       GPC  27 Level     21e8000.serial
 69:          0       GPC  28 Level     21ec000.serial
 70:          0       GPC  46 Level     dcp-vmi-irq
 71:          0       GPC  47 Level     dcp-irq
 73:          2       GPC   6 Level     imx-rng
211:          7  gpio-mxc   9 Level     gt9xx
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:          0  Rescheduling interrupts
IPI3:          0  Function call interrupts
IPI4:          0  CPU stop interrupts
IPI5:          0  IRQ work interrupts
IPI6:          0  completion interrupts
Err:          0

2.2 /proc/tty/drivers

依次是:driver_name、设备节点前缀、主设备号、次设备号范围、类型

root@npi:~# cat /proc/tty/drivers 
/dev/tty             /dev/tty        5       0 system:/dev/tty
/dev/console         /dev/console    5       1 system:console
/dev/ptmx            /dev/ptmx       5       2 system
/dev/vc/0            /dev/vc/0       4       0 system:vtmaster
rfcomm               /dev/rfcomm   216 0-255 serial
g_serial             /dev/ttyGS    246 0-3 serial
usbserial            /dev/ttyUSB   188 0-511 serial
fsl-lpuart           /dev/ttyLP    247 0-5 serial
IMX-uart             /dev/ttymxc   207 16-23 serial
pty_slave            /dev/pts      136 0-1048575 pty:slave
pty_master           /dev/ptm      128 0-1048575 pty:master
unknown              /dev/tty        4 1-63 console

2.3 /proc/tty/driver(没有s)

root@npi:~# ls /proc/tty/driver
fsl-lpuart  IMX-uart  usbserial		#所有的tty_driver
root@npi:~# cat /proc/tty/driver
driver/  drivers  

root@npi:~# cat /proc/tty/driver/IMX-uart 	#查看数据收发统计信息
serinfo:1.0 driver revision:
0: uart:IMX mmio:0x02020000 irq:18 tx:69907 rx:127 brk:1 RTS|DTR|DSR|CD		#发送字符数、接收字符数
1: uart:IMX mmio:0x021E8000 irq:68 tx:0 rx:0 DSR|CD		
2: uart:IMX mmio:0x021EC000 irq:69 tx:6248 rx:25167 DSR|CD

2.4 /proc/tty/ldiscs

root@npi:~# cat /proc/tty/ldiscs #有哪些行规程
n_tty       0
ppp         3
pppsync    14
n_hci      15
n_null     27

三、sys文件

在drivers\tty\serial\serial_core.c中,有如下代码:

static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL);
static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL);
static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL);
static DEVICE_ATTR(irq, S_IRUSR | S_IRGRP, uart_get_attr_irq, NULL);
static DEVICE_ATTR(flags, S_IRUSR | S_IRGRP, uart_get_attr_flags, NULL);
static DEVICE_ATTR(xmit_fifo_size, S_IRUSR | S_IRGRP, uart_get_attr_xmit_fifo_size, NULL);
static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL);
static DEVICE_ATTR(close_delay, S_IRUSR | S_IRGRP, uart_get_attr_close_delay, NULL);
static DEVICE_ATTR(closing_wait, S_IRUSR | S_IRGRP, uart_get_attr_closing_wait, NULL);
static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divisor, NULL);
static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL);
static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL);
static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL);

这些代码会在/sys目录中创建串口的对应文件,查看这些文件可以得到串口的很多参数

寻找这些文件的方法:

cd /sys
find -name uartclk

猜你喜欢

转载自blog.csdn.net/ch122633/article/details/130683475