这个补丁是我在全志A40 6.0增加的 , 当时是客户在搞can设备 , 但是收发的时候 can串口数据回显 我记得当时还研究了半天.....希望对有需要之人有帮助吧。
Rockchip系列之深度分析CAN接口系列(1)_一歲抬頭的博客-CSDN博客
Rockchip系列之CAN 新增framework系统jni接口访问(2)-CSDN博客
Rockchip系列之CAN 新增framework封装service+manager访问(3)-CSDN博客
Rockchip系列之CAN APP测试应用实现(4)_一歲抬頭的博客-CSDN博客
Rockchip CAN 部分波特率收发不正常解决思路_一歲抬頭的博客-CSDN博客
Android JNI与CAN通信遇到的问题总结_android can通信-CSDN博客
Android 内核关闭CAN 串口设备回显功能_一歲抬頭的博客-CSDN博客
这个补丁主要修改了 Linux 内核的串行 UART 驱动代码,以支持特定的硬件设备。
修改的文件
lichee/linux-3.10/drivers/input/touchscreen/gt9xx_new.zip
lichee/linux-3.10/drivers/tty/serial/sunxi-uart.c
lichee/linux-3.10/drivers/tty/serial/sunxi-uart.h
对每个文件的修改说明
sunxi-uart.c
:在处理接收和发送数据的函数中添加了对新配置的支持,并在相关函数中初始化了新添加的配置。sunxi-uart.h
:在结构体sw_uart_port
中添加了新的成员atomic_tx
,并定义了新的宏CONFIG_SW_UART_TX_DATA
和UART_TX_DATA_INDEX
。
如何应用这个补丁
- 将这个补丁应用到的 Linux 内核源码树中。
- 根据的硬件配置,可能需要修改
sunxi-uart.c
和sunxi-uart.h
中的相关设置。 - 编译并安装的 Linux 内核。
- 当的设备启动时,系统应该能够正确地检测和使用特定的硬件设备。
注意:这个补丁可能需要根据的具体硬件和 Linux 内核版本进行一些调整。
.../drivers/tty/serial/sunxi-uart.c | 36 +++++++++++++++--- .../drivers/tty/serial/sunxi-uart.h | 7 ++++ diff --git a/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.c b/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.c index 7ea5a16463..0db1231f30 100755 --- a/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.c +++ b/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.c @@ -39,7 +39,7 @@ #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_address.h> - +#include <linux/atomic.h> #include "sunxi-uart.h" //#define CONFIG_SW_UART_DUMP_DATA @@ -140,6 +140,7 @@ static unsigned int sw_uart_handle_rx(struct sw_uart_port *sw_uport, unsigned in char flag; do { + if (likely(lsr & SUNXI_UART_LSR_DR)) { ch = serial_in(&sw_uport->port, SUNXI_UART_RBR); #ifdef CONFIG_SW_UART_DUMP_DATA @@ -191,11 +192,18 @@ static unsigned int sw_uart_handle_rx(struct sw_uart_port *sw_uport, unsigned in } if (uart_handle_sysrq_char(&sw_uport->port, ch)) goto ignore_char; + #ifdef CONFIG_SW_UART_TX_DATA + //printk("can_test rx=%c\n",ch); + if (atomic_read(&sw_uport->atomic_tx) == 1) { + goto ignore_char; + } + #endif + uart_insert_char(&sw_uport->port, lsr, SUNXI_UART_LSR_OE, ch, flag); ignore_char: lsr = serial_in(&sw_uport->port, SUNXI_UART_LSR); } while ((lsr & (SUNXI_UART_LSR_DR | SUNXI_UART_LSR_BI)) && (max_count-- > 0)); - + SERIAL_DUMP(sw_uport, "Rx"); spin_unlock(&sw_uport->port.lock); tty_flip_buffer_push(&sw_uport->port.state->port); @@ -246,10 +254,15 @@ static void sw_uart_handle_tx(struct sw_uart_port *sw_uport) return; } count = sw_uport->port.fifosize / 2; + #ifdef CONFIG_SW_UART_TX_DATA + if (sw_uport->port.line == UART_TX_DATA_INDEX) { + atomic_set(&sw_uport->atomic_tx,1); + } + #endif do { -#ifdef CONFIG_SW_UART_DUMP_DATA - sw_uport->dump_buff[sw_uport->dump_len++] = xmit->buf[xmit->tail]; -#endif + #ifdef CONFIG_SW_UART_DUMP_DATA + sw_uport->dump_buff[sw_uport->dump_len++] = xmit->buf[xmit->tail]; + #endif serial_out(&sw_uport->port, xmit->buf[xmit->tail], SUNXI_UART_THR); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); sw_uport->port.icount.tx++; @@ -288,7 +301,9 @@ static unsigned int sw_uart_modem_status(struct sw_uart_port *sw_uport) wake_up_interruptible(&sw_uport->port.state->port.delta_msr_wait); } - + #ifdef CONFIG_SW_UART_TX_DATA + atomic_set(&sw_uport->atomic_tx,0); + #endif SERIAL_DBG("modem status: %x\n", status); return status; } @@ -1385,6 +1400,9 @@ static int sw_uart_request_resource(struct sw_uart_port* sw_uport, struct sw_uar } #endif + #ifdef CONFIG_SW_UART_TX_DATA + atomic_set(&sw_uport->atomic_tx,0); + #endif return 0; } @@ -1398,6 +1416,9 @@ static int sw_uart_release_resource(struct sw_uart_port* sw_uport, struct sw_uar sw_uport->dump_len = 0; #endif + #ifdef CONFIG_SW_UART_TX_DATA + atomic_set(&sw_uport->atomic_tx,0); + #endif clk_disable_unprepare(sw_uport->mclk); clk_put(sw_uport->mclk); @@ -1496,6 +1517,9 @@ static int sw_uart_probe(struct platform_device *pdev) if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time")) sw_uport->rs485conf.flags |= SER_RS485_ENABLED; + #ifdef CONFIG_SW_UART_TX_DATA + atomic_set(&sw_uport->atomic_tx,0); + #endif pdata->used = 1; port->iotype = UPIO_MEM; port->type = PORT_SUNXI; diff --git a/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.h b/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.h index 19d65950c5..57ccc176e1 100755 --- a/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.h +++ b/lichee/linux-3.10/drivers/tty/serial/sunxi-uart.h @@ -20,6 +20,9 @@ #include <linux/regulator/consumer.h> +#define CONFIG_SW_UART_TX_DATA +#define UART_TX_DATA_INDEX 4 + struct sw_uart_pdata { unsigned int used; unsigned int io_num; @@ -48,6 +51,10 @@ struct sw_uart_port { #define MAX_DUMP_SIZE 1024 unsigned int dump_len; char* dump_buff; + + #ifdef CONFIG_SW_UART_TX_DATA + atomic_t atomic_tx; + #endif struct proc_dir_entry *proc_root; struct proc_dir_entry *proc_info; -- 2.25.1