TinyOS之Blink(三) - 默认系统主时钟初始化分析

来源:互联网 发布:javascript 雪峰 编辑:程序博客网 时间:2024/06/05 22:37

对于tmote平台,基础时钟模块有3个时钟输入源:

  • LFXT1CLK:低速时钟源(32.768k低速晶振)
  • XT2CLK:高速时钟源(8M高速晶振)
  • DCOCLK:数字控制RC振荡器
基础时钟模块可提供3种时钟信号:

  • ACLK(辅助时钟):ACLK是LFXT1CLK信号经1、2、4、8分频后得到的。ACLK可由软件选作各个外围模块的时钟信号,一般用于低速外设。
  • MCLK(系统主时钟):MCLK可由软件选择来自LFXT1CLK、TX2CLK、DCOCLK三者之一,然后经1、2、4、8分频得到。MCLK主要用于CPU和系统。
  • SMCLK(子系统时钟):可由软件选择来自LFXT1CLK和DCOCLK,或者XT2CLK和DCOCLK(由具体器件决定),然后经1、2、4、8分频得到。SMCLK主要用于高速外围模块。
在本篇文章中我们主要关注MCLK(系统主时钟)的初始化过程,因为该时钟决定程序的执行效率。

硬件平台时钟初始化是在tinyos2.1/tos/platform/telosa/PlatformP.nc完成的:

command error_t Init.init() {
    call MoteClockInit.init();
    call MoteInit.init();
    call LedsInit.init();
    return SUCCESS;
  }

MoteClockInit接口在tinyos2.1/tos/platform/telosa/PlatformC.nc中进行绑定:

PlatformP.MoteClockInit -> MoteClockC;

组件MoteClockC位于tinyos2.1/tos/platform/telosb/MoteClockC.nc。在一层层的剥离之后,我们最终找到位于tinyos2.1/tos/chips/msp430/timer/msp430ClockP.nc中的系统时钟初始化的具体实现-

  command error_t Init.init()
  {
    // Reset timers and clear interrupt vectors
    TACTL = TACLR;
    TAIV = 0;
    TBCTL = TBCLR;
    TBIV = 0;

    atomic
    {
      signal Msp430ClockInit.setupDcoCalibrate();
      busyCalibrateDco();
      signal Msp430ClockInit.initClocks();
      signal Msp430ClockInit.initTimerA();
      signal Msp430ClockInit.initTimerB();
      startTimerA();
      startTimerB();
    }

    return SUCCESS;
  }
}

在这里我们主要关注Msp430ClockInit.initClocks(),其具体实现如下:

command void Msp430ClockInit.defaultInitClocks()
  {
    // BCSCTL1
    // .XT2OFF = 1; disable the external oscillator for SCLK and MCLK
    // .XTS = 0; set low frequency mode for LXFT1
    // .DIVA = 0; set the divisor on ACLK to 1
    // .RSEL, do not modify
    BCSCTL1 = XT2OFF | (BCSCTL1 & (RSEL2|RSEL1|RSEL0));

    // BCSCTL2
    // .SELM = 0; select DCOCLK as source for MCLK
    // .DIVM = 0; set the divisor of MCLK to 1
    // .SELS = 0; select DCOCLK as source for SCLK
    // .DIVS = 2; set the divisor of SCLK to 4
    // .DCOR = 0; select internal resistor for DCO
    BCSCTL2 = DIVS1;

    // IE1.OFIE = 0; no interrupt for oscillator fault
    CLR_FLAG( IE1, OFIE );
  }

从上面的程序中可以清楚的了解到,系统主时钟的时钟源来自数字DCO,频率在1M-10M。

原创粉丝点击