typedef void (*mr_init_fn_t)(void); /**< Auto initialization function */
#define MR_INIT_EXPORT(fn, level) \
MR_USED const mr_init_fn_t _mr_auto_init_##fn MR_SECTION("mr_auto_init."level) = fn
#define MR_INIT_BOARD_EXPORT(fn) MR_INIT_EXPORT(fn, "1") /**< Exports a Board initialization function */
#define MR_INIT_DRV_EXPORT(fn) MR_INIT_EXPORT(fn, "2") /**< Exports a Driver initialization function */
#define MR_INIT_DEV_EXPORT(fn) MR_INIT_EXPORT(fn, "3") /**< Exports a Device initialization function */
#define MR_INIT_APP_EXPORT(fn) MR_INIT_EXPORT(fn, "4") /**< Exports an App initialization function */
static void start(void)
{
}
MR_INIT_EXPORT(start, "0");
static void end(void)
{
}
MR_INIT_EXPORT(end, "5.end");
/**
* @brief This function is auto initialized.
*/
void mr_auto_init(void)
{
/* Auto-initialization */
for (const mr_init_fn_t *fn = &_mr_auto_init_start; fn < &_mr_auto_init_end; fn++) {
(*fn)();
}
}
这段代码提供了一个自动初始化系统的实现框架,使用C预处理器宏来简化和控制不同初始化阶段的函数导出。让我们逐步解析这段代码和相关的概念。
宏定义和类型
typedef void (*mr_init_fn_t)(void);
这行代码定义了一个名为 mr_init_fn_t 的类型,它是一个函数指针类型,指向无返回值、无参数的函数。
#define MR_INIT_EXPORT(fn, level) \
MR_USED const mr_init_fn_t _mr_auto_init_##fn MR_SECTION("mr_auto_init."level) = fn
这是一个宏定义,用于将指定的函数 fn 放入一个特定的编译器节(section)中。MR_USED 和 MR_SECTION 可能是特定于编译器的宏,用于确保函数指针不会被优化掉,并将它们放在特定的内存节中。节名由 "mr_auto_init." 和提供的 level 参数组成。
初始化阶段宏定义
接下来的宏定义是针对不同的初始化阶段:
#define MR_INIT_BOARD_EXPORT(fn) MR_INIT_EXPORT(fn, "1")
#define MR_INIT_DRV_EXPORT(fn) MR_INIT_EXPORT(fn, "2")
#define MR_INIT_DEV_EXPORT(fn) MR_INIT_EXPORT(fn, "3")
#define MR_INIT_APP_EXPORT(fn) MR_INIT_EXPORT(fn, "4")
这些宏定义简化了将函数分配到特定初始化阶段的过程。例如,MR_INIT_BOARD_EXPORT(fn) 会把函数 fn 放入名为 mr_auto_init.1 的节中,通常用于板级初始化。
示例函数和它们的注册
static void start(void)
{
}
MR_INIT_EXPORT(start, "0");
static void end(void)
{
}
MR_INIT_EXPORT(end, "5.end");
这里定义了两个静态函数 start 和 end,并通过 MR_INIT_EXPORT 宏将它们注册到特定的初始化段。start 函数被注册在最早的初始化阶段("0"),而 end 函数被放在一个名为 "5.end" 的特定阶段。
自动初始化函数
/**
* @brief This function is auto initialized.
*/
void mr_auto_init(void)
{
/* Auto-initialization */
for (const mr_init_fn_t *fn = &_mr_auto_init_start; fn < &_mr_auto_init_end; fn++) {
(*fn)();
}
}
这个函数遍历从 _mr_auto_init_start 到 _mr_auto_init_end 的所有函数指针。这些符号(_mr_auto_init_start 和 _mr_auto_init_end)通常在链接脚本中定义,标记自动初始化函数列表的开始和结束。mr_auto_init 函数通过解引用每个函数指针并调用它来执行初始化任务。
总结
这种机制允许开发者按预定的顺序(由 level 参数控制)自动执行初始化函数,非常适合管理复杂系统中的启动顺序,如嵌入式设备或系统软件。每个初始化阶段可以根据需要(如硬件初始化、驱动加载、设备配置、应用启动等)分别进行管理。
412



被折叠的 条评论
为什么被折叠?



