随性写的,不够完整,暂时先记着,还有一些没搞清楚呢!~
近日在做新版内核的移植工作,将原来的BSP弄进最新内核2.6.31-rc7中(已经又出新的了)。
在改写系统定时器(sys_timer)部分时,发现总缺少什么东西,我也不知道少什么,老大的提议+参考大牛的代码,发现这个BSP竟然没有clock管理的代码,不过也对,他们是本着能跑的理念来完成这个BSP,没有用到的就省略了,也不能怪他们。那我们就得自己实现咯!硬件、时钟对我来说还是比较吃力的,原理至今还不太清楚,参看了几块板子的内核代码和datasheet,发现时钟这些,起码在名字上是基本同一的,原来我还以为每个板子自己瞎定的。
时钟管理,主要的功能是使能某个时钟,因为一个时钟源通过PLL出来的频率,再加上divisor处理,就能达到可编程的时钟频率,每个硬件模块都可以有自己的频率,每个硬件模块都可以单独开关时钟。所以需要管理,因为多嘛!
我们的板子主要涉及到的时钟有:
PLL:时钟源出来时钟,这里可以理解为xtal时钟源;
PLL_CPU:为其他硬件模块提供时钟的时候;
PLL_USB:为USB HOST 控制器时钟
FCLK: CPU 时钟(ARM926)
HCLK: AHB总线上的硬件模块时钟
PCLK: PHB总线上的硬件模块时钟
RTC:实时时钟
WDT:看门狗时钟
TIMER:定时器时钟
因为TIMER的时钟源是可以选择的,1KHZ或者PCLK,如果选择PCLK,那就得从上面的层级结构中算出PCLK频率为定时器所用,时钟管理看似可有可无,不过为了扩展,有还是比没有好。
下面就是实现了,发现clk在arm linux下,主要有2类,一类如 mach-s3c24xx之类的,自己管理clock,一类如 mach-epxxx使用common/clock.c 的代码,通过内核来管理clock,这个common对代码 是 Russell 写的,也是新提倡的方式,那我当然得用,直接把mach-epxxx/clock.c 和头文件copy过来,根据需要加以修改,ops都不需要,提供3个API就是了: enable / disable / get_rate,因为我们这块板子时钟操作比较简单,这已经够用了,就这样实现啦!~呵呵,没啥东西,对了,还需要在mach-xxx/include/mach/下加个 clkdev.h,复制其他人的就好了,为什么需要,看代码就知道了。
也就是说,在arm linux 下实现 clock 管理很简单,3个文件:
mach-xxx/clock.c
mach-xxx/clock.h
mach-xxx/include/mach/clkdev.c
需要的其他文件就是,注册一些时钟,做做工作,配置配置,需要用的时候,clk_get()就能得到,然后操作,相当简单。我们现在就是这样做的。