科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件频率和初始化实时时钟

频率和初始化实时时钟

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

频率和初始化实时时钟

作者:caimouse 来源:CSDN 2008年1月22日

关键字: 实时时钟 初始化 频率 Linux

  • 评论
  • 分享微博
  • 分享邮件
前面已经介绍进入C语言世界,就会实现更多的功能,支持更多的应用。现在就来仔细地分析源程序,并且理解各部份功能实现。
首先来看看下面的函数:
/*
 *   Returns the external clock frequency, usually the bus clock
 */
int
tgt_cpufreq()
{
    if(md_cpufreq == 0) {
       _probe_frequencies();
    }
    return(md_cpufreq);
}
 
这个函数实现检测CPU运行的频率和总线的频率。这里又调用函数_probe_frequencies()来探测CPU和总线的频率,再跟踪到那个函数的实现。如下:
 
static void
_probe_frequencies()
{
 
下面定义使用的临时变量。
 
#ifdef HAVE_TOD
        int i, timeout, cur, sec, cnt;
#endif
                                                                              
        SBD_DISPLAY ("FREQ", CHKPNT_FREQ);
                                                                               
                                                                              
#if 0
        md_pipefreq = 300000000;        /* Defaults */
        md_cpufreq = 66000000;
#else
        md_pipefreq = 120000000;        /* NB FPGA*/
        md_cpufreq = 40000000;
上面定义缺省的北桥运行频率和CPU运行的频率。
 
 
#endif
 
        clk_invalid = 1;
 
 
下面开始探测CPU和北桥的频率。
#ifdef HAVE_TOD
        init_legacy_rtc();
上面初始化RTC,就是CMOS时钟,掉电后时钟也会继续运行的。
 
        SBD_DISPLAY ("FREI", CHKPNT_FREQ);
 
        /*
         * Do the next twice for two reasons. First make sure we run from
         * cache. Second make sure synched on second update. (Pun intended!)
         */
        for(i = 2; i != 0; i--) {
                cnt = CPU_GetCOUNT();
                timeout = 10000000;
                while(CMOS_READ(DS_REG_CTLA) & DS_CTLA_UIP);
                                                                              
                sec = CMOS_READ(DS_REG_SEC);
                                                                               
                do {
                        timeout--;
                        while(CMOS_READ(DS_REG_CTLA) & DS_CTLA_UIP);
                                                                              
                        cur = CMOS_READ(DS_REG_SEC);
                } while(timeout != 0 && cur == sec);
                                                                              
                cnt = CPU_GetCOUNT() - cnt;
                if(timeout == 0) {
                        break;          /* Get out if clock is not running */
                }
        }
上面代码第一次运行,把有所有指令都加载到缓存,第二次运行时,通过读取CP0的计数器值在1分钟内存的差值来计算北桥的频率。
 
                                                                         
    /*
     * Calculate the external bus clock frequency.
     */
    if (timeout != 0) {
       clk_invalid = 0;
       md_pipefreq = cnt / 10000;
       md_pipefreq *= 20000;
       /* we have no simple way to read multiplier value
        */
       md_cpufreq = 66000000;
    }
上面代码就是计算出来北桥频率和CPU频率。
 
                                                                               
#endif /* HAVE_TOD */
}
 
到这里就已经把北桥和CPU运行频率计算出来了。在这个函数里还初始化了南桥芯片上的RTC时钟,调用函数init_legacy_rtc()实现的。
 
static void init_legacy_rtc(void)
{
        int year, month, date, hour, min, sec;
        CMOS_WRITE(DS_CTLA_DV1, DS_REG_CTLA);
        CMOS_WRITE(DS_CTLB_24 | DS_CTLB_DM | DS_CTLB_SET, DS_REG_CTLB);
        CMOS_WRITE(0, DS_REG_CTLC);
        CMOS_WRITE(0, DS_REG_CTLD);
        year = CMOS_READ(DS_REG_YEAR);
        month = CMOS_READ(DS_REG_MONTH);
        date = CMOS_READ(DS_REG_DATE);
        hour = CMOS_READ(DS_REG_HOUR);
        min = CMOS_READ(DS_REG_MIN);
        sec = CMOS_READ(DS_REG_SEC);
        if( (year > 99) || (month < 1 || month > 12) ||
                (date < 1 || date > 31) || (hour > 23) || (min > 59) ||
                (sec > 59) ){
                /*
                printf("RTC time invalid, reset to epoch.\n");*/
                CMOS_WRITE(3, DS_REG_YEAR);
                CMOS_WRITE(1, DS_REG_MONTH);
                CMOS_WRITE(1, DS_REG_DATE);
                CMOS_WRITE(0, DS_REG_HOUR);
                CMOS_WRITE(0, DS_REG_MIN);
                CMOS_WRITE(0, DS_REG_SEC);
        }
        CMOS_WRITE(DS_CTLB_24 | DS_CTLB_DM, DS_REG_CTLB);
                                                                               
    //printf("RTC: %02d-%02d-%02d %02d:%02d:%02d\n",
    //    year, month, date, hour, min, sec);
}
上面初始化时间来24小时、二进制的方式返回时钟数据。后面的系统,就可以读取这里的时间作为系统时间了。
 
上面分析了怎么样探测CPU和北桥的运行频率,以及初始化南桥的实时时钟。
 


查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章