单片机实现自动初始化

仿照RT-Thread的自动初始化机制,写了一个自动初始化的模块,整个代码仅52字节。

好处:可以实现自动初始化,不用在外部显式地调用。

缺点:初始化逻辑较显式调用的方式模糊,容易引入BUG。

以下是对应的头文件和源文件,初始化顺序分为9级,LOADER_BOARD_EARLY_EXPORT最早,LOADER_APP_LATE_EXPORT最迟。使用方法可以看最后面的Demo。

#ifndef _LOADER__H
#define _LOADER__H

#if defined(__CC_ARM) || defined(__CLANG_ARM)	/* ARM Compiler */
	#define LOADER_USED			__attribute__((used))
	#define SECTION(x)			__attribute__((section(x)))
	
#elif defined (__IAR_SYSTEMS_ICC__)     		/* for IAR Compiler */
	#define LOADER_USED			__root
	#define SECTION(x)			@ x
	
#elif defined (__GNUC__) 						/* GNU GCC Compiler */
	#define LOADER_USED			__attribute__((used))
	#define SECTION(x)			__attribute__((section(x)))
#endif	
	

typedef int (*init_func_t)(void);
#define LOADER_EXPORT(fn, level) 		\
		LOADER_USED const init_func_t init_##fn SECTION(".loader_fn."level) = fn
				

#define LOADER_BOARD_EARLY_EXPORT(fn)     	LOADER_EXPORT(fn, "1")
#define LOADER_BOARD_EXPORT(fn)        		LOADER_EXPORT(fn, "2")
#define LOADER_BOARD_LATE_EXPORT(fn)      	LOADER_EXPORT(fn, "3")

#define LOADER_COMPONENT_EARLY_EXPORT(fn) 	LOADER_EXPORT(fn, "4")
#define LOADER_COMPONENT_EXPORT(fn) 		LOADER_EXPORT(fn, "5")
#define LOADER_COMPONENT_LATE_EXPORT(fn) 	LOADER_EXPORT(fn, "6")

#define LOADER_APP_EARLY_EXPORT(fn)       	LOADER_EXPORT(fn, "7")
#define LOADER_APP_EXPORT(fn)             	LOADER_EXPORT(fn, "8")
#define LOADER_APP_LATE_EXPORT(fn)       	LOADER_EXPORT(fn, "9")

int LoaderExec(void);
 
#endif
#include "Loader.h"

static int loader_start(void)
{
    return 0;
}
LOADER_EXPORT(loader_start, "0");


static int loader_end(void)
{
    return 0;
}
LOADER_EXPORT(loader_end, "9.end");


int LoaderExec(void)
{
	int res = 0;
	const init_func_t *fn_ptr;
	
	for (fn_ptr = &init_loader_start; fn_ptr < &init_loader_end; fn_ptr++)
	{
		res += (*fn_ptr)();
	}
	return res;
}
/* Loader Demo */

/********************** led.c **********************/
#include "Loader.h"

int led_init(void)
{
    /* GPIO初始化 */
    return 0;
}
LOADER_APP_EXPORT(led_init);


/********************** main.c **********************/
#include "Loader.h"

int main(void)
{
    HAL_Init();        /* 初始化芯片底层,实际上该函数也可以通过loader导出 */
    
    LoaderExec();      /* 加载Loader,里面会调用led_init */

    while(1)
    {
        /* do something */
    }    
}

猜你喜欢

转载自blog.csdn.net/qq_27575841/article/details/105151752