参考代码

This commit is contained in:
LokLiang
2024-03-28 12:19:52 +08:00
commit 7b86aa3362
96 changed files with 19986 additions and 0 deletions

View File

@@ -0,0 +1,400 @@
/**
* @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