疑问
RT-THREAD的DEMO工程在添加所有文件编译之后,完全没有用户自己去调用HAL库的代码,甚至连main函数里面都是空的,竟然可以正常运行。
当然是RT-THREAD做了其他操作来达到运行的效果。
启动解析
RESET之后第一时间的运行的是main函数虽然main函数里面是空,但是并不代表RT-THREAD没有运行代码
main函数重定向
先运行\$Sub$$main,来进行初始化,这样做的目的是为了适应不同的编译器,有些编译器的入口并不是main函数
在app初始化时再重新回调我们自己定义的main函数。
#ifdef __ARMCC_VERSION
extern int $Super$$main(void);
/* re-define main function */
int $Sub$$main(void)
{
rtthread_startup();
return 0;
}
\$Sub$$功能使用
板级初始化
在重定向main函数之后,会调用rt_hw_board_init来初始化board的功能,不同的板子实现方式不一样,现在我们这个函数是在drv_common.c这个文件里面实现,当然有些人在board.c里面实现也是没有问题,而且这个函数定义用的是RT_WEAK的类型,可重新定义。从源码中我们可以看出这个函数也是真正调用了相应的初始化代码。
RT_WEAK void rt_hw_board_init()
{
#ifdef BSP_SCB_ENABLE_I_CACHE
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
#endif
#ifdef BSP_SCB_ENABLE_D_CACHE
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* HAL_Init() function is called at the beginning of the program */
HAL_Init();
/* System clock initialization */
SystemClock_Config();
/* Heap initialization */
#if defined(RT_USING_HEAP)
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
rt_hw_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
rt_hw_usart_init();
#endif
/* Set the shell console output device */
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
宏添加初始化操作
rt_components_board_init这个函数调用了用户独有的板级初始化代码,而调用的方式不是显示地调用,而是使用section定义的方式,将初始化函数定在相近的代码区,然后用函数指针的方式去调用相应的初始化函数。
具体的section操作可参考其他教程。
RT-Thread定义了很多相近的宏用于初始化以及添加新的线程(INIT_APP_EXPORT)来进行直接加任务,而不需要显示调用。
/* board init routines will be called in board_init() function */
#define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")
/* pre/device/component/env/app init routines will be called in init_thread */
/* components pre-initialization (pure software initialization) */
#define INIT_PREV_EXPORT(fn) INIT_EXPORT(fn, "2")
/* device initialization */
#define INIT_DEVICE_EXPORT(fn) INIT_EXPORT(fn, "3")
/* components initialization (dfs, lwip, ...) */
#define INIT_COMPONENT_EXPORT(fn) INIT_EXPORT(fn, "4")
/* environment initialization (mount disk, ...) */
#define INIT_ENV_EXPORT(fn) INIT_EXPORT(fn, "5")
/* application initialization (rtgui application etc ...) */
#define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6")
通过以上的方式,完成板级初始化,同时创建主任务及空闲任务,开始系统的运行与调度。
总结
RT-THREAD通过重定向及宏的定义进行初始化,使代码本身更新的清晰可扩展性极好。理解之后还是一个很好的设计。
标签:RT,main,THREAD,init,INIT,EXPORT,解析,fn From: https://www.cnblogs.com/stupidpeng/p/16799520.html