用$Super$$和$Sub$$对函数进行重定义

  • 学习2261次

$Super$$和$Sub$$是KEIL编译器中可以使用的两个特殊符号。

  • $Super$$ 这个符号用来直接调用原始函数,例如原始函数名为foo(),使用此符号可以写为$Super$$foo()。
  • $Sub$$ 这个符号用来代替原始的函数,例如原始函数名为foo(),使用此符号可以写为$Sub$$foo()。

ARM官方介绍链接:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0377g/pge1362065967698.html

实例:在RTT源码中,程序启动流程中用到了这两个知识点。

1、运行 $Sub$$main()

int $Sub$$main(void)
{
    rt_hw_interrupt_disable();
    rtthread_startup();
    return 0;
}

2、进入rtthread_startup()

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;
}

3、进入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 to eliminate the warning */
    (void)result;
#endif

    rt_thread_startup(tid);
}

4、运行main_thread_entry任务

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)
    $Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
    main();
#endif
}

5、运行$Super$$main()

$Super$$main()实际上就是调用main,这里的main就是main.c中的main函数

int main(void)
{
    return 0;
}

总结,启动流程为:

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