Kernel and buildscript improvements (#477)
* **New Features** * Centralized module management with global symbol resolution * Level-aware logging with colored prefixes and millisecond timestamps * **Breaking Changes** * ModuleParent hierarchy and getModuleParent() removed * Logging API and adapter model replaced; LogLevel-driven log_generic signature changed * **Improvements** * Unified, simplified module registration across build targets * Tests updated to reflect new module lifecycle and global symbol resolution
This commit is contained in:
committed by
GitHub
parent
1a61eac8e0
commit
a935410f82
@@ -10,25 +10,32 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOG_TAG(x) "\033[37m"#x"\033[0m"
|
||||
/** Used for log output filtering */
|
||||
enum LogLevel {
|
||||
LOG_LEVEL_ERROR, /*!< Critical errors, software module can not recover on its own */
|
||||
LOG_LEVEL_WARNING, /*!< Error conditions from which recovery measures have been taken */
|
||||
LOG_LEVEL_INFO, /*!< Information messages which describe normal flow of events */
|
||||
LOG_LEVEL_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
|
||||
LOG_LEVEL_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
|
||||
};
|
||||
|
||||
#ifndef ESP_PLATFORM
|
||||
|
||||
void log_generic(const char* tag, const char* format, ...);
|
||||
void log_generic(enum LogLevel level, const char* tag, const char* format, ...);
|
||||
|
||||
#define LOG_E(x, ...) log_generic(x, ##__VA_ARGS__)
|
||||
#define LOG_W(x, ...) log_generic(x, ##__VA_ARGS__)
|
||||
#define LOG_I(x, ...) log_generic(x, ##__VA_ARGS__)
|
||||
#define LOG_D(x, ...) log_generic(x, ##__VA_ARGS__)
|
||||
#define LOG_V(x, ...) log_generic(x, ##__VA_ARGS__)
|
||||
#define LOG_E(tag, ...) log_generic(LOG_LEVEL_ERROR, tag, ##__VA_ARGS__)
|
||||
#define LOG_W(tag, ...) log_generic(LOG_LEVEL_WARNING, tag, ##__VA_ARGS__)
|
||||
#define LOG_I(tag, ...) log_generic(LOG_LEVEL_INFO, tag, ##__VA_ARGS__)
|
||||
#define LOG_D(tag, ...) log_generic(LOG_LEVEL_DEBUG, tag, ##__VA_ARGS__)
|
||||
#define LOG_V(tag, ...) log_generic(LOG_LEVEL_VERBOSE, tag, ##__VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
#define LOG_E(x, ...) ESP_LOGE(x, ##__VA_ARGS__)
|
||||
#define LOG_W(x, ...) ESP_LOGW(x, ##__VA_ARGS__)
|
||||
#define LOG_I(x, ...) ESP_LOGI(x, ##__VA_ARGS__)
|
||||
#define LOG_D(x, ...) ESP_LOGD(x, ##__VA_ARGS__)
|
||||
#define LOG_V(x, ...) ESP_LOGV(x, ##__VA_ARGS__)
|
||||
#define LOG_E(tag, ...) ESP_LOGE(tag, ##__VA_ARGS__)
|
||||
#define LOG_W(tag, ...) ESP_LOGW(tag, ##__VA_ARGS__)
|
||||
#define LOG_I(tag, ...) ESP_LOGI(tag, ##__VA_ARGS__)
|
||||
#define LOG_D(tag, ...) ESP_LOGD(tag, ##__VA_ARGS__)
|
||||
#define LOG_V(tag, ...) ESP_LOGV(tag, ##__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -6,15 +6,17 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define MODULE_SYMBOL_TERMINATOR { nullptr, nullptr }
|
||||
#else
|
||||
#define MODULE_SYMBOL_TERMINATOR { NULL, NULL }
|
||||
#endif
|
||||
|
||||
struct ModuleParent;
|
||||
struct ModuleParentPrivate;
|
||||
|
||||
#define MODULE_SYMBOL_TERMINATOR { NULL, NULL }
|
||||
#define DEFINE_MODULE_SYMBOL(symbol) { #symbol, (void*)&symbol }
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** A binary symbol like a function or a variable. */
|
||||
struct ModuleSymbol {
|
||||
/** The name of the symbol. */
|
||||
@@ -57,60 +59,45 @@ struct Module {
|
||||
*/
|
||||
const struct ModuleSymbol* symbols;
|
||||
|
||||
|
||||
struct {
|
||||
bool started;
|
||||
struct ModuleParent* parent;
|
||||
} internal;
|
||||
};
|
||||
|
||||
/**
|
||||
* A module parent is a collection of modules that can be loaded and unloaded at runtime.
|
||||
* @brief Construct a module instance.
|
||||
* @param module module instance to construct
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
struct ModuleParent {
|
||||
/** The name of the parent module, for logging/debugging purposes */
|
||||
const char* name;
|
||||
struct ModuleParentPrivate* module_parent_private;
|
||||
};
|
||||
error_t module_construct(struct Module* module);
|
||||
|
||||
/**
|
||||
* @brief Initialize the module parent.
|
||||
* @warn This function does no validation on input or state.
|
||||
* @param parent parent module
|
||||
* @return ERROR_NONE if successful, ERROR_OUT_OF_MEMORY if allocation fails
|
||||
* @brief Destruct a module instance.
|
||||
* @param module module instance to destruct
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t module_parent_construct(struct ModuleParent* parent);
|
||||
error_t module_destruct(struct Module* module);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the module parent. Must have no children when calling this.
|
||||
* @warn This function does no validation on input.
|
||||
* @param parent parent module
|
||||
* @return ERROR_NONE if successful or ERROR_INVALID_STATE if the parent has children
|
||||
* @brief Add a module to the system.
|
||||
* @warning Only call this once. This function does not check if it was added before.
|
||||
* @param module module to add
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t module_parent_destruct(struct ModuleParent* parent);
|
||||
error_t module_add(struct Module* module);
|
||||
|
||||
/**
|
||||
* @brief Resolve a symbol from the module parent.
|
||||
* @details This function iterates through all started modules in the parent and attempts to resolve the symbol.
|
||||
* @param parent parent module
|
||||
* @param symbol_name name of the symbol to resolve
|
||||
* @param symbol_address pointer to store the address of the resolved symbol
|
||||
* @return true if the symbol was found, false otherwise
|
||||
* @brief Remove a module from the system.
|
||||
* @param module module to remove
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
bool module_parent_resolve_symbol(struct ModuleParent* parent, const char* symbol_name, uintptr_t* symbol_address);
|
||||
|
||||
/**
|
||||
* @brief Set the parent of the module.
|
||||
* @warning must call before module_start()
|
||||
* @param module module
|
||||
* @param parent nullable parent module
|
||||
* @return ERROR_NONE if successful, ERROR_INVALID_STATE if the module is already started
|
||||
*/
|
||||
error_t module_set_parent(struct Module* module, struct ModuleParent* parent);
|
||||
error_t module_remove(struct Module* module);
|
||||
|
||||
/**
|
||||
* @brief Start the module.
|
||||
* @param module module
|
||||
* @return ERROR_NONE if already started, ERROR_INVALID_STATE if the module doesn't have a parent, or otherwise it returns the result of the module's start function
|
||||
* @return ERROR_NONE if already started, or otherwise it returns the result of the module's start function
|
||||
*/
|
||||
error_t module_start(struct Module* module);
|
||||
|
||||
@@ -138,6 +125,15 @@ error_t module_stop(struct Module* module);
|
||||
*/
|
||||
bool module_resolve_symbol(struct Module* module, const char* symbol_name, uintptr_t* symbol_address);
|
||||
|
||||
/**
|
||||
* @brief Resolve a symbol from any module
|
||||
* @details This function iterates through all started modules in the parent and attempts to resolve the symbol.
|
||||
* @param symbol_name name of the symbol to resolve
|
||||
* @param symbol_address pointer to store the address of the resolved symbol
|
||||
* @return true if the symbol was found, false otherwise
|
||||
*/
|
||||
bool module_resolve_symbol_global(const char* symbol_name, uintptr_t* symbol_address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user