TinyOS2.x启动顺序

对于嵌入式系统来说,系统的编译过程和启动顺序是至关重要的,对这两部分的了解程度直接关系到对系统移植、裁剪和配置的相关操作。在这篇文章中我们来看一看TinyOS2.x是如何启动的。需要强调的是,这里所涉及的系统版本是2.x而不是1.x,这两个版本还是有很大的区别的。

TinyOS2.x的启动代码其实很清晰的,其具体的实现代码在tinyos2.x/tos/system/RealMainP.nc中:

int main() @C() @spontaneous() {
atomic
{
platform_bootstrap();

call Scheduler.init();

call PlatformInit.init();


while (call Scheduler.runNextTask());

call SoftwareInit.init();


while (call Scheduler.runNextTask());
}

__nesc_enable_interrupt();

signal Boot.booted();

call Scheduler.taskLoop();

return -1;
}

组件RealMainP是被同一目录下的MainC组件调用的(几乎每个应用在顶层配置文件中都会引入MainC组件的)。下面我们详细分析下RealMainP模块中的内容。

首先,该模块中的main()函数是自发运行的,当然该函数也是系统启动的入口。

platform_bootstrap():这是系统调用的第一个命令,主要用于配置内存系统和设置处理器的工作模式。但通常情况下该函数为空。头文件tinyos2.1/tos/syetem/tos.h中包含了该函数的默认实现,即不做任何操作。如果某个平台需要将这个默认实现换成其他的具体操作,可以在该平台的platform.h文件里用#define语句声明。

Scheduler.init():调度器初始化。

PlatformInit.init():平台初始化(可以参考前面的文章《TinyOS之Blink(二) - Platform初始化分析》)。

while (call Scheduler.runNextTask()):检测初始化过程中是否有任务发布,如果有就先执行任务。

SoftwareInit.init():不直接依赖于硬件资源的组件初始化都应绑定Init(SoftwareInit接口是Init接口的别名)接口到MainC组件的SoftwareInit接口(但在tinyos2.1中并为找到Init接口的具体实现,也就是说Init接口是和哪一个模块进行绑定的?)。

__nesc_enable_interrupt():中断使能。

signal Boot.booted():这个booted事件就类似于用户角度的main函数,是实际应用程序的入口。

call Scheduler.taskLoop():循环运行任务调度器。

至此,系统启动完毕。

你可能感兴趣的:(OS)