s3c6410的UART设备驱动(1)

发布者:创意航海最新更新时间:2022-06-07 来源: eefocus关键字:s3c6410  UART  设备驱动 手机看文章 扫描二维码
随时随地手机看文章

1、

这段话摘于《设备驱动开发详解》


在使用串口核心层这个通用串口tty驱动层的接口后,一个串口驱动要完成的主要工作:


(1)、定义uart_driver、uart_ops、uart_port等结构体的实例并在适当的地方根据具体硬件和驱动的情况初始化它们,当然具体设备的驱动可以将这些结构体在新定义的xxx_uart_driver、xxx_uart_ops、xxx_uart_port之内。


(2)、在模块初始化是调用uart_register_driver和uart_add_port注册UART驱动并添加端口,在模块卸载时调用uart_unregister_driver和uart_remove_one_port以注销UART驱动并移除端口。


(3)、根据具体硬件的datasheet实现uart_ops中的成员函数,这些函数的实现成为UART驱动的主体工作。


2、s3c6410的串口驱动:


这些与上面的(1)相对应。


(1)、serial_core.c文件的作用:主要有如下结构体和实现其中的函数,供上层函数调用:


static const struct tty_operations uart_ops = {

.open = uart_open,

.close  = uart_close,

.write  = uart_write,

.put_char  = uart_put_char,

.flush_chars  = uart_flush_chars,

.write_room  = uart_write_room,

.chars_in_buffer= uart_chars_in_buffer,

.flush_buffer  = uart_flush_buffer,

.ioctl  = uart_ioctl,

.throttle  = uart_throttle,

.unthrottle  = uart_unthrottle,

.send_xchar  = uart_send_xchar,

.set_termios  = uart_set_termios,

.set_ldisc  = uart_set_ldisc,

.stop = uart_stop,

.start  = uart_start,

.hangup  = uart_hangup,

.break_ctl  = uart_break_ctl,

.wait_until_sent= uart_wait_until_sent,

#ifdef CONFIG_PROC_FS

.read_proc  = uart_read_proc,

#endif

.tiocmget  = uart_tiocmget,

.tiocmset  = uart_tiocmset,

#ifdef CONFIG_CONSOLE_POLL

.poll_init  = uart_poll_init,

.poll_get_char= uart_poll_get_char,

.poll_put_char= uart_poll_put_char,

#endif

};


并提供uart_register_driver、uart_unregister_driver、uart_add_one_port、uart_remove_one_port函数供底层函数注册。


(2)、在sansung.c文件中有如下:


static struct uart_ops s3c24xx_serial_ops = {

.pm = s3c24xx_serial_pm,

.tx_empty = s3c24xx_serial_tx_empty,

.get_mctrl = s3c24xx_serial_get_mctrl,

.set_mctrl = s3c24xx_serial_set_mctrl,

.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,

.startup = s3c24xx_serial_startup,

.shutdown = s3c24xx_serial_shutdown,

.set_termios = s3c24xx_serial_set_termios,

.type = s3c24xx_serial_type,

.release_port = s3c24xx_serial_release_port,

.request_port = s3c24xx_serial_request_port,

.config_port = s3c24xx_serial_config_port,

.verify_port = s3c24xx_serial_verify_port,

};



static struct uart_drivers3c24xx_uart_drv = {

.owner  = THIS_MODULE,

.dev_name  = "s3c2410_serial",

.nr = CONFIG_SERIAL_SAMSUNG_UARTS,

.cons = S3C24XX_SERIAL_CONSOLE,

.driver_name  = S3C24XX_SERIAL_NAME,

.major  = S3C24XX_SERIAL_MAJOR,

.minor  = S3C24XX_SERIAL_MINOR,

};


原始结构为


struct uart_driver {

struct module *owner;

const char *driver_name;

const char *dev_name;

int major;

int minor;

int nr;

struct console *cons;



/*

* these are private; the low level driver should not

* touch these; they should be initialised to NULL

*/

struct uart_state *state;

struct tty_driver *tty_driver;

};



static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {

[0] = {

.port = {

.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),

.iotype  = UPIO_MEM,

.irq = IRQ_S3CUART_RX0,

.uartclk  = 0,

.fifosize  = 16,

.ops = &s3c24xx_serial_ops,

.flags  = UPF_BOOT_AUTOCONF,

.line = 0,

}

},

[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,

}

},

#if CONFIG_SERIAL_SAMSUNG_UARTS > 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

#if CONFIG_SERIAL_SAMSUNG_UARTS > 3

[3] = {

.port = {

.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),

.iotype  = UPIO_MEM,

.irq = IRQ_S3CUART_RX3,

.uartclk  = 0,

.fifosize  = 16,

.ops = &s3c24xx_serial_ops,

//---->modify by phantom


#if 1 

.flags  = UPF_BOOT_AUTOCONF | UPF_CONS_FLOW,

#else

.flags  = UPF_BOOT_AUTOCONF,

#endif

//<---- 

.line = 3,

}

}

#endif

};


这个数组中的内容其实就是对下面struct uart_port结构成员的初始化。


其中: 结构体s3c24xx_uart_port源码如下:


struct s3c24xx_uart_port {

unsigned charrx_claimed;

unsigned chartx_claimed;

unsigned intpm_level;

unsigned longbaudclk_rate;



unsigned intrx_irq;

unsigned inttx_irq;



struct s3c24xx_uart_info*info;

struct s3c24xx_uart_clksrc*clksrc;

struct clk*clk;

struct clk*baudclk;

struct uart_portport;



#ifdef CONFIG_CPU_FREQ

struct notifier_blockfreq_transition;

#endif

};


其中:struct uart_port源码如下:


struct uart_port {

spinlock_tlock;/* port lock */

unsigned long  iobase; /* in/out[bwl] */

unsigned char __iomem*membase;/* read/write[bwl] */

unsigned int  irq; /* irq number */

unsigned intuartclk;/* base uart clock */

unsigned intfifosize;/* tx fifo size */

unsigned charx_char;/* xon/xoff char */

unsigned charregshift;/* reg offset shift */

unsigned chariotype;/* io access style */

unsigned charunused1;



#define UPIO_PORT(0)

#define UPIO_HUB6(1)

#define UPIO_MEM(2)

#define UPIO_MEM32(3)

#define UPIO_AU(4)/* Au1x00 type IO */

#define UPIO_TSI(5)/* Tsi108/109 type IO */

#define UPIO_DWAPB(6)/* DesignWare APB UART */

#define UPIO_RM9000(7)/* RM9000 type IO */



unsigned intread_status_mask;/* driver specific */

unsigned intignore_status_mask;/* driver specific */

struct uart_info*info;/* pointer to parent info */

struct uart_icounticount;/* statistics */



struct console*cons;/* struct console, if any */

#ifdef CONFIG_SERIAL_CORE_CONSOLE

unsigned longsysrq;/* sysrq timeout */

#endif



upf_tflags;



#define UPF_FOURPORT((__force upf_t) (1 << 1))

#define UPF_SAK((__force upf_t) (1 << 2))

#define UPF_SPD_MASK((__force upf_t) (0x1030))

#define UPF_SPD_HI((__force upf_t) (0x0010))

#define UPF_SPD_VHI((__force upf_t) (0x0020))

#define UPF_SPD_CUST((__force upf_t) (0x0030))

#define UPF_SPD_SHI((__force upf_t) (0x1000))

#define UPF_SPD_WARP((__force upf_t) (0x1010))

#define UPF_SKIP_TEST((__force upf_t) (1 << 6))

#define UPF_AUTO_IRQ((__force upf_t) (1 << 7))

#define UPF_HARDPPS_CD((__force upf_t) (1 << 11))

#define UPF_LOW_LATENCY((__force upf_t) (1 << 13))

#define UPF_BUGGY_UART((__force upf_t) (1 << 14))

#define UPF_MAGIC_MULTIPLIER((__force upf_t) (1 << 16))

#define UPF_CONS_FLOW((__force upf_t) (1 << 23))

#define UPF_SHARE_IRQ((__force upf_t) (1 << 24))

#define UPF_BOOT_AUTOCONF((__force upf_t) (1 << 28))

#define UPF_FIXED_PORT((__force upf_t) (1 << 29))

#define UPF_DEAD((__force upf_t) (1 << 30))

#define UPF_IOREMAP((__force upf_t) (1 << 31))



#define UPF_CHANGE_MASK((__force upf_t) (0x17fff))

#define UPF_USR_MASK((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))



unsigned intmctrl;/* current modem ctrl settings */

unsigned inttimeout;/* character-based timeout */

unsigned inttype;/* port type */

const struct uart_ops*ops;

unsigned intcustom_divisor;

unsigned intline;/* port index */

resource_size_tmapbase;/* for ioremap */

struct device*dev;/* parent device */

unsigned charhub6;/* this should be in the 8250 driver */

unsigned charsuspended;

unsigned charunused[2];

void*private_data;/* generic platform data pointer */

};

关键字:s3c6410  UART  设备驱动 引用地址:s3c6410的UART设备驱动(1)

上一篇:ARM9 2410移植之ARM中断原理, 中断嵌套的误区,中断号的怎么来的
下一篇:linux中触摸屏驱动的实现(2)——基于s3c6410处理器

推荐阅读最新更新时间:2024-11-11 12:02

s3c6410_时钟初始化
参考: 1)《USER'S MANUAL-S3C6410X》第三章 SYSTEM CONTROLLER 2)u-boot/board/samsumg/smdk6410/lowlevel_init.S 1. PLL与CLK的关系: 详细关系图见用户手册122页Figure 3-2 The block diagram of clock generator。 三种PLL:APLL,MPLL,EPLL 四种CLK:ACLK,HCLK,PCLK 1)APLL产生ACLK,,ACLK为CPU提供时钟; 2)同步模式下APLL产生HCLK/PCLK,异步模式下MPLL产生HCLK/PCLK,HCLK为AXI/AHB总线上的外设提供时钟,
[单片机]
s3c6410_时钟初始化
STM32--UART异步通信学习
字符发送的过程描述:在UART的发送过程中先将数据输入到发送数据寄存器中(TDR)此时(TXE)被硬件置1,之后TDR寄存器将数据串行移入到发送移位寄存器中,将数据在TX端口发送,此时(TC)被硬件置1。 发送与接收是逆过程。 UART发送配置步骤: 1.通过USART_CR1寄存器上置位UE来激活USART。 2.编程USART_CR1的M位来定义字长。 3.在USART_CR2中编程停止位的位数。 4.如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器。 5.利用USART_BRR寄存器选择要求的波特率。 6. 设置USART_CR
[单片机]
STM32--<font color='red'>UART</font>异步通信学习
s3c6410 SD卡启动的Secure mode
前段时间我新来的同事弄SD卡启动的时候,按照三星Internal ROM Booting的Application Note弄得,也和网上的文章写的一样,irom启动完了以后开始u-boot的汇编初始化的代码,配置PLL、配置RAM...,然后到C语言段的时候开始调用irom自己提供的CopyMMCtoMem函数将代码复制到内存开始运行。但无论如何跑不起来,还报了4.2 Verification failure of BL1 integrity的错误。后来找了好久,用Jlink连上以后一步一步的看irom的代码才发现了是启动时候的Secure mode的问题。手册里面对于这方面什么都没写,就把我们知道的一点东西写一下吧。 在IR
[单片机]
STM32开发 -- UART应用层通信协议分析
拿到一份UART的通信协议,上手来操作之前先做一下分析。 一、帧格式说明 先看一下它的帧格式说明: 1、 帧头标志Head 不论是命令帧还是响应帧,帧头标志都是0x92。 2、 协议版本 协议版本号(4bit),目前值为1 加密方式(4bit),0表示采取“数据不加密+校验和”方式。 所以,当前此字段完整值为0x10 3、 控制字段中的C/R比特 用于指示该帧是命令帧还是应答帧,1表示命令帧,0表示应答帧。 4、 控制字段中的T/F比特 用于指示传输数据类型,1表示透明的非结构化数据,0表示正常的数据帧。 5、 虚拟通道 虚拟地址(4bit):代表数据帧的源地址标识。目前为保留位,取值为0。 通道序
[单片机]
STM32开发 -- <font color='red'>UART</font>应用层通信协议分析
STM32F103 UART通信讲解
一、串行通信的通信方式 1.同步通信:带时钟同步信号传输,有一根线是同步时钟。例如SPI(全双功)、IIC(半双工)通信接口 2.异步通信:不带时钟同步信号,必须约定好波特率。例如UART(全双功) 二、STM32的串口通信接口 UART:通用异步收发器。 USART:通用同步异步收发器。 STM32F10x系列包含3个USART和2个UART。 都是TTL电平交叉相连即可 与PC机可以使用USB-TTL进行通信。 三、通信引脚 四、常用串口相关寄存器 1.USART_SR状态寄存器:里面一些相关位可以用来判断是否发送接收完成等。 2.USART_DR数据寄存器:通过读写这个寄存器来
[单片机]
STM32F103 <font color='red'>UART</font>通信讲解
UART与RS232以及COM端口的关系
UART作为硬件来看,它是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是电脑硬件的一部分,将资料由串行传输(Serial communication)与平行传输(Parallel communication)间作传输转换。UART通常用在与其他通讯协定(如EIA RS-232)的连结上。 具体实物表现为独立的模块化芯片,或作为集成于微处理器中的周边设备。在开发板设计和测试阶段被用来控制CPU与其余部分的信息传送。 UART作为一种软件协议来看,是异步串口通信协议的英文缩写,它包括了RS232、RS499、RS423、RS422和RS485等接口标准规范和总线标准规范
[单片机]
ARM11(s3c6410)和ARM9(2440)的区别
1.主频不同。2440是400M的。6410是533/667M的; 2.处理器版本不一样:2440是ARM920T内核,6410是ARM1176ZJF内核; 3.6410在视频处理方面比2440要强很多。内部视频解码器,包括MPEG4等视频格式; 4.6410支持WMV9、xvid、mpeg4、h264等格式的硬解码和编码; 5. 6410多和很多扩展接口比如:tv-out、CF卡和S-Video输出等; 6. spi、串口、sd接口也比那两个要丰富; 7.6410采用的是DDR内存控制器;2440采用的是SDRam内存控制器; 8.6410为双总线架构,一路用于内存总线、一路用于Fl
[单片机]
STM32-USART串口通信【USART和UART的区别】
USART简介 USART(Universal Synchronous/Asynchronous Receiver/Transmitter),即通用同步/异步串行接收/发送器。 所谓同步通信和异步通信的主要区别是前者有公共时钟,总线上的所有设备按统一的时序、统一的传输周期进行信息传输。后者没有公共时钟,没有固定的传输周期,采用应答方式通信。简单的说,“同步”就是发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。 “异步”就是发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。异步通信发送方式下,在每一个字符的开始和结束分别加上开始位和停止位,以便使接收端能够正确地将每一个字符接收来。 我们用
[单片机]
STM32-USART串口通信【USART和<font color='red'>UART</font>的区别】
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved