六 linux UART串口驱动代分析

发布者:数字翻飞最新更新时间:2022-04-22 来源: eefocus关键字:linux  UART  串口驱动 手机看文章 扫描二维码
随时随地手机看文章

1、对UART驱动添加设备信息


对于2440的UART,内核已经对其完整的配置不需要做写入任何的代码,


这里要说明的是,在学习的裸机的时候,我们知道,UART相应的引脚可以配置称为红外IR,这里串口2就被配置成了红外驱动。


对于平台设备,首先要说明的应该是s3c2410_uartcfg结构体,该结构体定义在,Serial_s3c.h(includelinux)文件中


structs3c2410_uartcfg {undefined


      unsigned char         hwport;   /* 硬件端口编号比如UART0  UART1 等等*/


      unsigned char         unused;  //发送和接收使能控制信号


      unsigned short        flags; //标记号


      upf_t                uart_flags;      /* 默认UART标记号,流量控制标志位*/


      unsigned int     clk_sel; //时钟选择


 


      unsigned int     has_fracval;


 


      unsigned long         ucon;      /* 对应控制寄存器UCONn*/


      unsigned long         ulcon;     /*对应格式寄存器ULCONn */


      unsigned long         ufcon;     /* 设置缓冲区的寄存器UFCONn */


};


 


在Mach-smdk2440.c (archarmmach-s3c24xx)文件中,有对其平台设备信息的描述:


static structs3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {undefined


      [0] = {undefined


             .hwport       = 0,


             .flags           = 0,


             .ucon          = 0x3c5,//00000011 1100 0101


/**************************************************************************


对应的二进制为0000 0011 1100 0101


查看数据手册可以很直观的看出来,这里是设置含义是:


接收和发送均使用中断或者查询法


将发生数据帧错误时将触发中断


当使用FIFO的时候,接收超时将产生中断,设置为低电平触发中断


UART的时钟选用PCLK


*******************************************************************/


             .ulcon         = 0x03,


/**************************************************************************


对应的二进制为0000 0000 0000 0011


这里主要设设置帧格式:


8为数据位


1为停止位


无校验位


正常模式(非红外模式)


*******************************************************************/


 


             .ufcon         = 0x51,


/**************************************************************************


对应的二进制为0000 00000101 0001


这是设置使用FIFO


使能FIFO


接收FIFO的阈值为8BYTE


接收FIFO的阈值为16BYTE


*******************************************************************/


 


      },


      [1] = {undefined


             .hwport       = 1,


             .flags           = 0,


             .ucon          = 0x3c5,


             .ulcon         = 0x03,


             .ufcon         = 0x51,


      },


      /* 设备为红外模式*/


      [2] = {undefined


             .hwport       = 2,


             .flags           = 0,


             .ucon          = 0x3c5,


             .ulcon         = 0x43, //红外模式


             .ufcon         = 0x51,


      }


};


在Mach-smdk2440.c中的smdk2440_map_io函数中有:


s3c24xx_init_uarts(smdk2440_uartcfgs,ARRAY_SIZE(smdk2440_uartcfgs));(该函数定义在Init.c (archarmplat-samsung)    中),干函数又调用:


(cpu->init_uarts)(cfg,no);


cpu->init_uarts在Common.c (archarmmach-s3c24xx)文件中,指向的是s3c244x_init_uarts(该函数定义在S3c244x.c (archarmmach-s3c24xx)),然后s3c244x_init_uarts又调用s3c244x_init_uarts函数:


void __inits3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)


{undefined


      s3c24xx_init_uartdevs("s3c2440-uart",s3c2410_uart_resources, cfg, no);


}


也就是说s3c24xx_init_uarts(smdk2440_uartcfgs,ARRAY_SIZE(smdk2440_uartcfgs));最终会被使用成:


s3c24xx_init_uartdevs("s3c2440-uart",s3c2410_uart_resources, cfg, no);


也就是,UART的平台设备定义的名字为:"s3c2440-uart"


可以,应该不容忽视的是,这里内核还定义了系统的资源,s3c2410_uart_resources,该资源在Common.c (archarmmach-s3c24xx)文件中被定义:


static structresource s3c2410_uart0_resource[] = {undefined


      [0] = DEFINE_RES_MEM(S3C2410_PA_UART0,SZ_16K),


      [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0,


                    IRQ_S3CUART_ERR0 -IRQ_S3CUART_RX0 + 1,


                    NULL, IORESOURCE_IRQ)


};


 


static structresource s3c2410_uart1_resource[] = {undefined


      [0] = DEFINE_RES_MEM(S3C2410_PA_UART1,SZ_16K),


      [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX1,


                    IRQ_S3CUART_ERR1 -IRQ_S3CUART_RX1 + 1,


                    NULL, IORESOURCE_IRQ)


};


 


static structresource s3c2410_uart2_resource[] = {undefined


      [0] = DEFINE_RES_MEM(S3C2410_PA_UART2,SZ_16K),


      [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX2,


                    IRQ_S3CUART_ERR2 -IRQ_S3CUART_RX2 + 1,


                    NULL, IORESOURCE_IRQ)


};


在这里,我们以uart0的资源为例来分析一下资源的构成:


static structresource s3c2410_uart0_resource[] = {undefined


      [0] = DEFINE_RES_MEM(S3C2410_PA_UART0,SZ_16K),


      [1] =DEFINE_RES_NAMED(IRQ_S3CUART_RX0,


                    IRQ_S3CUART_ERR0 - IRQ_S3CUART_RX0 + 1,


                    NULL, IORESOURCE_IRQ)


};


可以看到对于UART0一共定义了两个资源,其中:


[0] =DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K),表明声明的为内存资源,其实,宏DEFINE_RES_MEM被定义为:


      {                                                     


             .start = (_start),                               


             .end = (_start) + (_size) - 1,                         


             .name = (_name),                                   


             .flags = (_flags),                             


      }


其中name为NULL;也就是说,UART申请的内存资源为起始物理地址为S3C2410_PA_UART0,大小为SZ_16K,很容易可以查到S3C2410_PA_UART0对应的物理地址就是0x50000000,通过查看数据手册得到0x50000000对应的是ULCON0(UART channel 0 line controlregister,控制帧格式的寄存器)的首地址,那么为什么是SZ_16K呢?继续看数据手册,发现ULCON1的首地址是0x50004000,那么0x50004000-0x50000000=SZ_16K,所以是大小为16kBYTE;.flags = (_flags)这个标号对应的内存资源的标记号,只不过系统为每种资源设定的标记号码而已,驱动找什么类型资源就是对应这个标号找的。


补充一点的是:这里的内存资源是16Kbyte,而且申请的时候为什么只有是一个寄存器的地址,这里是因为对于控制UART0的寄存器组的地址是有规律的,也就是说每个寄存器占有四个字节,上一个寄存器的地址+4就是下一个寄存器的首地址,而ULCON0(0x50000000)就UART0寄存器组的第一个寄存器,可以理解为是该组寄存器的首地址。


查看数据手册,对于UART0来说,看一下其寄存器分配:


ULCON0  0x50000000 R/W  UART channel 0 line controlregister


 


UCON0  0x50000004 R/W  UART channel 0 controlregister


 


UFCON0  0x50000008 R/W  UART channel 0 FIFO controlregister


 


UMCON0  0x5000000C R/W  UART channel 0 Modem controlregister


 


UTRSTAT0  0x50000010 R  UART channel 0 Tx/Rx statusregister


 


UERSTAT0  0x50000014 R  UART channel 0 Rx error statusregister


 


UFSTAT0  0x50000018 R  UART channel 0 FIFO statusregister


 


UMSTAT0  0x5000001C R  UART channel 0 modem statusregister


 


UTXH00x50000020(L)


0x50000023(B)            W (by byte)     UART channel 0 transmit buffer register


 


URXH00x50000024(L)


0x50000027(B)             R (bybyte)     UART channel 0 receive bufferregister


 


UBRDIV0  0x50000028 R/W  Baud rate divisior register 0


 


 


接下来看第二个资源:


[1] =DEFINE_RES_NAMED(IRQ_S3CUART_RX0,


                    IRQ_S3CUART_ERR0 -IRQ_S3CUART_RX0 + 1,


                    NULL, IORESOURCE_IRQ)


首先把宏替换掉就是:


.start = IRQ_S3CUART_RX0,                             //74


             .end = RQ_S3CUART_ERR0 -IRQ_S3CUART_RX0 + 1,            //76-74+1       


             .name = NULL,                                


             .flags = IORESOURCE_IRQ,


对于IRQ就比较简单了,内核为每个中断都有对其唯一的IRQ号,这些号码定义在Irqs.h(archarmmach-s3c24xxincludemach)       文件中(对于中断号的问题,这些东西在裸机接扫寄存器的时候已经写的很详细了,通过中断号可以判定是哪个中断源引起的中断),可以看到:


UART0接收中断     #define IRQ_S3CUART_RX0        74


UART0发送中断     #define IRQ_S3CUART_TX0        75


UART0错误中断     #define IRQ_S3CUART_ERR0       76


在平台设备中定义的这些资源,可以通过在驱动程序通过函数:


platform_get_resource来或许相应的资源。


 


对于平台设备,暂时分析到这里,后面看驱动分析和测试部分。


 


2、对UART驱动的测试


假如够细心的话,可以在内核启动的时候看到:


s3c2440-uart.0:ttySAC0 at MMIO 0x50000000 (irq = 74, base_baud = 0) is a S3C2440

[1] [2] [3] [4] [5] [6] [7]
关键字:linux  UART  串口驱动 引用地址:六 linux UART串口驱动代分析

上一篇:七 linux LCD驱动代码分析
下一篇:linux USB 摄像头 驱动 移植,使用

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

基于ARM-LINUX平台的物联网服务器设计
  基于XSCALE PXA270处理器平台和开源Linux系统搭建ARM-Linux物联网服务器。使用51单片机连接温湿度传感模块、LED灯等外围设备,使用基于XSCALE PXA270处理器的Up-Tech嵌入式实验箱为核心服务器运行平台。首先介绍了嵌入式设备的ARM-Linux系统搭建、守护程序和CGI程序之间的通信设计,然后详细介绍了Web服务器的搭建和网络程序设计所使用的iQuery类库和AJAX技术的设计实现。   物联网是互联网应用的扩展,是一种新兴的联网技术,其核心是物与物之间的信息通信交流,也是物与人之间的交互控制。物联网技术,主要是利用各种传感器设备,例如:无线技术、射频识别(RFID)技术,各类传感器等技术设备
[单片机]
基于ARM-<font color='red'>LINUX</font>平台的物联网服务器设计
Linux移植之make uImage编译过程分析
编译出uboot可以运行的linux内核代码的命令是make uImage,下面详细介绍下生成linux-2.6.22.6/arch/arm/boot/uImage的过程: 1、vmlinux、Image、uImage、zImage的区别 2、vmlinux生成过程简介 3、uImage生成过程简介 1、vmlinux、Image、uImage、zImage的区别,在执行make uImage之后会在%生成如下几个文件Image、uImage、zImage。 vmlinux是可引导的、压缩的内核。“vm”代表“Virtual Memory”。Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制。Lin
[单片机]
<font color='red'>Linux</font>移植之make uImage编译过程分析
PIC32MX单片机外设库使用(Ⅱ)-- UART
4.4 串口应用 因为笔者硬件设计使用UART4口,然而在《PIC32 Peripheral Libraries for MPLAB C32 Compiler》库里却找不到使用UART4的库函数。历经百度百般搜索,终于获得了一点蛛丝马迹:原文如下 PIC32MX 5/6/7系列的C32用法,已經完全變了一個方式。 範例程式所用的是依新版的用法,也可以相容PIC32MX 3/4系列。 用法說明在 \MPLAB C32\doc\pic32-lib-help\下的UART-PLIB-Help.chm 另外APP1632實驗版及說明書也有提及這部份,可以參考使用。 感叹一句,神奇的万能的百度啊! 结合例程,及笔者的实际硬件,做出如下
[单片机]
linux驱动程序之电源管理之新版linux系统设备架构中关于电源管理方式的变更
新版linux系统设备架构中关于电源管理方式的变更 based on linux-2.6.32 一、设备模型各数据结构中电源管理的部分 linux的设备模型通过诸多结构体来联合描述,如struct device,struct device_type,struct class, struct device_driver,struct bus_type等。 @kernel/include/linux/devices.h中有这几中结构体的定义,这里只列出和PM有关的项,其余查看源码: struct device{ ... struct dev_pm_info power; ... } struct
[单片机]
研究UART通信端口上的射频干扰
  有客户报告其中心位于840MHz左右的RF干扰影响配置成UART的串行通信端口,该接口位于包含一个AD6903(LeMansLCR+)数字式基带处理器的调制解调器和一台主处理机之间。   出现的问题是连接到AD6903GPIO_1引脚的UARTRX信号中出现噪声,每当射频(RF)干扰源出现时,信号平均电压就会远离其期望值。平均电压的偏移幅度取决于RF源的功率和频率。   图2显示当射频功率放大器接通时,进入AD6903的GPIO_1引脚上的UARTRX信号受到影响的情况。在图2中,进入AD6903的UARTRX用粉红色表示,来自主处理机的UARTTX信号用紫色表示,功率放大器使能用黄色表示,而AD6903VEXT电源用绿色表示
[测试测量]
研究<font color='red'>UART</font>通信端口上的射频干扰
Linux PC可选用的电源管理:DPM
  谈到 PC 的 电源管理 标准,不作二想的当然是ACPI,不过这样的想法如今似乎需要一些补充,若将PC的定义更广义延伸来看,那么可使用的电源管理机制、标准将不单只有ACPI,DPM(Dynamic Power Management,动态电源管理)则是另一个可评估的选择,以下我们将对此逐一说明理由。   不是所有PC OS都支持ACPI   PC使用ACPI的电源管理机制已久,打从1996年发布首版标准以来已经使用超过10年的时间,就连Apple在2005年决议将Mac OS X移植到x86平台后,所使用的电源管理规范也一样是ACPI,由此来看真的需要选用ACPI之外的省电标准吗?   这样的疑问,主要是以
[电源管理]
<font color='red'>Linux</font> PC可选用的电源管理:DPM
基于ARM9和嵌入式Linux系统的多功能综合通信控制系统的框架
本文介绍了基于ARM9硬件平台和嵌入式Linux系统的多功能综合通信控制系统的框架设计及各模块的功能。系统采用符合POSIX.1标准的C语言编写,实现了对下位机传送数据帧的采集、分析和存储,并能根据上位机的配置指令和数据传输指令分别对串口波特率、数据时间及手机短信号码等参数进行配置和存储数据的传输。 伴随着计算机技术的迅速发展,工业数据采集已由传统的测控 电路 发展为由微型计算机、接口电路、外部通用设备和工业生产对象等组成的现代数据采集与控制系统。但是以微型计算机为核心的数据采集系统也逐渐暴露出许多缺陷:体积大,不易携带;扩展性差、成本高等。因此,以嵌入式系统为平台的数据采集和控制系统应运而生,嵌入式数据采集系统具备可靠性
[单片机]
基于ARM9和嵌入式<font color='red'>Linux</font>系统的多功能综合通信控制系统的框架
基于Linux和S3C2410的嵌入式图象传输系统设计
1 引言 如何更好的获得监控现场的图象数据一直是棘手的一个问题,传统的方法是采用CCD摄象机获取现场的视频信息,这种方法易于实现,但成本较高。随着ARM系列处理器应用的越来越广和基于linux的嵌入式技术的迅速发展,利用linux自身带有的TCP/IP协议来实现远程监控、图象传输已成为可能。本文提出的正是一种这样的方法,利用市场上很常见的中星微系列的USB摄象头来得到现场的图象数据,利用linux内核中的Video4Linux编程接口函数采集图象,并把得到的图象通过Internet传输到上位机PC上,在PC上实现图象的保存和显示。 2 硬件系统设计原理 系统的硬件功能框图如图1所示,CPU采用的是三星公司的S3C2410。该
[工业控制]

推荐帖子

STM32加密库
请教版主:STM32EncryptionLibrary库在哪里有下载STM32加密库哪里说有这个库?我怎么不知道。前阵子,在网站上看到有这个 标题 的库下载的,只是当时链接不对,下载的别的内容。现在网站上,已经没有了。是不是在测试,还没正式开放啊。另外,宣传手册上,都说有这个库了 http://www.st.com/internet/com/SALES_AND_MARKETING_RESOURCES/MARKET
cooler1981 stm32/stm8
ring buffer原理举例
假设我们有一个环形缓冲区,其大小(RING_BUFFER_SIZE)为8字节。初始情况下,缓冲区是空的:索引:01234567数据:头:^尾:^在这个例子中,头(head)和尾(tail)索引都是0,表示下一个数据应写入数组的第0位,下一个读取也应该是第0位。当我们写入3个字节的数据(例如A,B,C)后,环形缓冲区看起来将是:索引:01234567数据:头:^尾:^现在
WZH70246 汽车电子
高通芯片,烧写方法有哪些?
网上和书上很多讲得都是三星的S3C2440之类的。现在没有仿真器。也不知道下载哪个模拟器,有下载ADS的软件。SJF2440软件可以用于高通的这个芯片吗?上面讲得好乱,整理下:就是现在手头上有个现成的产品。原来的软件有问题,或改正。但是他的开发环境以及烧写的软件我这边都没有。有USB接口。是个无线上网卡。用的是东芝和美光合作的内存(型号:TY8A0A11152KCR020600922KCD)。我要什么方法把写好的镜像烧写进去?最好是软件的方法。芯片:Qualcommqs
zyz_npu 嵌入式系统
LED驱动
有谁能够上传一些关于LED驱动方面的资料吗?谢谢LED驱动可以到百度上搜搜去!百度上有很多的去LED板块看看吧??
messiceding 模拟电子
CE X86下内核编译出错,求教,急急急
系统崩溃了一次,重装的windowcewithPB,结果编译所有的工程都是报同样的2个错,BUILD:C:\\WINCE500\\PUBLIC\\COMMON\\OAK\\DRIVERS\\CEDDK\\DDK_POWER\\ddk_power.cpp(0):fatalerrorC1033:cannotopenprogramdatabase\'c:\\wince500\\public\\common\\oak\\lib\\x86\\retail\\ddk_powe
seadistant 嵌入式系统
提问+MSP430控制LCD12864
如题,用C语言写程序的时候该注意哪些??提问+MSP430控制LCD12864问题太空泛了,应具体、详细。直接套程序,出了问题再来问问题的信息量太大楼主用的哪款430其实程序完全可以仿照51的来只是IO口的控制不一样
牵手此生 微控制器 MCU
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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