日期:2014-05-16  浏览次数:20539 次

linux平台设备(以RTC为例)

只要和内核本身运行依赖性不大的外围设备(换句话说只要不在内核运行所需的一个最小系统之内的设备),相对独立的,拥有各自独自的资源(addresses and IRQs),都可以用platform_driver实现。如:lcd,usb,uart等,都可以用platfrom_driver写,而timer,irq等最小系统之内的设备则最好不用platfrom_driver机制,实际上内核实现也是这样的。

LINUX平台设备分为

1 设备层(主要是描述设备资源)?
2 驱动层(我们写驱动要实现的)

?
设备层:主要定义个设备的资源。?
用platform_device结构体来描述一个平台设备。定义在(/include/LINUX/platform_device.h)?
struct platform_device {?
const char * name;//设备名称?
int?? id;?
struct device dev;?
u32?? num_resources;//设备使用资源的数量?
struct resource * resource;//使用的资源?
};?
例如:/* RTC */?
/**************************************************************/?
arch/arm/plat-s3c24xx/devs.c中就定义了很多平台设备,截取RTC的设备结构?
static struct resource s3c_rtc_resource[] = {?
[0] = {//IO端口资源范围?
?? .start = S3C24XX_PA_RTC,?
?? .end?? = S3C24XX_PA_RTC + 0xff,?
?? .flags = IORESOURCE_MEM,//定义了这个资源的类型(通俗点就是要内存映射的类型)/include/linux/ioport.h?
},?
[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 = {?
.name??? = "s3c2410-rtc",//RTC名字(与驱动里面的name要一样)?
.id??? = -1,?
.num_resources?? = ARRAY_SIZE(s3c_rtc_resource),(对上面的s3c_rtc_resource求值,求出的是定义了几个资源)?
.resource?? = s3c_rtc_resource,//对应上面的 struct resource s3c_rtc_resource[]?
};

EXPORT_SYMBOL(s3c_device_rtc);?
/**************************************************************/?
以上定义了RTC所有的设备资源!然后我们要使用这些资源,就要添加到内核里面!?
打开arch/arm/mach-s3c2440/mach-smdk2440.c这个ARM 2440平台的系统入口文件。里面有这两个!?
static struct platform_device *smdk