s3c6410的UART设备驱动(2)

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

上一篇说到了第一部分,这一篇说第二部分,如下这部分:


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


1、先说uart_register_driver函数,这个函数在


static int __init s3c24xx_serial_modinit(void) module_init(s3c24xx_serial_modinit);中被调用。


列出其源码,在Serial_core.c (linux2.6.28driversserial)文件中:


/**

 * uart_register_driver - register a driver with the uart core layer

 * @drv: low level driver structure

 *

 * Register a uart driver with the core driver.  We in turn register

 * with the tty layer, and initialise the core driver per-port state.

 *

 * We have a proc file in /proc/tty/driver which is named after the

 * normal driver.

 *

 * drv->port should be NULL, and the per-port structures should be

 * registered using uart_add_one_port after this call has succeeded.

 */


这个函数进行驱动的注册,在其中包含了tty_register_driver函数(这个函数我们以前讲过,可以回过去看一下),传入的参数在上一篇中有列出,在列一次,主要是为对照着,更容易看:


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;

};

int uart_register_driver(struct uart_driver *drv)

{

struct tty_driver *normal = NULL;

int i, retval;

......

drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);

retval = -ENOMEM;

if (!drv->state)

goto out;


这段可以看上面那段注释,在struct uart_driver结构体中的注释。这里是申请内存的大小为sizeof(struct uart_state) * drv->nr,其中drv->nr是设备个数,因为可能有多个设备。



normal  = alloc_tty_driver(drv->nr);

if (!normal)

goto out;

这个以前说过


drv->tty_driver = normal;


normal->owner  = drv->owner;

normal->driver_name= drv->driver_name;

normal->name  = drv->dev_name;

normal->major  = drv->major;

normal->minor_start= drv->minor;

normal->type  = TTY_DRIVER_TYPE_SERIAL;

normal->subtype= SERIAL_TYPE_NORMAL;

normal->init_termios= tty_std_termios;

normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;

normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;

normal->flags  = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;

normal->driver_state    = drv;注意这里,使struct tty_driver结构体和struct uart_driver结构体联系起来了,在后面很重要,如 uart_open函数中。

tty_set_operations(normal, &uart_ops);在前面说过,把static const struct tty_operations uart_ops结构和struct tty_driver结构绑定在一起,就不细说了。


这段对struct tty_driver的normal结构体赋值,其实就是对struct uart_driver 中的成员struct tty_driver*tty_driver赋值,因为都是指针。


/*

* Initialise the UART state(s).

*/

for (i = 0; i < drv->nr; i++) {

struct uart_state *state = drv->state + i;


state->close_delay     = 500;/* .5 seconds */

state->closing_wait    = 30000;/* 30 seconds */


mutex_init(&state->mutex);

}



retval = tty_register_driver(normal);这个函数在前面也说过,可以会前面查看。主要是关于终端设备顶层的设备注册。列出一个小片段:


cdev_init(&driver->cdev, &tty_fops);

driver->cdev.owner = driver->owner;

error = cdev_add(&driver->cdev, dev, driver->num);

if (error) {

unregister_chrdev_region(dev, driver->num);

driver->ttys = NULL;

driver->termios = NULL;

kfree(p);

return error;

}

 out:

if (retval < 0) {

put_tty_driver(normal);

kfree(drv->state);

}

return retval;

}


对应的uart_unregister_driver就比较简单了,做相反的事,就不说了,其内部调用了tty_unregister_driver(p)函数。


/**

 * uart_unregister_driver - remove a driver from the uart core layer

 * @drv: low level driver structure

 *

 * Remove all references to a driver from the core driver.  The low

 * level driver must have removed all its ports via the

 * uart_remove_one_port() if it registered them with uart_add_one_port().

 * (ie, drv->port == NULL)

 */

void uart_unregister_driver(struct uart_driver *drv)

{

struct tty_driver *p = drv->tty_driver;

tty_unregister_driver(p);

put_tty_driver(p);

kfree(drv->state);

drv->tty_driver = NULL;

}


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

上一篇:s3c6410的UART设备驱动(5)
下一篇:Linux下s3c6410的GPIO操作(4)

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

keil通过UART串口打印汉字到串口工具乱码的问题
近通过STMCubexMX生成的代码程序,将打印的字符串通过uart串口打印出来,发现中文字符乱码,参考了keil5串口USART输出中文乱码的解决方法_zhouml_msn的博客-CSDN博客_串口输出中文 但是我解决的方法正好和他的相反;程序中要打印的汉字在,MobaXterm中显示如下: 通过记事本打开main.c文件发现它是以ANSI格式保存的, 通过:文件- 另存为- 编码格式改成UTF-8,覆盖原来的文件 再重新编译,下载就正常显示中文字符
[单片机]
keil通过<font color='red'>UART</font>串口打印汉字到串口工具乱码的问题
Tiny4412的Uart操作
#include regs.h void enable_mmu(unsigned long ttb); void init_ttb(unsigned long *ttb_base); void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa); void memset(char *buf, char ch, int size); void memcpy(char *dst, char *src, int size); void do_irq(unsigned long regs ); void uart3_putc(unsigned char ch
[单片机]
HAL+Cube MX 学习之UART串口通信
一、UART’s Configuration 在Connectivity的USART1配置中,Mode选择为Asynchronous(异步通信),Cube MX已经配置好了相关的引脚,下面的波特率没有特别要求,需要跟串口助手的波特率一致,常用的波特率是9600和115200,然后生成代码。 二、Coding in MDK 可以直接用printf来打印,打印的内容会在串口调试助手上显示,但是用printf需要添加头文件和函数, /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN
[单片机]
HAL+Cube MX 学习之<font color='red'>UART</font>串口通信
STM8 UART2
#include stm8s.h #include stm8s_conf.h #include UART2.h #include stdarg.h void UART2_Config(u32 Rate) { CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE); GPIO_Init(UART2_PORT, TX2_PIN, GPIO_MODE_OUT_PP_LOW_FAST); GPIO_Init(UART2_PORT, RX2_PIN, GPIO_MODE_IN_PU_NO_IT); UART2_Init(Rate, U
[单片机]
S5PV210的Uart应用
准备分析 S5PV210的NandFlash应用(一)出现很多bug,所以要先把Uart搞出来了。Uart一般是和clock相关联的,但是IROM中的代码已经提升了PCLK到66.5MHZ,这里就不进行CLOCK的设置了。 资源工具 同《 S5PV210的LED应用(一)》 着手写程序 为实现代码最简化,只是在LED程序的基础上进行添加,其它硬件如NandFlash,重定向等等都不涉及。函数设计如下: (1) void uart_init (void) ,初始化Uart (2) char getc (void),接收一个字符 (3) void putc (char c) ,发送一个字符 (4) puthex(
[单片机]
S5PV210的<font color='red'>Uart</font>应用
最简单的S3c2440UART功能测试
/******************************************* * 文件名称:UART.c * 实现功能:最基本的UART发送与接收 * 作者:无jianqi * 版本:1.0 **********************************************/ #include 2440addr.h //包含2440相关寄存器的设置 #include def.h //四个LED对应GPB5.6.7.8。 #define LED1 5 #define LED2 6 #define LED3 7 #define LED4 8 #
[单片机]
S3C6410之uboot回炉再造(6)异常中断处理
这篇是中断向量的存储、注释比较清晰、就不再细讲 1 /* 2 ************************************************************************* 3 * 4 * Interrupt handling 5 * 6 ************************************************************************* 7 */ 8 @ 9 @ IRQ stack frame. 10 @ 11 #define S_FRAME_SIZE 72 12 13 #define S_OLD_R0 68 1
[单片机]
RS232与RS485谁才是UART中的高速公路
串口通讯是电子工程师面对的最基本的一个通讯方式,RS-232是其中最简单的一种。然而,很多初学者往往搞不清楚UART和RS-232、RS-422、RS-485的联系和区别,本文将谈谈我对这几个概念的理解,帮助大家理清它们之间的关系。 通讯问题,和交通问题一样,也有高速、低速、拥堵、中断等等各种情况。如果把串口通讯比做交通,UART比作车站,那么一帧的数据就好比汽车。汽车跑在路上,要遵守交通规则。如果是市内,一般限速30、40,而高速公路则可以到120。而汽车走什么路,限速多少,就要看协议怎么规定了。常见的串口协议有RS-232、RS-422、RS-485等,那么谁才是UART中的高速公路?下面我们就一起来探讨一下。 一
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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