Files
ESPC3-wireless/components/system/include/sys_init.h

401 lines
13 KiB
C
Raw Normal View History

2024-03-28 12:19:52 +08:00
/**
* @file sys_init.h
* @author LokLiang (lokliang@163.com)
* @brief
* @version 0.1
* @date 2023-06-01
* @date 2023-05-01
*
* @copyright Copyright (c) 2023
*
*/
#ifndef __SYS_INIT_H__
#define __SYS_INIT_H__
#include "sys_types.h"
#ifdef __cplusplus
extern "C"
{
#endif /* #ifdef __cplusplus */
/* initialize function -------------------------------------------------------- */
#define INIT_EXPORT_BOARD(FN) _INIT_EXPORT(FN, 0, 1) // 定义自动初始化函数:非常早期的初始化,此时调度器还未启动
#define INIT_EXPORT_PREV(FN) _INIT_EXPORT(FN, 1, 1) // 定义自动初始化函数:主要是用于纯软件的初始化、没有太多依赖的函数
#define INIT_EXPORT_DEVICE(FN) _INIT_EXPORT(FN, 2, 1) // 定义自动初始化函数:外设驱动初始化相关,比如网卡设备
#define INIT_EXPORT_COMPONENT(FN) _INIT_EXPORT(FN, 3, 1) // 定义自动初始化函数:组件初始化,比如文件系统或者 LWIP
#define INIT_EXPORT_ENV(FN) _INIT_EXPORT(FN, 4, 1) // 定义自动初始化函数:系统环境初始化,比如挂载文件系统
#define INIT_EXPORT_APP(FN, PRIOR) _INIT_EXPORT(FN, 5, PRIOR) // 定义自动初始化函数:应用初始化,比如 GUI 应用PRIOR 建议取值为 0 或 10..99
/* module define -------------------------------------------------------------- */
#define OBJ_EXPORT_DEVICE(OBJECT, NAME) _MODULE_EXPORT(OBJECT, NAME, MODULE_TYPE_DEVICE)
#define OBJ_EXPORT_COMPONENT(OBJECT, NAME) _MODULE_EXPORT(OBJECT, NAME, MODULE_TYPE_COMPONENT)
/* module api------------------------------------------------------------------ */
__static_inline const void *device_binding(const char *name);
__static_inline const char *device_name(const void *object);
__static_inline const char *device_search(const char *prefix_name, unsigned int num);
__static_inline const void *component_binding(const char *name);
__static_inline const char *component_name(const void *object);
__static_inline const char *component_search(const char *prefix_name, unsigned int num);
/* code ----------------------------------------------------------------------- */
/** @defgroup initialize function
* @{
*/
typedef struct
{
int (*fn)(void); // 初始化函数地址
const char *fn_name; // debug: 函数关联名
const char *file; // debug: 所在文件名
uint16_t line; // debug: 所在文件行
uint8_t level; // debug: 初始化等级
uint8_t prior; // debug: 初始化优先级
} sys_init_t;
/**
* @def _INIT_EXPORT
*
* @brief
* INIT_EXPORT_BOARD
* INIT_EXPORT_PREV
* INIT_EXPORT_DEVICE
* INIT_EXPORT_COMPONENT
* INIT_EXPORT_ENV
* INIT_EXPORT_APP
* sys_init_t
* "(.s_sys_init_t.*)"
* "sys_init.ld"
*
*
* @param FN
*
* @param LEVEL
*
* @param PRIOR 0..99
*
*
* @verbatim
* static int _init_env_template(void)
* {
* SYS_LOG_INF("done.\r\n");
* return 0;
* }
* INIT_EXPORT_ENV(_init_env_template);
*
* static int _init_app_template1(void)
* {
* SYS_LOG_INF("done.\r\n");
* return 0;
* }
* static int _init_app_template2(void)
* {
* SYS_LOG_INF("done.\r\n");
* return 0;
* }
* INIT_EXPORT_APP(_init_app_template1, 0);
* INIT_EXPORT_APP(_init_app_template2, 1);
* @endverbatim
*/
#define _INIT_EXPORT(FN, LEVEL, PRIOR) \
__used __section(".s_sys_init_t." #LEVEL "." #PRIOR) static sys_init_t const \
__sys_init_##FN = { \
.fn = FN, \
.fn_name = #FN, \
.line = __LINE__, \
.file = __FILE__, \
.level = LEVEL, \
.prior = PRIOR, \
}
/**
* @}
*/
/** @defgroup initialize module
* @{
*/
typedef enum __packed // 定义模块的类型
{
MODULE_TYPE_DEVICE, // 模块类型为驱动
MODULE_TYPE_COMPONENT, // 模块类型为组件
// ...
} module_type_t;
typedef struct // 模块数据结构
{
const char *name; // 模块数据关联名
const void *obj; // 模块数据地址
module_type_t type; // 模块数据类型
uint16_t line; // debug: 所在文件行
const char *file; // debug: 所在文件名
} module_t;
/**
* @def _MODULE_EXPORT
*
* @brief
* OBJ_EXPORT_DEVICE
* OBJ_EXPORT_COMPONENT
* ".sys_module_data"
* "sys_init.ld"
* 使 sys_module_binding()
*
* @param OBJECT
*
* @param OBJ_NAME 使 sys_module_search()
*
* @param MODULE_TYPE @ref module_type_t
*
*
* @verbatim
* #include "device_template.h"
*
* static void _set_data(device_template_t dev, int data);
* static int _get_data(device_template_t dev);
*
* static device_template_config_t config;
*
* static struct device_template const device = {
* .api = {
* .set_data = _set_data,
* .get_data = _get_data,
* },
* .config = &config,
* };
* OBJ_EXPORT_DEVICE(device, "DRV1");
*
* static void _set_data(device_template_t dev, int data)
* {
* dev->config->data = data;
* }
*
* static int _get_data(device_template_t dev)
* {
* return dev->config->data;
* }
* @endverbatim
*
*/
#define _MODULE_EXPORT(OBJECT, OBJ_NAME, MODULE_TYPE) \
__used __section(".sys_module_data.1") static module_t const \
__sys_module_##OBJECT = { \
.name = OBJ_NAME, \
.obj = &OBJECT, \
.type = MODULE_TYPE, \
.line = __LINE__, \
.file = __FILE__, \
}
/**
* @brief _MODULE_EXPORT
*
* @param type _MODULE_EXPORT
* @param name _MODULE_EXPORT
* @return module_t * _MODULE_EXPORT
*/
__static_inline const module_t *sys_module_binding(module_type_t type, const char *name)
{
if (name)
{
extern const module_t __sys_module_leader_0;
extern const module_t __sys_module_leader_9;
const module_t *module = &__sys_module_leader_0;
const module_t *end = &__sys_module_leader_9;
while (module < end)
{
if (module->type == type)
{
int i;
for (i = 0; 1; i++)
{
if (name[i] != module->name[i])
break;
if (name[i] == '\0')
return module;
}
}
module = &module[1];
}
}
return NULL;
}
/**
* @brief _MODULE_EXPORT
*
* @param type _MODULE_EXPORT
* @param prefix_name _MODULE_EXPORT prefix_name "UART" "UART1", "UART2"...
* @param num prefix_name 0..n
* @return const char * num prefix_name.* sys_module_binding()
* @return NULL
*/
__static_inline const char *sys_module_search(module_type_t type, const char *prefix_name, unsigned int num)
{
if (prefix_name)
{
extern const module_t __sys_module_leader_0;
extern const module_t __sys_module_leader_9;
const module_t *module = &__sys_module_leader_0;
const module_t *end = &__sys_module_leader_9;
unsigned int match = 0;
while (module < end)
{
if (module->type == type)
{
int i;
for (i = 0; 1; i++)
{
if (prefix_name[i] == '\0')
{
if (match < num)
{
match++;
break;
}
else
{
return module->name;
}
}
if (prefix_name[i] != module->name[i])
break;
}
}
module = &module[1];
}
}
return NULL;
}
/**
* @brief
*
* @param object sys_module_binding()
* @return const char *
*/
__static_inline const char *sys_module_name(const void *object)
{
if (object)
{
extern const module_t __sys_module_leader_0;
extern const module_t __sys_module_leader_9;
const module_t *module = &__sys_module_leader_0;
const module_t *end = &__sys_module_leader_9;
while (module < end)
{
if (module->obj == object)
{
return module->name;
}
module = &module[1];
}
}
return "";
}
/**
* @}
*/
/** @defgroup module
* @{
*/
/**
* @brief OBJ_EXPORT_DEVICE
*
* @param name OBJ_EXPORT_DEVICE
* @return const void * OBJ_EXPORT_DEVICE
*/
__static_inline const void *device_binding(const char *name)
{
const module_t *module = sys_module_binding(MODULE_TYPE_DEVICE, name);
if (module)
return module->obj;
else
return NULL;
}
/**
* @brief
*
* @param object device_binding()
* @return const char *
*/
__static_inline const char *device_name(const void *object)
{
return sys_module_name(object);
}
/**
* @brief device_binding()
*
* @param prefix_name _MODULE_EXPORT prefix_name "UART" "UART1", "UART2"...
* @param num prefix_name 0..n
* @return const char * num prefix_name.*
* @return NULL
*/
__static_inline const char *device_search(const char *prefix_name, unsigned int num)
{
return sys_module_search(MODULE_TYPE_DEVICE, prefix_name, num);
}
/**
* @brief OBJ_EXPORT_COMPONENT
*
* @param name OBJ_EXPORT_COMPONENT
* @return const void * OBJ_EXPORT_COMPONENT
*/
__static_inline const void *component_binding(const char *name)
{
const module_t *module = sys_module_binding(MODULE_TYPE_COMPONENT, name);
if (module)
return module->obj;
else
return NULL;
}
/**
* @brief
*
* @param object component_binding()
* @return const char *
*/
__static_inline const char *component_name(const void *object)
{
return sys_module_name(object);
}
/**
* @brief component_binding()
*
* @param prefix_name _MODULE_EXPORT prefix_name "UART" "UART1", "UART2"...
* @param num prefix_name 0..n
* @return const char * num prefix_name.*
* @return NULL
*/
__static_inline const char *component_search(const char *prefix_name, unsigned int num)
{
return sys_module_search(MODULE_TYPE_COMPONENT, prefix_name, num);
}
/**
* @}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif /* #ifdef __cplusplus */
#endif