RK3399驱动开发 | 04 - WK2124串口芯片驱动浅析
Posted Mculover666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RK3399驱动开发 | 04 - WK2124串口芯片驱动浅析相关的知识,希望对你有一定的参考价值。
一、驱动挂载与卸载
加载模块之后,查看完整的系统日志:
1. 模块加载与卸载
WK2124使用spi总线通信,所以在模块加载的时候向内核注册spi驱动。
2. 驱动挂载与卸载
可以看到spi驱动兼容性是"wkmic,wk2124spi",驱动挂载函数probe,卸载函数remove。
Linux 5.4内核中spi驱动框架没有resume,所以注释resume函数实现:
3. SPI读写函数
以 wk2xxx_read_global_reg 为例,基于SPI驱动框架,实现如下:
二、probe函数略读
1. 测试SPI通信是否正常
对应日志为,能读到寄存器数据,说明SPI通信正常:
2. 解析中断引脚
函数实现如下,返回irq编号:
对应日志为:
3. 注册uart驱动
uart_drriver实现为wk2xxx_uart_driver,使用uart_register_driver
API注册进内核,后面进行剖析。
4. 注册uart端口
uart端口使用 uart_add_one_port
注册进内核,这些端口的操作函数集为wk2xxx_pops,后面进行剖析。
三、uart驱动框架实现
关于Linux驱动框架,参考文章:i.MX6ULL驱动开发 | 15 - Linux UART 驱动框架。
1. uart_driver结构体实现
需要注意,dev_name 将会是后续注册的设备节点名称,每个注册的uart端口都会对应一个节点,名称为ttysWKx。
2. uart_port_ops实现
注册uart_port的时候,最重要的是端口的操作函数集,也就是 uart_ops 成员中的函数,Linux内核最终调用的都是其中的函数。
其实整个驱动的目的就是实现这些函数,但没有逐个分析的必要,主要看一下串口发送流程和串口接收流程。
四、设置串口波特率流程
1. enable_ms
enable_ms用于启用modem状态中断:
enable_ms(port)
Enable the modem status interrupts.
This method may be called multiple times. Modem status
interrupts should be disabled when the shutdown method is
called.
wk2124没有对应的控制线,所以实现为空:
2. set_termios
set_termios用于设置串口属性,比如更改波特率。
对于波特率是经过了转码的:
而且驱动中最大支持到230400,这点在用户态设置的时候需要注意:
在所有设置参数都准备好之后,调用该函数设置到WK2124中每个子串口对应的寄存器中:
其中设置寄存器的代码如下:
WK2124寄存器如下:
五、串口发送数据流程
printk级别要改为 7 4 1 7
1. enable_ms
2. set_termios
3. start_tx(重点)
其中的核心是 workqueue 机制,将发送的内容使用queue_work提交到工作队列中:
工作队列实际的处理函数为wk2xxx_work,在其中实际操作wk2124寄存器去完成数据的发送,如下:
六、串口接收数据
1. enable_ms
2. set_termios
3. irq中断函数
4. wk2xxxirq_app
在接收流程的work处理函数wk2xxx_work中,主要调用 wk2xxxirq_app 函数,其中完成一系列与WK2124芯片的操作。
(1)读取GIFR寄存器
wk2xxx_read_global_reg(s->spi_wk,WK2XXX_GIFR ,dat);
gifr = dat[0];
读取之后判断子串口是否确实发生了中断,如果没有发生则直接return。
(2)读取子串口SIFR寄存器
wk2xxx_read_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_SIFR,dat);
sifr = dat[0];
(3)读取子串口SIER寄存器
wk2xxx_read_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_SIER,dat);
sier = dat[0];
5. wk2xxx_rx_chars
该函数完成中断数据读取的工作。
wk2xxx_read_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_FDAT,dat);
ch = (int)dat[0];
以上是关于RK3399驱动开发 | 04 - WK2124串口芯片驱动浅析的主要内容,如果未能解决你的问题,请参考以下文章
RK3399驱动开发 | 03 - WK2124串口芯片驱动调试
RK3399驱动开发 | 03 - WK2124串口芯片驱动调试
RK3399驱动开发 | 05 - 使用lszrz压测串口传输(wk2124)
使用lszrz压测串口传输(RK3399 + wk2124)