设为首页 加入收藏

TOP

源码解读·RT-Thread操作系统从开机到关机(二)
2019-08-27 07:20:57 】 浏览:102
Tags:源码 解读 RT-Thread 操作系统 开机 关机
tern
void ExtraFunc(void); extern void $Super$$foo(void); /* this functionis called instead of the original foo() */ void $Sub$$foo(void) { ExtraFunc(); /* does some extra setup work */ $Super$$foo(); /* calls the original foo() function */ /* To avoid calling the original foo() function * omit the $Super$$foo(); function call. */ }
上例中原本有一个原始函数叫做foo,但是现在通过$Sub$$foo来劫持所有调用foo的地方,自动会调用$Sub$$foo,然后新的$Sub$$foo里面先调用自己的扩展实现ExtraFunc后,再接着调用原始版本的foo函数,不过调用原始的foo是加了前缀$Super$$的$Super$$foo.

当使用RT-Thread操作系统开启RT_USING_USER_MAIN后就是利用这种骚操作来完成RT-Thread操作系统的初始化过程的。(代码摘录自components.c)

extern int $Super$$main(void);
/* re-definemain function */
int $Sub$$main(void)
{
    rtthread_startup();
    return 0;
}
关于rtthread_startup函数稍后再讲解,不过先接着看下面这个函数:
/* the systemmain thread */
void main_thread_entry(void*parameter)
{
    extern int main(void);
    extern int $Super$$main(void);
 
    /* RT-Thread components initialization*/
    rt_components_init();
 
    /* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
    $Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
    main();
#endif
}
上面这个函数其实是个小任务,就是完成组件初始化后再跳转到用户main函数的。这个小任务在rtthread_startup中调用rt_application_init时创建的,所以此时rt-thread系统早就以经跑起来了。也就是说当调用rtthread_startup后正常情况就不再会返回到原来的调用地方,接下来会交给系统的调度器去接管,切换运行任务去了。看下面的代码了解rt_application_init:
void rt_application_init(void)
{
    rt_thread_t tid;
 
#ifdef RT_USING_HEAP
    tid = rt_thread_create("main", main_thread_entry, RT_NULL,
                          RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
    RT_ASSERT(tid != RT_NULL);
#else
    rt_err_t result;
 
    tid = &main_thread;
    result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
                            main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
    RT_ASSERT(result == RT_EOK);
    
    /* if not define RT_USING_HEAP, using toeliminate the warning */
    (void)result;
#endif
 
    rt_thread_startup(tid);
}
至此,关于各种main的子子孙孙以经差不多了解清楚了,其流程大概如下:

ResetHandle->__main->$Sub$$main->(rtthread_startup->rt_application_init->main_thread_entry)->$Super$$main。

其中$Super$$main就是我们的用户main函数。如果没有启用RT_USING_USER_MAIN那就简单了,其流程如下:

ResetHandle->__main->main

接下来再接着分析$Sub$$main中调用的rtthread_startup函数。

RT-Thread操作系统的传统初始化与自动初始化组件

这里着重讨论rtthread_startup函数,因为这就是RT-Thread操作系统的入口和初始化流程。不过既然说到rtthread_startup函数了,就不得不一起介绍一下RT-Thread操作系统的自动初始化组件了。

rtthread_startup函数是一个函数调用链,依次调用各个阶段的初始化函数,并在最后启动调度器不再返回。代码摘录自components.c

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();
 
    /* board level initialization
     * NOTE: please initialize heap insideboard 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 */
首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇解决SDL/SDL.h: No such file or .. 下一篇初级模拟电路:3-2 BJT的工作原理

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目