中级会员
 
- 积分
- 214
- 金钱
- 214
- 注册时间
- 2014-4-30
- 在线时间
- 26 小时
|
RT-Thread上面学习的函数的初始化,都是隐式调用的,不需要在main函数前面列出长长的硬件初始化代码或者测试代码,只需要在需要初始化的代码后面加一句:INIT_BOARD_EXPORT(SetSysClock);
即可。
这样做好处:①降低代码的耦合性;
②多人联合开发时,非常方便;
③...
我从rt-thread中抽取出这部分,没有操作系统也可以使用。
这是我测试的主函数:
int main(void)
{
board_init();
components_init();
while (1)
{
MbWork();
IWDG_Feed(); // 喂狗
Uart2ListenTask();
}
}
其中关键的两个函数:
/**
* Initialization for board
*/
void board_init(void)
{
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)();
}
}
/**
* Components Initialization
*/
void components_init(void)
{
const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
{
(*fn_ptr)();
}
}

这里我封装成了init.c和init.h
======================================================
init.c
#include "init.h"
/*
* 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.
*/
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");
/**
* Initialization for board
*/
void board_init(void)
{
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)();
}
}
/**
* Components Initialization
*/
void components_init(void)
{
const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
{
(*fn_ptr)();
}
}
=======================================================
init.h:
#ifndef __INIT_H
#define __INIT_H
#include <stdarg.h>
/* 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")
#define SECTION(x) __attribute__((section(x)))
#define RT_UNUSED __attribute__((unused))
#define RT_USED __attribute__((used))
#define ALIGN(n) __attribute__((aligned(n)))
typedef int (*init_fn_t)(void);
#define INIT_EXPORT(fn, level) RT_USED const init_fn_t __rt_init_##fn SECTION(".rti_fn."level) = fn
void board_init(void);
void components_init(void);
#endif
============================================================================
只需要这两个文件,就可以在其他任何stm32的工程上使用了。亲测可用。
附工程。(工程基于stm32f070,使用了iwdg,usart1,usart2,stmflash,timer3-1ms,timer4-2.5ms,基于usart2的一个简易的命令解释器,可用于运行时参数设置)。
第一次测试,可能有些问题没有发现,欢迎各位网友共同探讨。
|
|