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
	}

猜你喜欢

转载自blog.csdn.net/tigerots/article/details/103521407