ARM-Linux s3c2440 之UART分析(二)
软件篇(linux-2.6.30.4):
Linux系统的串口驱动与一般字符设备并一样,它采用层次化的架构,从而看做是一个串行系统来实现。
(1)关注UART或其他底层串行硬件特征的底层驱动程序。
(2)和底层驱动程序接口的TTY驱动程序。
(3)加工用于和TTY驱动程序交换数据的线路规程。
下图描述了串行系统间的层次结构关系(s3c2440串口实现例),可以概括为:用户应用层 --> 线路规划层 -->TTY层 -->底层驱动层 -->物理硬件层
线路规程和TTY驱动程序是与硬件平台无关的,Linux源码中已经提供了实现,所以对于具体的平台,我们只需实现底层驱动程序即可,这也是我们最关心的。在s3c2440a中,主要由dirivers/serial/下的s3c2440.c和samsung.c实现。
Uart驱动程序主要围绕三个关键的数据结构展开(include/linux/serial_core.h中定义):
UART特定的驱动程序结构定义:struct uart_driver s3c24xx_uart_drv;
UART端口结构定义: struct uart_port s3c24xx_serial_ops;
UART相关操作函数结构定义: struct uart_ops s3c24xx_serial_ops;
基于以上三个结构体,来看看s3c2440是如何挂接到Linux中串口构架的:
S3c2440串口相关操作函数定义在s3c24xx_serial_ops中,这个是一个structuart_ops结构
- staticstructuart_opss3c24xx_serial_ops={
- .pm=s3c24xx_serial_pm,//电源管理函数
- .tx_empty=s3c24xx_serial_tx_empty,//检车发送FIFO缓冲区是否空
- .get_mctrl=s3c24xx_serial_get_mctrl,//是否串口流控
- .set_mctrl=s3c24xx_serial_set_mctrl,//是否设置串口流控cts
- .stop_tx=s3c24xx_serial_stop_tx,//停止发送
- .start_tx=s3c24xx_serial_start_tx,//启动发送
- .stop_rx=s3c24xx_serial_stop_rx,//停止接收
- .enable_ms=s3c24xx_serial_enable_ms,//空函数
- .break_ctl=s3c24xx_serial_break_ctl,//发送break信号
- .startup=s3c24xx_serial_startup,//串口发送/接收,以及中断申请初始配置函数
- .shutdown=s3c24xx_serial_shutdown,//关闭串口
- .set_termios=s3c24xx_serial_set_termios,//串口clk,波特率,数据位等参数设置
- .type=s3c24xx_serial_type,//CPU类型关于串口
- .release_port=s3c24xx_serial_release_port,//释放串口
- .request_port=s3c24xx_serial_request_port,//申请串口
- .config_port=s3c24xx_serial_config_port,//串口的一些配置信息info
- .verify_port=s3c24xx_serial_verify_port,//串口检测
- };
驱动程序结构定义:
- staticstructuart_drivers3c24xx_uart_drv={
- .owner=THIS_MODULE,
- .dev_name="s3c2440_serial",//具体设备名称
- .nr=CONFIG_SERIAL_SAMSUNG_UARTS,//定义有几个端口
- .cons=S3C24XX_SERIAL_CONSOLE,//console接口
- .driver_name=S3C24XX_SERIAL_NAME,//串口名:ttySAC
- .major=S3C24XX_SERIAL_MAJOR,//主设备号
- .minor=S3C24XX_SERIAL_MINOR,//次设备号
- };
端口配置结构定义,其中包括了一个structuart_ports结构:
- structs3c24xx_uart_port{
- unsignedcharrx_claimed;
- unsignedchartx_claimed;
- unsignedintpm_level;
- unsignedlongbaudclk_rate;
- unsignedintrx_irq;
- unsignedinttx_irq;
- structs3c24xx_uart_info*info;
- structs3c24xx_uart_clksrc*clksrc;
- structclk*clk;
- structclk*baudclk;
- structuart_portport;
- #ifdefCONFIG_CPU_FREQ
- structnotifier_blockfreq_transition;
- #endif
- };
- staticstructs3c24xx_uart_ports3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS]={
- [0]={//串口0
- .port={
- .lock=__SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
- .iotype=UPIO_MEM,//
- .irq=IRQ_S3CUART_RX0,//中断号
- .uartclk=0,//时钟值
- .fifosize=16,//定义FIFO缓存区大小
- .ops=&s3c24xx_serial_ops,//串口相关操作函数
- .flags=UPF_BOOT_AUTOCONF,
- .line=0,//线路1
- }
- },
- [1]={//串口1
- .port={
- .lock=__SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
- .iotype=UPIO_MEM,
- .irq=IRQ_S3CUART_RX1,
- .uartclk=0,
- .fifosize=16,
- .ops=&s3c24xx_serial_ops,
- .flags=UPF_BOOT_AUTOCONF,
- .line=1,
- }
- },
- #ifCONFIG_SERIAL_SAMSUNG_UARTS>2
- [2]={//串口2
- .port={
- .lock=__SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
- .iotype=UPIO_MEM,
- .irq=IRQ_S3CUART_RX2,
- .uartclk=0,
- .fifosize=16,
- .ops=&s3c24xx_serial_ops,
- .flags=UPF_BOOT_AUTOCONF,
- .line=2,
- }
- },
- #endif
- };
综上所述,s3c2440主要是实现这三个数据结构:
s3c24xx_serial_ops, s3c24x
ARMLinuxs3c2440UAR 相关文章:
- ARM-Linux s3c2440 之UART分析(一)(11-19)
- ARMLinux s3c2440 之UART分析二(11-19)
- ARM-Linux s3c2440 之UART分析(三)(11-19)
- ARMLinux s3c2440 之UART分析一(11-19)
- ARM-Linux s3c2440 之UART分析(四)(11-19)
- ARM-Linux s3c2440 之UART分析(五)(11-19)