一般嵌入式操作系统因为它的特殊性,往往和硬件平台密切相关连,具体的嵌入式操作系统往往只能在特定的硬件上运行。
对于刚接触RT-Thread操作系统的读者并不容易马上就获得一个和RT-Thread操作系统相配套的硬件模块,但随着计算机技术的发展,我们可以采用软件方式来模拟一个能够运行RT-Thread操作系统的硬件模块,这就是ARM公司的MDK-ARM仿真模拟环境。
MDK-ARM软件是一套完整的集成开发环境(IDE),它出自ARM公司,包括了针对ARM芯片的高效C/C++编译器;针对各类ARM设备,评估板的工程向导,工程管理;用于软件模拟运行硬件平台的模拟器;以及与市面上常见的如ST-Link,JLink等在线仿真器相连接以配合调试目标板的调试器。
MDK-ARM软件中的软件仿真模拟器,采用完全软件模拟方式解释执行ARM的机器指令,并实现外围的一些外设逻辑,从而构成一套完整的虚拟硬件环境,使得用户能够不借助真实硬件平台就能够在电脑上执行相应的目标程序。
MDK-ARM集成开发环境因为其完全的STM32F103软件仿真环境,也让我们有机会在不使用真实硬件环境的情况下直接在电脑上运行目标代码。
这套软件仿真模拟器能够完整地虚拟出 ARM Cortex-M3 的各种运行模式、外设,如中断异常,时钟定时器,串口等,这几乎和真实的硬件环境完全一致。实践也证明,本文使用到的这份 RT-Thread 入门例程,在编译成二进制代码后,不仅能够在模拟器上软件模拟运行,也能够不需要修改地在真实硬件平台上正常运行。
下面我们将选择MDK-ARM集成开发环境作为目标硬件平台来观察RT-Thread操作系统是如何运行的。
在components.c中
int $Sub$$main(void)
{
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}
RT-Thread支持多种平台和多种编译器,而rtthread_startup()函数是RT-Thread规定的统一入口点。
例如采用GNU GCC编译器编译的RT-Thread,就是直接从汇编启动代码部分跳转到rtthread_startup()函数中,并开始第一个C代码的执行的。
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* board level initalization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
#ifdef RT_USING_SIGNALS
/* signal system initialization */
rt_system_signal_init();
#endif
/* create init_thread */
rt_application_init();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
启动代码,大致可以分成4个部分:
RTT将main函数作为了用户代码入口,只需要在main函数里添加自己的代码即可。
int main(void)
{
/* user app entry */
return 0;
}
为了在进入main程序之前,完成系统功能初始化,可以使用 s u b sub sub 和 和 和super$$函数标识符在进入主程序之前调用另外一个例程,这样可以让用户不用去管main()之前的系统初始化操作。
#define LED_PIN 3
int led(void)
{
rt_uint8_t count;
rt_pin_mode(LED_PIN,PIN_MODE_UOTPUT);
for(count=0; count<10; count++)
{
rt_pin_write(LED_PIN,PIN_HIGH);
rt_kprintf("led on,count:%d\r\n",count);
rt_thread_mdelay(500);
rt_pin_write(LED_PIN,PIN_HIGH);
rt_kprintf("led on,count:%d\r\n",count);
rt_thread_mdelay(500);
}
return 0;
}
MSH_CMD_EXPORT(led,RT_THREAD first led sample);