深度探索嵌入式操作系统:从零开始设计、架构和开发
上QQ阅读APP看书,第一时间看更新

2.2.3 定时器

前面说的RTC表示的是自然时间,就是我们常说的:“现在什么时间了”,而这次说的定时器是什么呢,它表示的是从现在开始到将来某一个时刻之间的时间,比如,从下午3点到下午4点之间过去了多少时间。

定时器单元也没有在mini2440开发板上,而是在S3C2440A这个黑盒子里。

S3C2440A内部有5个16位定时器。其中定时器0、1、2、3具有脉宽调制功能。定时器4是一个无输出引脚的内部定时器。定时器0还包含用于大电流驱动的死区发生器。

定时器0和1共用一个8位预分频器,定时器2、3、4共用一个另外的8位预分频器。每个定时器都有一个可以生成5种不同分频信号的时钟分频器。每个定时器模块从相应8位预分频器得到时钟,然后再通过时钟分频器分频后得到其自己的时钟信号。8位预分频器是可编程的。

每个定时器的计数缓冲寄存器中,包含了一个当使能了定时器时被加载到递减计数器中的初始值。定时比较缓冲寄存器中,包含了一个被加载到比较寄存器中与递减计数器相比较的初始值。这种双缓冲特征保证了改变频率时定时器产生稳定的输出。

每个定时器有它自己的由定时器时钟驱动的16位递减计数器。当递减计数器到达零时,产生定时器中断请求,通知CPU定时器操作已经完成。当定时器计数器到达零时,相应的计数值将自动被加载到递减计数器以继续下一次操作。

这5个定时器所有的特性如下:

1)5个16位定时器。

2)2个8位预分频器和两个4位分频器。

3)可编程输出波形的占空比控制。

4)自动重载模式或单稳态脉冲模式。

5)死区发生。

定时器内部工作是靠时钟信号驱动的,事实上不只是定时器,CPU也是,几乎计算平台所有的部件的运行都与时钟信号有关。比如,我们这里的定时器,来一个时钟信号就对自己内部计数器的值减1,减到0时就发出中断通知CPU。分频器就是对时钟频率进行处理,得到一个比当前更低或者更高的频率,当然定时器的分频器是得到更低的时钟频率,同时配合定时器中的计数值,达到精准的定时功能。定时器输入的时钟频率计算公式如下:

定时器输入时钟频率=PCLK/{预分频值+1}/{分频值}

{预分频值}=0~255

{分频值}=2,4,8,16

PCLK是S3C2440A内部APB总线的时钟频率。

这些定时器还可以自动重复定时或者一次性定时,自动重复定时是:比如,开始设定定时器每隔2s产生一次中断,中断产生后它会继续计时到下一个2s钟又产生中断,如此反复。一次性定时是指,时间到达产生中断后就不继续定时了,直到下一次设定。

来看看定时器最常用的一个情景:我们让定时器每隔1ms产生一次中断,然后在中断处理程序中检查一个进程已经运行了多长时间,分配给这个进程的时间它是否已经用完,如果已经用完,就调度其他进程运行。如果没有定时器,我们在应用软件中写入一个死循环代码,操作系统立马就会被这个应用软件锁死,因为系统已经没有任何手段从这个应用程序手里夺回CPU的使用权了。想想吧,这有多可怕!

同样的,操作系统内核,也必须了解这个平台上的定时器,不然就会出现上述情况。但是也不会在这里详述其细节,依然等到用到它时再了解它的编程细节。