嵌入式系统的实时时钟,至少需要提供一个精度可接受的1s事件。一般是物理定时器再进行计数后产生。比如物理定时器1ms触发一次,则计数到1000的时候可以触发一个1s事件。
实时时钟,在硬件上,需要时钟源、脉冲计数器、数字比较器。
脉冲计数器对时钟源输出的时钟进行计数,当达到一定值后和数字比较器比较,如果一致则触发硬件中断。程序在硬件中断中进行处理。
如果要保证系统的实时时钟不丢弃,则需要保持计数器不被清零,则计数器相关的电路就必须保持供电。由于这部分电路结构简单,耗电极低,一般用纽扣电池就能够完成供电并持续运行很长时间。在PC中的CMOS时间就是这种计数值。
单纯靠硬件保持计数值以及触发中断,仅仅提供了最基本的时钟保持。由于计数器的位数往往很有限,时钟频率又比较高,很快就会溢出。如果不尽快被处理,则很快会被丢失。
实时时钟还需要软件上的处理。比如硬件计数器中保持了系统时钟的ms值,并且能保持几个小时(或者至少大于系统重启时间2倍的值)。则当遇到系统异常重启,可以根据计数器中保持的数值,恢复实时时钟值。
对于具有复位保持内存的硬件系统,当前时间(一般存储为UTC时间)可以保存在复位保持内存中。当系统异常复位后,首先要检查硬件时钟是否被清零了,如果没有,则说明电池还有电,保持了复位之前的时钟值,从复位保持内存中读取之前保存的当前时间,然后再根据硬件计数器的值,换算出新的当前时间。
对于没有复位保持内存的硬件系统,为了在系统复位后保持RTC时间,就必须定期保存一个时间基点。这个定期值要根据硬件计数器翻转的时间来设计。比如硬件计数器翻转时间为3小时,则建议每1~2小时就保存一个时间基点,这样复位后,RTC时间能够被有效恢复。
虽然保存时间基点的方法比较麻烦,基点数据必须保存到FLASH等非掉电易失的器件中,但是这样做有一个好处,在对时钟要求不严格的场景下,即使硬件计数器没有被复位保持,也可以得到一个最近记录的时间(当然这个时间很可能是不准确的)。