/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : bsp_config.c * @brief : 板级支持包配置文件源文件 ****************************************************************************** */ /* USER CODE END Header */ #include "bsp_config.h" #include #include #include #include /** * @brief 配置存储条目 */ typedef struct bsp_config_storage_entry { char section[BSP_CONFIG_MAX_SECTION_NAME_LENGTH]; char key[BSP_CONFIG_MAX_KEY_NAME_LENGTH]; char value[BSP_CONFIG_MAX_VALUE_LENGTH]; struct bsp_config_storage_entry* next; } bsp_config_storage_entry_t; /** * @brief 配置存储 */ typedef struct { bsp_config_storage_entry_t* entries; uint32_t entry_count; uint8_t initialized; } bsp_config_storage_t; /** * @brief 配置存储实例 */ static bsp_config_storage_t bsp_config_storage = { .entries = NULL, .entry_count = 0, .initialized = 0 }; /** * @brief 去除字符串中的空白字符 * @param str: 要处理的字符串 * @return 处理后的字符串 */ static char* bsp_config_trim(char* str) { char* end; // Trim leading whitespace while (isspace((unsigned char)*str)) { str++; } if (*str == 0) { return str; } // Trim trailing whitespace end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) { end--; } // Null terminate *(end + 1) = 0; return str; } /** * @brief 打开配置文件 * @param filename: 配置文件名称 * @param parser: 解析器上下文 * @retval HAL 状态码 */ static hal_ret_t bsp_config_file_open(const char* filename, bsp_config_parser_t* parser) { if (filename == NULL || parser == NULL) { return HAL_INVALID_PARAM; } parser->file = fopen(filename, "r"); if (parser->file == NULL) { return HAL_ERROR; } memset(parser->current_section, 0, sizeof(parser->current_section)); memset(parser->buffer, 0, sizeof(parser->buffer)); parser->line_number = 0; parser->initialized = 1; return HAL_OK; } /** * @brief 关闭配置文件 * @param parser: 解析器上下文 * @retval HAL 状态码 */ static hal_ret_t bsp_config_file_close(bsp_config_parser_t* parser) { if (parser == NULL || !parser->initialized) { return HAL_INVALID_PARAM; } if (parser->file != NULL) { fclose(parser->file); parser->file = NULL; } parser->initialized = 0; return HAL_OK; } /** * @brief 从文件读取配置条目 * @param parser: 解析器上下文 * @param entry: 配置条目 * @retval HAL 状态码 */ static hal_ret_t bsp_config_file_read_entry(bsp_config_parser_t* parser, bsp_config_entry_t* entry) { if (parser == NULL || entry == NULL || !parser->initialized) { return HAL_INVALID_PARAM; } if (parser->file == NULL) { return HAL_ERROR; } while (fgets(parser->buffer, sizeof(parser->buffer), parser->file) != NULL) { parser->line_number++; char* line = bsp_config_trim(parser->buffer); size_t len = strlen(line); // Skip empty lines and comments if (len == 0 || line[0] == '#') { continue; } // Check for section header if (line[0] == '[' && line[len - 1] == ']') { // Extract section name memset(parser->current_section, 0, sizeof(parser->current_section)); strncpy(parser->current_section, line + 1, len - 2); parser->current_section[len - 2] = '\0'; continue; } // Check for key-value pair char* equals = strchr(line, '='); if (equals != NULL) { // Extract key and value *equals = '\0'; char* key = bsp_config_trim(line); char* value = bsp_config_trim(equals + 1); entry->section = parser->current_section; entry->key = key; entry->value = value; return HAL_OK; } } return HAL_TIMEOUT; } /** * @brief 解析整数值 * @param value: 要解析的字符串值 * @param result: 存储结果的指针 * @retval HAL 状态码 */ static hal_ret_t bsp_config_parse_int(const char* value, int* result) { if (value == NULL || result == NULL) { return HAL_INVALID_PARAM; } char* endptr; long val = strtol(value, &endptr, 0); if (*endptr != '\0') { return HAL_ERROR; } *result = (int)val; return HAL_OK; } /** * @brief 解析无符号整数值 * @param value: 要解析的字符串值 * @param result: 存储结果的指针 * @retval HAL 状态码 */ static hal_ret_t bsp_config_parse_uint(const char* value, uint32_t* result) { if (value == NULL || result == NULL) { return HAL_INVALID_PARAM; } char* endptr; unsigned long val = strtoul(value, &endptr, 0); if (*endptr != '\0') { return HAL_ERROR; } *result = (uint32_t)val; return HAL_OK; } /** * @brief 解析布尔值 * @param value: 要解析的字符串值 * @param result: 存储结果的指针 * @retval HAL 状态码 */ static hal_ret_t bsp_config_parse_bool(const char* value, uint8_t* result) { if (value == NULL || result == NULL) { return HAL_INVALID_PARAM; } if (strcmp(value, "true") == 0 || strcmp(value, "TRUE") == 0 || strcmp(value, "1") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "YES") == 0) { *result = 1; return HAL_OK; } else if (strcmp(value, "false") == 0 || strcmp(value, "FALSE") == 0 || strcmp(value, "0") == 0 || strcmp(value, "no") == 0 || strcmp(value, "NO") == 0) { *result = 0; return HAL_OK; } return HAL_ERROR; } /** * @brief 解析字符串值 * @param value: 要解析的字符串值 * @param result: 存储结果的指针 * @param max_length: 结果缓冲区的最大长度 * @retval HAL 状态码 */ static hal_ret_t bsp_config_parse_string(const char* value, char* result, size_t max_length) { if (value == NULL || result == NULL) { return HAL_INVALID_PARAM; } strncpy(result, value, max_length - 1); result[max_length - 1] = '\0'; return HAL_OK; } /** * @brief 添加配置条目到存储 * @param section: 节名称 * @param key: 键名称 * @param value: 值 * @retval HAL 状态码 */ static hal_ret_t bsp_config_storage_add(const char* section, const char* key, const char* value) { // Check if entry already exists bsp_config_storage_entry_t* entry = bsp_config_storage.entries; while (entry != NULL) { if (strcmp(entry->section, section) == 0 && strcmp(entry->key, key) == 0) { // Update existing entry strncpy(entry->value, value, sizeof(entry->value) - 1); entry->value[sizeof(entry->value) - 1] = '\0'; return HAL_OK; } entry = entry->next; } // Create new entry bsp_config_storage_entry_t* new_entry = malloc(sizeof(bsp_config_storage_entry_t)); if (new_entry == NULL) { return HAL_OUT_OF_MEMORY; } strncpy(new_entry->section, section, sizeof(new_entry->section) - 1); strncpy(new_entry->key, key, sizeof(new_entry->key) - 1); strncpy(new_entry->value, value, sizeof(new_entry->value) - 1); new_entry->section[sizeof(new_entry->section) - 1] = '\0'; new_entry->key[sizeof(new_entry->key) - 1] = '\0'; new_entry->value[sizeof(new_entry->value) - 1] = '\0'; new_entry->next = NULL; // Add to list if (bsp_config_storage.entries == NULL) { bsp_config_storage.entries = new_entry; } else { entry = bsp_config_storage.entries; while (entry->next != NULL) { entry = entry->next; } entry->next = new_entry; } bsp_config_storage.entry_count++; return HAL_OK; } /** * @brief 清空配置存储 */ static void bsp_config_storage_clear(void) { bsp_config_storage_entry_t* entry = bsp_config_storage.entries; while (entry != NULL) { bsp_config_storage_entry_t* next = entry->next; free(entry); entry = next; } bsp_config_storage.entries = NULL; bsp_config_storage.entry_count = 0; } /** * @brief 初始化 BSP 配置系统 * @retval HAL 状态码 */ hal_ret_t bsp_config_init(void) { if (bsp_config_storage.initialized) { return HAL_OK; } bsp_config_storage_clear(); bsp_config_storage.initialized = 1; return HAL_OK; } /** * @brief 反初始化 BSP 配置系统 * @retval HAL 状态码 */ hal_ret_t bsp_config_deinit(void) { if (!bsp_config_storage.initialized) { return HAL_OK; } bsp_config_storage_clear(); bsp_config_storage.initialized = 0; return HAL_OK; } /** * @brief 从文件加载 BSP 配置 * @param filename: 配置文件名称 * @retval HAL 状态码 */ hal_ret_t bsp_config_load(const char* filename) { if (!bsp_config_storage.initialized) { hal_ret_t status = bsp_config_init(); if (status != HAL_OK) { return status; } } bsp_config_parser_t parser; hal_ret_t status = bsp_config_file_open(filename, &parser); if (status != HAL_OK) { return status; } bsp_config_entry_t entry; while ((status = bsp_config_file_read_entry(&parser, &entry)) == HAL_OK) { status = bsp_config_storage_add(entry.section, entry.key, entry.value); if (status != HAL_OK) { bsp_config_file_close(&parser); return status; } } if (status != HAL_TIMEOUT) { bsp_config_file_close(&parser); return status; } status = bsp_config_file_close(&parser); if (status != HAL_OK) { return status; } return HAL_OK; } /** * @brief 保存 BSP 配置到文件 * @param filename: 配置文件名称 * @retval HAL 状态码 */ hal_ret_t bsp_config_save(const char* filename) { if (!bsp_config_storage.initialized || bsp_config_storage.entry_count == 0) { return HAL_OK; } FILE* file = fopen(filename, "w"); if (file == NULL) { return HAL_ERROR; } fprintf(file, "# BSP Configuration File\n"); fprintf(file, "# Version: %s\n\n", BSP_CONFIG_FILE_VERSION); char current_section[BSP_CONFIG_MAX_SECTION_NAME_LENGTH] = ""; bsp_config_storage_entry_t* entry = bsp_config_storage.entries; while (entry != NULL) { if (strcmp(entry->section, current_section) != 0) { // New section strncpy(current_section, entry->section, sizeof(current_section) - 1); fprintf(file, "[%s]\n", current_section); } fprintf(file, "%s=%s\n", entry->key, entry->value); entry = entry->next; } fclose(file); return HAL_OK; } /** * @brief 获取配置值 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 存储值的指针 * @param max_length: 值缓冲区的最大长度 * @retval HAL 状态码 */ hal_ret_t bsp_config_get_value(const char* section, const char* key, char* value, size_t max_length) { if (!bsp_config_storage.initialized || section == NULL || key == NULL || value == NULL) { return HAL_INVALID_PARAM; } bsp_config_storage_entry_t* entry = bsp_config_storage.entries; while (entry != NULL) { if (strcmp(entry->section, section) == 0 && strcmp(entry->key, key) == 0) { strncpy(value, entry->value, max_length - 1); value[max_length - 1] = '\0'; return HAL_OK; } entry = entry->next; } return HAL_NOT_SUPPORTED; } /** * @brief 设置配置值 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 配置值 * @retval HAL 状态码 */ hal_ret_t bsp_config_set_value(const char* section, const char* key, const char* value) { if (!bsp_config_storage.initialized || section == NULL || key == NULL || value == NULL) { return HAL_INVALID_PARAM; } return bsp_config_storage_add(section, key, value); } /** * @brief 获取配置值作为整数 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 存储整数值的指针 * @retval HAL 状态码 */ hal_ret_t bsp_config_get_int(const char* section, const char* key, int* value) { char str_value[BSP_CONFIG_MAX_VALUE_LENGTH]; hal_ret_t status = bsp_config_get_value(section, key, str_value, sizeof(str_value)); if (status != HAL_OK) { return status; } return bsp_config_parse_int(str_value, value); } /** * @brief 设置配置值作为整数 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 整数值 * @retval HAL 状态码 */ hal_ret_t bsp_config_set_int(const char* section, const char* key, int value) { char str_value[BSP_CONFIG_MAX_VALUE_LENGTH]; snprintf(str_value, sizeof(str_value), "%d", value); return bsp_config_set_value(section, key, str_value); } /** * @brief 获取配置值作为无符号整数 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 存储无符号整数值的指针 * @retval HAL 状态码 */ hal_ret_t bsp_config_get_uint(const char* section, const char* key, uint32_t* value) { char str_value[BSP_CONFIG_MAX_VALUE_LENGTH]; hal_status_t status = bsp_config_get_value(section, key, str_value, sizeof(str_value)); if (status != HAL_OK) { return status; } return bsp_config_parse_uint(str_value, value); } /** * @brief 设置配置值作为无符号整数 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 无符号整数值 * @retval HAL 状态码 */ hal_ret_t bsp_config_set_uint(const char* section, const char* key, uint32_t value) { char str_value[BSP_CONFIG_MAX_VALUE_LENGTH]; snprintf(str_value, sizeof(str_value), "%lu", (unsigned long)value); return bsp_config_set_value(section, key, str_value); } /** * @brief 获取配置值作为布尔值 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 存储布尔值的指针 * @retval HAL 状态码 */ hal_ret_t bsp_config_get_bool(const char* section, const char* key, uint8_t* value) { char str_value[BSP_CONFIG_MAX_VALUE_LENGTH]; hal_status_t status = bsp_config_get_value(section, key, str_value, sizeof(str_value)); if (status != HAL_OK) { return status; } return bsp_config_parse_bool(str_value, value); } /** * @brief 设置配置值作为布尔值 * @param section: 配置节名称 * @param key: 配置键名称 * @param value: 布尔值 * @retval HAL 状态码 */ hal_ret_t bsp_config_set_bool(const char* section, const char* key, uint8_t value) { return bsp_config_set_value(section, key, value ? "true" : "false"); } /** * @brief 从配置解析 BSP 模块 * @param config: 指向要填充的 BSP 板卡配置结构体的指针 * @retval HAL 状态码 */ hal_ret_t bsp_config_parse_modules(bsp_board_config_t* config) { if (config == NULL) { return HAL_INVALID_PARAM; } // TODO: Implement module parsing logic // This will depend on the specific configuration file format // and how modules are defined in the configuration return HAL_OK; } /** * @brief 从配置文件初始化 BSP * @param filename: 配置文件名称 * @retval HAL 状态码 */ hal_ret_t bsp_init_from_config(const char* filename) { // Load configuration file hal_ret_t status = bsp_config_load(filename); if (status != HAL_OK) { return status; } // Initialize HAL layer status = hal_init(); if (status != HAL_OK) { return status; } // Initialize BSP module manager status = bsp_module_manager_init(); if (status != HAL_OK) { return status; } // Create board configuration from file bsp_board_config_t board_config; memset(&board_config, 0, sizeof(board_config)); // Parse board information char board_name[64]; status = bsp_config_get_value("board", "name", board_name, sizeof(board_name)); if (status == HAL_OK) { board_config.name = strdup(board_name); } else { board_config.name = "Unknown"; } uint32_t version = BSP_CONFIG_VERSION; status = bsp_config_get_uint("board", "version", &version); if (status == HAL_OK) { board_config.version = version; } else { board_config.version = BSP_CONFIG_VERSION; } // Parse modules from configuration status = bsp_config_parse_modules(&board_config); if (status != HAL_OK) { return status; } // Initialize board status = bsp_board_init(); if (status != HAL_OK) { return status; } // Initialize all modules status = bsp_module_init_all(); if (status != HAL_OK) { return status; } // Configure all modules // TODO: Implement module configuration from file // Start all modules status = bsp_module_start_all(); if (status != HAL_OK) { return status; } return HAL_OK; }