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
上一篇:七 linux LCD驱动代码分析
下一篇:linux USB 摄像头 驱动 移植,使用
推荐阅读最新更新时间:2024-11-17 02:14
推荐帖子
- 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
设计资源 培训 开发板 精华推荐
- ADMV8420-EVALZ,用于 ADMV8420 11 至 20 GHz 可调带通滤波器的评估套件
- LT1912 的典型应用 - 36V、2A、500kHz 降压型开关稳压器
- AM1G-1207DZ ±7.2V 1 瓦 DC/DC 转换器的典型应用
- 使用 Analog Devices 的 LT8608IMSE 的参考设计
- C8051F560DK,C8051F560 8051 MCU 工业应用开发系统
- LT6656BIS6-2.048、2.048V 低功率精密高压电源监视器的典型应用
- 基于HK32F030M的单手遥控器
- LT3990HMSE-3.3 5V 降压转换器的典型应用
- NCP59801MTADJTAGEVB:NCP59801 WDFNW6 2x2 ADJ 评估板
- type-c口 stlink