在外企做服务器开发, 目前是项目经理, 管理两个server开发的项目。不做嵌入式好久了。
全部博文(197)
分类: LINUX
2007-04-04 09:59:11
|
|
|
事实上 , 这篇文章还是比较浅的 , 最近在培训新人写driver , 就是从watchdog ==》 RTC ==》 UART 驱动 这个思路走的 ,
有空我再整理一下, 希望可以对新人有帮助。
RTC driver
框架以及具体的s3c2410-rtc.c情景分析(beta2)
/*
* (C) Copyright 2007
* RTC driver 框架以及具体的s3c2410-rtc.c 的情景分析 bob_zhang2004@163.com
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
Author :BobZhang(张林宝,linuxforum id 为bob2004) ,欢迎大家一起讨论补充
Mail :
msn :
感谢之前wheelz对我的帮助!在此谢过!
Kernel Version :Linux-2.6.11-1
分析工具 : Source Insight 3.50.0045
在学习如何写driver的过程中, 我发现入门很容易, 不过想要进一步提高就很困难,究其原因,一个主要的原因就是 实践的机会太少, 另外一个原因就是写driver需要对hardware有比较熟悉,能看懂datasheet . 显然, 光能写一个比较简单的hello world module 离driver开发还是比较远的. 我也是一直在这个矛盾中徘徊,因为工作中修改driver并不是工作的重心,但是又非常喜欢研究分析linux kernel的代码,而研究后练手的机会又只能从driver入手.
现在研究s3c2410的朋友特别多, 我也希望通过能porting 2.6.18 or higher 到我们自己的板子上去来提高自己的kernel水平,同时也可以参考s3c2410的相关文档.无意中看rtc的部分,觉得对怎么看datasheet有点茅塞顿开!对怎么写driver的那层窗户纸突然间破了. 我发现s3c2410 的cpu的datasheet定义的非常清晰,而且,s3c2410-rtc.c 和 s3c2410_wdt.c 的driver 也写的非常直观明了, 非常利于我们想要提高driver开发水平的R&D来练手.
所以,就萌发了写一个情景分析的念头 , 一来,可以把这些日子一直困扰自己的问题贴出来,自己如何解决的,二来,可以把自己的分析总结出来,作个备忘录,也可以为更多苦于无法提高自己的新手有一个提高自己的机会! 我对driver开发经验不多, 很多都是停留在分析上,如果有错误,还望大家多多指点,加以补充!谢谢!
主要讨论的问题:
l 针对RTC ,如何看 s3c2410的datasheet中的RTC定义的部分.
l S3c2410-rtc.c 的具体代码分析
l 关于怎么写driver的一些讨论
l 如何更多的实践, 比如RTC的架构熟悉了以后, 可以进一步研究一下watchdog ,再具体看datasheet .
l 从应用的角度,总结一下driver中常用的一些机制,纯粹是从应用的角度: 比如:同步与互斥的操作(spinlock , mutex , semaphore等等的用法,再跟上一些例子,便于以后写driver的时候直接复制粘贴) , 读写register , 如何定义自己的头文件. 这些我都会把自己这两年复制的经典的例子,粘贴出来.
主要涉及的c文件:
arch/arm/mach-s3c2410/devs.c à 主要包含了各个部件的resource的定义.我们主要看rtc部分的定义。
arch/arm/common/rtctime.c à 一个arm平台通用的rtc函数,它实际上隐蔽了各个不同rtc driver的差异性。
drivers/char/s3c2410-rtc.c à 具体的s3c2410 cpu 上的rtc chip的驱动程序。
Datasheet中关于RTC的部分还是非常简短的, 看起来比较容易, 我们只要对照datasheet 和 rtc-regs.h 就可以了。 重点就是地址部分。
举个例子:
REAL TIME CLOCK CONTROL (RTCCON) REGISTER |
The RTCCON register consists of 4 bits such as the RTCEN, which controls the read/write enable of the BCD registers, CLKSEL, CNTSEL, and CLKRST for testing. |
RTCEN bit can control all interfaces between the CPU and the RTC, so it should be set to 1 in an RTC control routine to enable data read/write after a system reset. Also before power off, the RTCEN bit should be cleared to 0 to prevent inadvertent writing into RTC registers. 从这里就可以理解到RTCEN的作用了, 它是用来控制cpu与RTC之间的接口。 只有这个bit 置1 , cpu才可以往RTC clock寄存器write ,否则无法操作寄存器。尤其是在关机之前,务必要reset 0 , 防止无序随机的数据写入RTC clock中去。 |
Register |
Address |
R/W |
Description |
Reset Value |
RTCCON |
0x57000040(L) |
R/W |
RTC control register |
0x0 |
|
0x57000043(B) |
(by byte) |
|
|
RTCCON |
Bit |
Description |
Initial State | |
CLKRST |
[3] |
RTC clock count reset. |
0 | |
|
|
0 = No reset, 1 = Reset |
| |
CNTSEL |
[2] |
BCD count select. |
0 | |
|
|
0 = Merge BCD counters |
| |
|
|
1 = Reserved (Separate BCD counters) |
| |
CLKSEL |
[1] |
BCD clock select. |
0 | |
|
|
0 = XTAL 1/215 divided clock |
| |
|
|
1 = Reserved (XTAL clock only for test) |
| |
RTCEN |
[0] |
RTC control enable. |
0 | |
|
|
0 = Disable |
1 = Enable |
|
|
|
NOTE: Only |
BCD time count and read operation can be performed. |
|
从这里我们可以得出以下信息:
RTCCON的物理地址是:0x57000040(L) ,可读可写,初始值是0x0
不过里面没有说多少bit的寄存器 ,不过起作用的也就是bit0~bit3 ,而且实际上,真正有用的也就是 bit0和bit3 而已。
那么我们怎么定义自己的头文件呢?
事实上0x57000040(L) 只是个物理地址, 我们知道在有MMU的情况下, cpu是不能直接访问物理地址的, 只能访问虚拟地址。 一般情况下我们是用request_mem_region() 申请一块resource 空间, 然后利用ioremap() 函数把这段物理地址映射到虚拟地址上去 , 然后才可以访问。 由于RTC的寄存器是连续编址的,因此,我们可以把RTC物理地址,size映射到虚拟地址上去, 然后根据offset ,就可以访问RTC clock的寄存器了。
.....
剩下的部分, 请参看附件中的word档案或者pdf文件
chinaunix网友2008-05-25 12:37:36
学习了,linux内核真是改的太快了,对照了一下2.6.25发现一些文件竞然没有了比如.arch/arm/mach-s3c2410/devs.c。多谢了,希望以后能发更多的文章来让我们学习。