微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440上RTC时钟驱动开发实例讲解

S3C2440上RTC时钟驱动开发实例讲解

时间:11-20 来源:互联网 点击:
一、开发环境
  • 主 机:VMWare--Fedora 9
  • 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4
  • 编译器:arm-linux-gcc-4.3.2

二、相关概念

1、平台设备:
通常在Linux中,把SoC系统中集成的独立外设单元(如:I2C、IIS、RTC、看门狗等)都被当作平台设备来处理。在Linux中用platform_device结构体来描述一个平台设备,在2.6.30.4内核中定义在:include/linux/platform_device.h中,如下:

struct platform_device {
const char* name;//设备名称
intid;
struct devicedev;
u32num_resources;//设备使用各类资源的数量
struct resource* resource;//设备使用的资源

struct platform_device_id*id_entry;
};

现在你不必深入理解这个结构体,只要知道在Linux中是用这个结构体来定义一些平台设备的。比如在:arch/arm/plat-s3c24xx/devs.c中就定义了很多平台设备,下面我就只贴出RTC这一种的:

* RTC */
static struct resource s3c_rtc_resource[] = {//定义了RTC平台设备使用的资源,这些资源在驱动中都会用到
[0] = {//IO端口资源范围
.start = S3C24XX_PA_RTC,
.end = S3C24XX_PA_RTC + 0xff,
.flags = IORESOURCE_MEM,
},
[1] = {//RTC报警中断资源
.start = IRQ_RTC,
.end = IRQ_RTC,
.flags = IORESOURCE_IRQ,
},
[2] = {//TICK节拍时间中断资源
.start = IRQ_TICK,
.end = IRQ_TICK,
.flags = IORESOURCE_IRQ
}
};

struct platform_device s3c_device_rtc = {//定义了RTC平台设备
.name = "s3c2410-rtc",//设备名称
.id = -1,
.num_resources = ARRAY_SIZE(s3c_rtc_resource),//资源数量
.resource = s3c_rtc_resource,//引用上面定义的资源
};

EXPORT_SYMBOL(s3c_device_rtc);

好了,定义了平台设备,那系统是怎么来使用他的呢?我们打开:arch/arm/mach-s3c2440/mach-smdk2440.c这个ARM 2440平台的系统入口文件,可以看到在系统初始化函数smdk2440_machine_init中是使用platform_add_devices这个函数将一些平台设备添加到系统中的,如下:(至于系统是如何实现添加平台设备的,这里我们不必研究,这些Linux系统都已经做好了的,我们要研究的是后面平台设备的驱动是如何实现的)

static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,DE>

&s3c_device_rtc,//这里我们添加上RTC平台设备,默认是没添加的
};//平台设备列表,也就是说我们要使用一个新的平台设备要先在上面定义,然后加到这个列表中,最后到驱动层去实现该设备的驱动

static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
//将上面列表中的平台设备添加到系统总线
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}

2、平台设备驱动:
这里所讲的平台设备驱动是指具体的某种平台设备的驱动,比如上面讲的RTC平台设备,这里就是指RTC平台设备驱动。在Linux中,系统还为平台设备定义了平台驱动结构体platform_driver,就好比系统为字符设备定义了file_operations一样,但不要把平台设备跟字符设备、块设备、网络设备搞成了并列的概念,因平台设备也可以是字符设备等其他设备。注意:在被定义为平台设备的字符设备的驱动中,除了要实现字符设备驱动中file_operations的open、release、read、write等接口函数外,还要实现平台设备驱动中platform_driver的probe、remove、suspend、resume等接口函数。好了,在我们搞明白上面这些后,下面我们就来具体详细分析讲解RTC平台设备的驱动现实。

三、实例讲解

1、RTC在Linux中的整体结构:
就个人理解,RTC在Linux中整体结构分为两个部分。第一个是部分就是上面所讲的作为平台设备被挂接到系统总线中,这里我把他叫做设备层(呵呵,可能不是很准确的叫法);第二部分就是驱动部分,这里叫做驱动层。在Linux中要使一个驱动在不同的平台中都能够使用似乎是不可能的,所以我们先看2.6.30.4内核驱动中的RTC部分是单独的一个文件夹,在文件夹中包含了很多不同体系结构的RTC驱动,当然也有S3C2440的RTC驱动,然而在这些驱动中他们都使用了一组文件里面的方法,那么这组文件就是RTC的核心(注意这里的核心不是指对RTC硬件的操作,指的是对RTC操作的方法。对硬件寄存器的操作还是在具体的驱动中)。好了,我们还是用图来说明这种关系吧!!

2、RTC硬件原理图分析:以下是S3C2440AL内部集成的RTC模块结构图和一个外部

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top