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表等的分析就省略了;
来看一下代码实现:
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中:
代码简单 不做分析;
下面来到重点函数,我们将看到main函数冒泡了,总算逮到你了
kernel_init()在RIOT\core下kernel_init.c中:
别着急了解thread的概念,先把他理解成普通的C函数的调用;来看一下俩个thread干了什么:kernel_init.c中:
我们看到main_trampoline中出现了main()了,总算搞清楚了RIOT的启动过程;
其中出现了auto_init(),这个函数非常重要,来看一下实现:
在RIOT\sys\auto_init下auto_init.c中:
我们看到了MODULE_xxx;让作者感到很亲切,毕竟作者本身是一个TinyOS控
到此我们基本的启动工程分析完成;
RIOT为什么不像TinyOS和Contiki那样,系统提供了int main()函数;
TinyOS是MainC组件/Contiki是contiki-main.c;
RIOT的int main()需要用户自己编写;可以去看一下例程; 通过初步的代码阅读;感觉RIOT的代码风格是本人比较喜欢的先不提他支持C++;在后面的部分我将一层一层揭开他的面纱;
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++;在后面的部分我将一层一层揭开他的面纱;
相关文章推荐
- UVA 10881_Piotr's Ant
- 【物联网】QCA4010开发环境搭建(二)(解决WIN10下不能驱动问题)
- 物联网平台设计心得:管中窥豹之HeartBeat
- 使用Jlayer和AudioTrack实现在线流媒体边下边播功能
- 深度学习入门,以及它在物联网和智慧城市中的角色
- Windows 10 IoT Core Samples
- iotop--补齐系统监视工具缺失的一环
- 一维码:EAN-13码的识别
- 物联网行业的关注点
- IOS GameAudioManager 使用缺少 AudioToolbox Framework
- C#工业物联网和集成系统解决方案的技术路线
- 飞思卡尔推厚度0.34mm物联网芯片
- 物联网技术趋势预测
- C#工业物联网和集成系统解决方案的技术路线(数据源、数据采集、数据上传与接收、ActiveMQ、Mongodb、WebApi、手机App)
- 物联网重点
- android byte字节数组转换十六进制字符串(物联网开发总结)
- Chirimen:Mozilla 发布基于 Firefox OS 的物联网单片机开放平台
- (iota)regetnIotgnirtS.8
- 我想做一条机器狗
- 考拉社区黄俊:社区O2O临近爆发点 IOT是引爆器