Main组件分析一(TinyOS1.x)
[ 2008-5-9 20:27:00 | By: 三月春分 ]
 
在《最简单的tinyos应用程序》中提到去掉Timer组件后,“表面上”只适用了两个系统组件:LedsCMain,上篇文章《LedsC组件分析》已经分析了LedsC组件的实现,此文试图对Main组件进行解剖和并分析,让大家对tinyos(程序)的启动有个大概了解 
      在分析之前,有一点必须说明的是:在此文分析的Main组件是 tinyos-1.x\tos\platform\msp430目录下的Main组件,而不是tinyos-1.x\tos\system目录下的Main组件。对此,大家可能觉得有点奇怪,由于tinyos 1.x本身的缺陷(庆幸的是tinyos 2.x已经对其进行了改进)system目录下的Main组件只是针对一些老的节点的,例如mica系列的节点。而一些新的节点平台会有自己的Main组件的实现。由于本人使用的是telosb节点,所以分析的是msp430文件夹里的Main组件。不过这两处的实现大同小异,不同之处读者可以自己分析。 
       老规矩,下面先将Main组件的代码拷贝出来,方便大家查看。 
    //file Main.nc 
    configuration Main 
       { 
        uses interface StdControl; 
       } 
       implementation 
       { 
         components MainM, HPLInitC; 

         StdControl = MainM.StdControl; 
        MainM.hardwareInit -> HPLInitC; 
       } 
       //file MainM.nc 
     module MainM 
       { 
         uses command result_t hardwareInit(); 
         uses interface StdControl; 
       } 
       implementation 
       { 
        int main() __attribute__ ((C, spontaneous)) 
        { 
           call hardwareInit(); 
           TOSH_sched_init(); 
     
           call StdControl.init(); 
           call StdControl.start(); 
           __nesc_enable_interrupt(); 

          for(;;) { TOSH_run_task(); } 
        } 
       } 
       首先分析Main,Main里的实现只有几句,作用大家都知道了,只不过是对一些用到的组件进行“装配”,对使用到的一些接口进行连接。下面还是集中精力对付MainM 
    MainM里面的实现只有一个main函数,此函数相当于c语言的main函数,在全局变量等构造好之后,tinyos程序从此处开始执行。 
    第一个语句:call hardwareInit();初始化您所用的平台的硬件,稍后将对其进行分析; 
    第二个语句:TOSH_sched_init();是初始化调度程序(scheduler)用到的东西,稍后将对其进行详细分析; 
   第三四个语句: call StdControl.init();   call StdControl.start();是调用您在您的程序里实现的StdControl 
接口。 
   第五个语句:__nesc_enable_interrupt();是激活中断,没什么好讲。 
   第六个语句: for(;;) { TOSH_run_task(); }是个死循环。是调度程序(scheduler)的核心,稍后将对其进行详细分析; 
      从上面可以看出,main 函数可以分为几组相关的语句: 
1、  call hardwareInit(); 
2、  TOSH_sched_init(); 
       for(;;){TOSH_run_task();} 
3、  call StdControl.init(); 
       call StdControl.start(); 
4、__nesc_enable_interrupt(); 
好钢应该用在刀刃上,34就不分析了。 


    第一组:call hardwardInit(); 


   调用的是相同目录下的HPLInitC组件的 init()命令,而HPLInitC里的init()命令实际上是在HPLInitM实现(在此好象感觉nesc总是拖泥带水的,好烦它啊,不过烦我一个人就好了,以后有我整理并分析给大家看。)其代码如下: 
       command result_t init() 
  { 
    TOSH_SET_PIN_DIRECTIONS(); 
    call MSP430ClockControl.init(); 
    call MSP430ClockControl.start(); 
    return SUCCESS; 
  } 
       在此值得注意的是一个函数:TOSH_SET_PIN_DIRECTIONS();该函数的实现在\tinyos-1.x\tos\platform\telosb目录下的hardware.h头文件中(大家还记不记得我分析的是什么节点的代码?如果不记得,感紧回到本文前面去浏览一下)。 
void TOSH_SET_PIN_DIRECTIONS(void) 
{ 
  // reset all of the ports to be input and using i/o ality 
  atomic 
  { 
  P1SEL = 0; 
  P2SEL = 0; 
  P3SEL = 0; 
  P4SEL = 0; 
  P5SEL = 0; 
  P6SEL = 0; 

  P1DIR = 0xe0; 
  P1OUT = 0x00; 
  P2DIR = 0x7b; 
  P2OUT = 0x10; 
P3DIR = 0xf1; 
  P3OUT = 0x00; 
  P4DIR = 0xfd; 
  P4OUT = 0xdd; 
  P5DIR = 0xff; 
  P5OUT = 0xff; 
  P6DIR = 0xff; 
  P6OUT = 0x00; 
  P1IE = 0; 
  P2IE = 0; 

  // the commands above take care of the pin directions 
  // there is no longer a need for explicit set pin 
  // directions using the TOSH_SET/CLR macros 

  // wait 10ms for the flash to startup 
  TOSH_uwait(1024*10); 
  // Put the flash in deep sleep state 
  TOSH_FLASH_M25P_DP(); 
  }//atomic 
} 
       从代码的注释中可以了解到,那些赋值操作是设置管脚使之可以输入并打算在以后使用其i/o功能。接下来就是等待10ms并启动flash 
TOSH_SET_PIN_DIRECTIONS()函数后面的两个语句先打住,放到《MSP430ClockC组件分析》中分析了。(请接着看Main组件分析(二)) 
 
 

发表评论:

    大名:
    密码: (游客无须输入密码)
    主页:
    标题:

时 间 记 忆
最 新 评 论
专 题 分 类
最 新 日 志
最 新 留 言
搜 索
用 户 登 录
友 情 连 接
博 客 信 息