---恢复内容开始---
RT-Thread 版本:2.1.0
RTGUI相关代码解读,仅为自己学习记录,若有错误之处,请告知[email protected],不胜感激!
GUI流程:
main() -> rtthread_startup(); -> rt_hw_board_init(); -> rt_components_board_init();
在rt_components_board_init()中:
1 void rt_components_board_init(void) 2 { 3 #if RT_DEBUG_INIT 4 int result; 5 const struct rt_init_desc *desc; 6 for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++) 7 { 8 rt_kprintf("initialize %s", desc->fn_name); 9 result = desc->fn(); 10 rt_kprintf(":%d done\n", result); 11 } 12 #else 13 const init_fn_t *fn_ptr; 14 15 for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++) 16 { 17 (*fn_ptr)(); //此处回调所有组件的初始化函数 18 } 19 #endif 20 }
查找init_fn_t的定义:(参考阅读:http://blog.csdn.net/sunheshan/article/details/48596103)
1 /* initialization export */ 2 #ifdef RT_USING_COMPONENTS_INIT 3 typedef int (*init_fn_t)(void); 4 #ifdef _MSC_VER /* we do not support MS VC++ compiler */ 5 #define INIT_EXPORT(fn, level) 6 #else 7 #if RT_DEBUG_INIT 8 struct rt_init_desc 9 { 10 const char* fn_name; 11 const init_fn_t fn; 12 }; 13 #define INIT_EXPORT(fn, level) \ 14 const char __rti_##fn##_name[] = #fn; \ 15 const struct rt_init_desc __rt_init_desc_##fn SECTION(".rti_fn."level) = \ 16 { __rti_##fn##_name, fn}; 17 #else 18 #define INIT_EXPORT(fn, level) \ //重点就是在这两行 19 const init_fn_t __rt_init_##fn SECTION(".rti_fn."level) = fn //INIT_APP_EXPORT(rtgui_system_server_init) 相当于__rt_init_rtgui_system_server_init @ .rti_fn.6
20 #endif
21 #endif
22 #else
23 #define INIT_EXPORT(fn, level)
24 #endif
25
26 /* board init routines will be called in board_init() function */
27 #define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")
28 /* device/component/fs/app init routines will be called in init_thread */
29 /* device initialization */
30 #define INIT_DEVICE_EXPORT(fn) INIT_EXPORT(fn, "2")
31 /* components initialization (dfs, lwip, ...) */
32 #define INIT_COMPONENT_EXPORT(fn) INIT_EXPORT(fn, "3")
33 /* file system initialization (dfs-elm, dfs-rom, ...) */
34 #define INIT_FS_EXPORT(fn) INIT_EXPORT(fn, "4")
35 /* environment initialization (mount disk, ...) */
36 #define INIT_ENV_EXPORT(fn) INIT_EXPORT(fn, "5")
37 /* appliation initialization (rtgui application etc ...) */
38 #define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6")
根据INIT_APP_EXPORT,找到GUI初始化函数:
1 int rtgui_system_server_init(void) 2 { 3 rt_mutex_init(&_screen_lock, "screen", RT_IPC_FLAG_FIFO); 4 5 /* init image */ 6 rtgui_system_image_init(); 7 /* init font */ 8 rtgui_font_system_init(); 9 10 /* init rtgui server */ 11 rtgui_topwin_init(); 12 rtgui_server_init(); 13 14 /* use driver rect for main window */ 15 rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &_mainwin_rect); 16 17 /* set the default font */ 18 #if RTGUI_DEFAULT_FONT_SIZE == 16 19 rtgui_font_set_defaut(&rtgui_font_asc16); 20 #elif RTGUI_DEFAULT_FONT_SIZE == 12 21 rtgui_font_set_defaut(&rtgui_font_asc12); 22 #else 23 rtgui_font_set_defaut(&rtgui_font_asc12); 24 #endif 25 26 return 0; 27 } 28 INIT_APP_EXPORT(rtgui_system_server_init);
在.map文件中:
可以看到__rt_init_rtgui_system_server_init的地址和.rti_fn.6的地址是相同的。
至此可大致了解RT Thread组件初始化的方式,在固定的地址段存放相关的初始化函数,然后用一个回调函数去逐个调取执行,以完成响应组件的初始化。