天天看點

RT-Thread 自動初始化代碼片段RT-Thread 自動初始化代碼片段

RT-Thread 自動初始化代碼片段

C語言#文法

一個#号: 将宏參數轉變為字元串 例如: #define STR(s) #s
兩個#号: 把兩個宏參數連接配接到一起 例如: #define CONS(a,b)  int(a##e##b)
           
#define STR(s) #s
#define CONS(a,b)  int(a##e##b)
int main()

{
	printf(STR(vck));   // 輸出字元串"vck"
	printf("%d\n", CONS(2,3));  // 2e3 輸出:2000
	return 0;
}
           

代碼片段

// 使用者自動初始化的函數, 通過如下宏定義執行
/* 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 initilization) */
#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")
/* appliation initialization (rtgui application etc ...) */
#define INIT_APP_EXPORT(fn)             INIT_EXPORT(fn, "6")

//定義導入初始化函數, 将函數fn存放到代碼塊兒level(為1-6代碼片段)位置
#define INIT_EXPORT(fn, level)    \
		// 定義字元串__rti_##fn##_name 為fn的函數名
        const char __rti_##fn##_name[] = #fn;   \
		// 建立以fn函數名命名的結構體 __rt_init_desc_##fn 并将結構體内容放到指定位置
        RT_USED const struct rt_init_desc __rt_init_desc_##fn SECTION(".rti_fn." level) = \
		// 将__rti_##fn##_name函數名和fn函數放到 .rti_fn.level的資料段中
        {__rti_##fn##_name, fn}; 
  
           
  • 關于代碼片段位址的定義在link.lds檔案中定義(記憶體分布)
/* section information for initial. */
    . = ALIGN(4);
    __rt_init_start = .;
    KEEP(*(SORT(.rti_fn*)))
    __rt_init_end = .;

	/*注: 
		. :點代表目前記憶體位置
		KEEP() :告訴編譯器,這部分不要被垃圾回收
	    SORT() :對滿足字元串模式的所有名字進行遞增排序
	*/
           
  • 通過如下函數實作記憶體分段
static int rti_start(void)
	{
	    return 0;
	}
	INIT_EXPORT(rti_start, "0");
	
	static int rti_board_start(void)
	{
	    return 0;
	}
	INIT_EXPORT(rti_board_start, "0.end");
	
	static int rti_board_end(void)
	{
	    return 0;
	}
	INIT_EXPORT(rti_board_end, "1.end");
	
	static int rti_end(void)
	{
	    return 0;
	}
	INIT_EXPORT(rti_end, "6.end");

	/*
	 * Components Initialization will initialize some driver and components as following
	 * order:
	 * rti_start         --> 0
	 * BOARD_EXPORT      --> 1
	 * rti_board_end     --> 1.end
	 *
	 * DEVICE_EXPORT     --> 2
	 * COMPONENT_EXPORT  --> 3
	 * FS_EXPORT         --> 4
	 * ENV_EXPORT        --> 5
	 * APP_EXPORT        --> 6
	 *
	 * rti_end           --> 6.end
	 *
	 * These automatically initialization, the driver or component initial function must
	 * be defined with:
	 * INIT_BOARD_EXPORT(fn);
	 * INIT_DEVICE_EXPORT(fn);
	 * ...
	 * INIT_APP_EXPORT(fn);
	 * etc.
	 */
           
  • 通過如下函數實作記憶體片段内的函數周遊并執行
void rt_components_board_init(void)
	{
	#if RT_DEBUG_INIT
	    int result;
	    const struct rt_init_desc *desc;
	    for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
	    {
	        rt_kprintf("initialize %s", desc->fn_name);
	        result = desc->fn();
	        rt_kprintf(":%d done\n", result);
	    }
	#else
	    const init_fn_t *fn_ptr;
	
	    for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
	    {
	        (*fn_ptr)();
	    }
	#endif
	}
           

繼續閱讀