您的位置:首页 > 大数据 > 物联网

RIOT(基于CC2538cb)学习1-启动分析/寻找int main()

2016-01-21 11:29 573 查看
硬件平台:cc2538cb (cc2538sf53)



TinyOS和Contiki的启动依赖start-gcc.c,RIOT则选择在cortex_common中实现;

三个OS本质启动没有区别都是进入reset_handler_default;该实现在RIOT\cpu\cortexm_common\vectors_cortexm.c中,对于ISR表等的分析就省略了;

来看一下代码实现:


void reset_handler_default(void)
{
    uint32_t *dst;
    uint32_t *src = &_etext;

    pre_startup();

#ifdef DEVELHELP
    uint32_t *top;
    /* Fill stack space with canary values up until the current stack pointer */
    /* Read current stack pointer from CPU register */
    asm volatile ("mov %[top], sp" : [top] "=r" (top) : : );
    dst = &_sstack;
    while (dst < top) {
        *(dst++) = STACK_CANARY_WORD;
    }
#endif

    /* load data section from flash to ram */
    for (dst = &_srelocate; dst < &_erelocate; ) {
        *(dst++) = *(src++);
    }
    /* default bss section to zero */
    for (dst = &_szero; dst < &_ezero; ) {
        *(dst++) = 0;
    }

    post_startup();

    /* initialize the board (which also initiates CPU initialization) */
    board_init();

#if MODULE_NEWLIB
    /* initialize std-c library (this must be done after board_init) */
    extern void __libc_init_array(void);
    __libc_init_array();
#endif

    /* startup the kernel */
    kernel_init();
}


pre_startup();post_startup();在文件中是空函数;

和TinyOS和Contiki一样,先完成rom,bss段初始化;Contiki-3.0版本的2538段初始化部分的写法个人觉得不如2.7版本的写法直观,不懂的朋友也可以去看一下arm-none-eabi-gcc提供的文档和源码例子或者去参考TI给的驱动库,他们的startup文件的写法;

我们具体关心的有board_init()和kernel_init()函数;

board_init()在RIOT\boards\cc2538cb下board.c中:


void board_init(void)
{
    /* initialize the CPU */
    cpu_init();

    /* initialize the boards LEDs */
    led_init();
}


代码简单 不做分析;

下面来到重点函数,我们将看到main函数冒泡了,总算逮到你了

kernel_init()在RIOT\core下kernel_init.c中:


void kernel_init(void)
{
    (void) disableIRQ();

    thread_create(idle_stack, sizeof(idle_stack),
            THREAD_PRIORITY_IDLE,
            THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
            idle_thread, NULL, idle_name);

    thread_create(main_stack, sizeof(main_stack),
            THREAD_PRIORITY_MAIN,
            THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
            main_trampoline, NULL, main_name);

    cpu_switch_context_exit();
}


别着急了解thread的概念,先把他理解成普通的C函数的调用;来看一下俩个thread干了什么:kernel_init.c中:

extern int main(void);
static void *main_trampoline(void *arg)
{
    (void) arg;

#ifdef MODULE_AUTO_INIT
    auto_init();
#endif

#ifdef MODULE_SCHEDSTATISTICS
    schedstat *stat = &sched_pidlist[thread_getpid()];
    stat->laststart = 0;
#endif

    LOG_INFO("main(): This is RIOT! (Version: " RIOT_VERSION ")\n");

    main();
    return NULL;
}

static void *idle_thread(void *arg)
{
    (void) arg;

    while (1) {
        if (lpm_prevent_sleep) {
            lpm_set(LPM_IDLE);
        }
        else {
            lpm_set(LPM_IDLE);
            /* lpm_set(LPM_SLEEP); */
            /* lpm_set(LPM_POWERDOWN); */
        }
    }

    return NULL;
}


我们看到main_trampoline中出现了main()了,总算搞清楚了RIOT的启动过程;

其中出现了auto_init(),这个函数非常重要,来看一下实现:

在RIOT\sys\auto_init下auto_init.c中:


void auto_init(void)
{
#ifdef MODULE_CONFIG
    DEBUG("Auto init loading config\n");
    config_load();
#endif

#ifdef MODULE_XTIMER
    DEBUG("Auto init xtimer module.\n");
    xtimer_init();
#endif
#ifdef MODULE_RTC
    DEBUG("Auto init rtc module.\n");
    rtc_init();
#endif
#ifdef MODULE_SHT11
    DEBUG("Auto init SHT11 module.\n");
    sht11_init();
#endif
#ifdef MODULE_GPIOINT
    DEBUG("Auto init gpioint module.\n");
    gpioint_init();
#endif
#ifdef MODULE_LTC4150
    DEBUG("Auto init ltc4150 module.\n");
    ltc4150_init();
#endif
#ifdef MODULE_MCI
    DEBUG("Auto init mci module.\n");
    MCI_initialize();
#endif
#ifdef MODULE_PROFILING
    extern void profiling_init(void);
    profiling_init();
#endif
#ifdef MODULE_GNRC_PKTBUF
    DEBUG("Auto init gnrc_pktbuf module\n");
    gnrc_pktbuf_init();
#endif
#ifdef MODULE_GNRC_PKTDUMP
    DEBUG("Auto init gnrc_pktdump module.\n");
    gnrc_pktdump_init();
#endif
#ifdef MODULE_GNRC_SIXLOWPAN
    DEBUG("Auto init gnrc_sixlowpan module.\n");
    gnrc_sixlowpan_init();
#endif
#ifdef MODULE_GNRC_IPV6
    DEBUG("Auto init gnrc_ipv6 module.\n");
    gnrc_ipv6_init();
#endif
#ifdef MODULE_GNRC_UDP
    DEBUG("Auto init UDP module.\n");
    gnrc_udp_init();
#endif

/* initialize network devices */
#ifdef MODULE_AUTO_INIT_GNRC_NETIF

#ifdef MODULE_AT86RF2XX
    extern void auto_init_at86rf2xx(void);
    auto_init_at86rf2xx();
#endif

#ifdef MODULE_ENCX24J600
    extern void auto_init_encx24j600(void);
    auto_init_encx24j600();
#endif

#ifdef MODULE_ENC28J60
    extern void auto_init_enc28j60(void);
    auto_init_enc28j60();
#endif

#ifdef MODULE_GNRC_SLIP
    extern void auto_init_slip(void);
    auto_init_slip();
#endif

#ifdef MODULE_CC110X
    extern void auto_init_cc110x(void);
    auto_init_cc110x();
#endif

#ifdef MODULE_XBEE
    extern void auto_init_xbee(void);
    auto_init_xbee();
#endif

#ifdef MODULE_KW2XRF
    extern void auto_init_kw2xrf(void);
    auto_init_kw2xrf();
#endif

#ifdef MODULE_NETDEV2_TAP
    extern void auto_init_netdev2_tap(void);
    auto_init_netdev2_tap();
#endif

#endif /* MODULE_AUTO_INIT_GNRC_NETIF */

#ifdef MODULE_GNRC_IPV6_NETIF
    gnrc_ipv6_netif_init_by_dev();
#endif

/* initialize sensors and actuators */
#ifdef MODULE_AUTO_INIT_SAUL
    DEBUG("auto_init SAUL\n");

#ifdef MODULE_SAUL_GPIO
    extern void auto_init_gpio(void);
    auto_init_gpio();
#endif
#ifdef MODULE_LSM303DLHC
    extern void auto_init_lsm303dlhc(void);
    auto_init_lsm303dlhc();
#endif
#ifdef MODULE_LPS331AP
    extern void auto_init_lps331ap(void);
    auto_init_lps331ap();
#endif
#ifdef MODULE_ISL29020
    extern void auto_init_isl29020(void);
    auto_init_isl29020();
#endif
#ifdef MODULE_L3G4200D
    extern void auto_init_l3g4200d(void);
    auto_init_l3g4200d();
#endif

#endif /* MODULE_AUTO_INIT_SAUL */
}
应该不用作者多介绍了,这个函数到底是干什么的;

我们看到了MODULE_xxx;让作者感到很亲切,毕竟作者本身是一个TinyOS控


到此我们基本的启动工程分析完成;

RIOT为什么不像TinyOS和Contiki那样,系统提供了int main()函数;

TinyOS是MainC组件/Contiki是contiki-main.c;

RIOT的int main()需要用户自己编写;可以去看一下例程; 通过初步的代码阅读;感觉RIOT的代码风格是本人比较喜欢的先不提他支持C++;在后面的部分我将一层一层揭开他的面纱;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: