新增静态库及配置
This commit is contained in:
@@ -54,7 +54,7 @@ static cfg_app_t const s_cfg_app_default = {
|
||||
.strip_pwrup = 0, // 使用灯带上电效果
|
||||
.strip_show_rf = 0, // 在灯带中用一个灯来显示射频数据接口状态的灯效图层
|
||||
.strip_link_fc = 0, // 开启灯带联动飞控
|
||||
.ws2812_bat_led_mode = 1, // 电量灯效, 0: 关闭, 1: 普通飞控, 2: 竞速飞控, 3: 固定翼飞控
|
||||
.ws2812_bat_led_mode = 0, // 电量灯效, 0: 关闭, 1: 普通飞控, 2: 竞速飞控, 3: 固定翼飞控
|
||||
},
|
||||
.ws2812_bat_led_direction = 0, // 0: 正向,1: 反向(正反向是指灯珠的连接方式,正向是指从第一个灯珠开始,反向是指从最后一个灯珠开始)
|
||||
.ws2812_bat_led_color = 0xFFFFFF, // 电量灯颜色, RGB颜色值,如 0xFFFFFF 代表白色(默认)
|
||||
|
||||
276
app/config/app_log.c
Normal file
276
app/config/app_log.c
Normal file
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* @file app_log.c
|
||||
* @author LokLiang
|
||||
* @brief app_log.h 模块源码
|
||||
* @version 0.1
|
||||
* @date 2023-11-242
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#include "app_log.h"
|
||||
#include "nvs.h"
|
||||
#include "utils/crc.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#undef CONFIG_SYS_LOG_LEVEL
|
||||
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
|
||||
#define SYS_LOG_DOMAIN "APLOG"
|
||||
#define CONS_ABORT()
|
||||
#include "sys_log.h"
|
||||
|
||||
#define _NVS_KEY_MAIN "log-main"
|
||||
|
||||
/* 数据区 -------------------------------------------------------------------------------------- */
|
||||
|
||||
extern nvs_handle g_nvs_hdl;
|
||||
|
||||
static struct
|
||||
{
|
||||
os_time_t flight_time_start;
|
||||
} s_cm;
|
||||
|
||||
/* nvs 接口 ------------------------------------------------------------------------------------ */
|
||||
|
||||
static int _read_key(const char *key, void *out_value, size_t tar_length, uint32_t *crc_base);
|
||||
static int _set_crc(const void *struct_base, size_t struct_length, uint32_t *crc_base);
|
||||
static int _do_factory_set(log_app_t *log);
|
||||
|
||||
/**
|
||||
* @brief 读取指定的数据,并按给出的特性进行校验,返回校验结果
|
||||
*
|
||||
* @param key 在 nvs 的存储块的键值
|
||||
* @param out_value[out] 输出内存
|
||||
* @param tar_length 输出的内存预期的长度
|
||||
* @param crc_base[io] CRC 校验值所在内存块的地址(绝对值)。输入:校验值,输出:新的正确校验值
|
||||
* @retval 0 正确读取了已存储数据
|
||||
* @retval 1 nvs 模块可用, CRC 校验值已更新
|
||||
* @retval -1 nvs 模块不可用
|
||||
*/
|
||||
static int _read_key(const char *key, void *out_value, size_t tar_length, uint32_t *crc_base)
|
||||
{
|
||||
size_t required_size = 0;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
/* 在确认已存储的数据长度前,仅获取长度以免数据溢出 */
|
||||
err = nvs_get_blob(g_nvs_hdl, key, NULL, &required_size);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
SYS_LOG_WRN("failed to read prfsdata data length, err:%d", err);
|
||||
return -1;
|
||||
}
|
||||
if (required_size != tar_length)
|
||||
{
|
||||
SYS_LOG_WRN("invalid prfsdata length, length:%d, err:%d", required_size, err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 读出已存储的数据 */
|
||||
err = nvs_get_blob(g_nvs_hdl, key, out_value, &required_size);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
SYS_LOG_ERR("failed to read prfsdata data, err:%d", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 设置并校验 CRC */
|
||||
if (_set_crc(out_value, tar_length, crc_base))
|
||||
{
|
||||
SYS_LOG_WRN("read frs failed, incorrect crc and update");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 校验并更新结构体中 CRC 的值。
|
||||
* 这将校验整个结构(包含 CRC 本身),因此 CRC 自身的初始值为 0,然后更新 CRC 的结果到结构中
|
||||
*
|
||||
* @param struct_base 待分析和设置的内存块
|
||||
* @param struct_length 待分析和设置的内存块的实际长度
|
||||
* @param crc_base[io] CRC 校验值所在内存块的地址(绝对值)
|
||||
* @retval 0 校验正确
|
||||
* @retval 1 校验错误,并且设置了正确的校验值
|
||||
*/
|
||||
static int _set_crc(const void *struct_base, size_t struct_length, uint32_t *crc_base)
|
||||
{
|
||||
// 校验读出来的数据的正确性
|
||||
uint32_t crc_read = *crc_base;
|
||||
*crc_base = 0;
|
||||
*crc_base = crc32_calc(0, struct_base, struct_length);
|
||||
return (crc_read != *crc_base);
|
||||
}
|
||||
|
||||
static int _do_factory_set(log_app_t *log)
|
||||
{
|
||||
memset(log, 0, sizeof(*log));
|
||||
|
||||
log->flight_data.crc16 = crc16_calc(NULL, 0);
|
||||
|
||||
return app_log_do_save(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化
|
||||
*/
|
||||
void app_log_init(void)
|
||||
{
|
||||
SYS_ASSERT(g_nvs_hdl != 0, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 使内存的数据恢复到默认设置
|
||||
*
|
||||
* @retval 0 操作成功
|
||||
* @retval -1 操作失败
|
||||
*/
|
||||
int app_log_factory_set(void)
|
||||
{
|
||||
log_app_t *log = os_malloc(sizeof(log_app_t));
|
||||
if (log == NULL)
|
||||
{
|
||||
SYS_LOG_WRN("malloc fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = _do_factory_set(log);
|
||||
|
||||
os_free(log);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 立即执行保存 配置数据 到 nvs 的动作
|
||||
*
|
||||
* @param delay_ms 0: 立即保存, > 0 多少毫秒后执行保存
|
||||
* @return int @ref esp_err_t
|
||||
*/
|
||||
int app_log_do_save(log_app_t *log)
|
||||
{
|
||||
log->version = APP_LOG_DATA_VER;
|
||||
_set_crc(log, sizeof(*log), &log->crc32);
|
||||
esp_err_t err = nvs_set_blob(g_nvs_hdl, _NVS_KEY_MAIN, log, sizeof(*log));
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
SYS_LOG_WRN("nvs_set_blob() err: %d", err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 读接口 -------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 读取日志信息
|
||||
* 将从 nvs 读取已保存的数据到内存 log_app_t 中。
|
||||
* 当出现以下情况时,配置数据被恢复到默认值:
|
||||
* nvs 未初始化或操作失败;
|
||||
* 使用 app_log_factory_set() 立即恢复到默认值;
|
||||
* 结构体的长度 log_app_t 发生改变;
|
||||
* APP_CONFIG_DATA_VER 定义的值发生改变;
|
||||
*
|
||||
* @param out_log[out] 用于保存日志信息的内存
|
||||
* @retval 0 成功读取已有记录
|
||||
* @retval 1 已恢复默认设置
|
||||
* @retval -1 nvs 操作失败
|
||||
*/
|
||||
int app_log_read(log_app_t *out_log)
|
||||
{
|
||||
int ret = _read_key(_NVS_KEY_MAIN, out_log, sizeof(*out_log), &out_log->crc32);
|
||||
if (ret)
|
||||
{
|
||||
goto use_default_prfs;
|
||||
}
|
||||
if (out_log->version != APP_LOG_DATA_VER)
|
||||
{
|
||||
ret = 1;
|
||||
SYS_LOG_WRN("Upgrade to the latest version: %u ==> %u", out_log->version, APP_LOG_DATA_VER);
|
||||
goto use_default_prfs;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
use_default_prfs:
|
||||
_do_factory_set(out_log);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 写接口 -------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 开始计时
|
||||
*
|
||||
*/
|
||||
void app_log_flight_time_start(void)
|
||||
{
|
||||
log_app_t *log = os_malloc(sizeof(log_app_t));
|
||||
if (log == NULL)
|
||||
{
|
||||
SYS_LOG_WRN("malloc fail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (log->flight_data.flight_number < __ARRAY_SIZE(log->flight_data.datas))
|
||||
{
|
||||
s_cm.flight_time_start = os_get_sys_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
s_cm.flight_time_start = 0;
|
||||
SYS_LOG_INF("The maximum number of groups: %d", __ARRAY_SIZE(log->flight_data.datas));
|
||||
}
|
||||
|
||||
os_free(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 结束计时,并保存这个记录
|
||||
*
|
||||
*/
|
||||
void app_log_flight_time_stop(void)
|
||||
{
|
||||
if (s_cm.flight_time_start == 0)
|
||||
{
|
||||
SYS_LOG_WRN("never exec app_log_flight_time_start()");
|
||||
return;
|
||||
}
|
||||
|
||||
log_app_t *log = os_malloc(sizeof(log_app_t));
|
||||
if (log == NULL)
|
||||
{
|
||||
SYS_LOG_WRN("malloc fail");
|
||||
return;
|
||||
}
|
||||
|
||||
os_time_t time_cost_sec = (os_get_sys_time() - s_cm.flight_time_start) / 1000;
|
||||
if (time_cost_sec > 10)
|
||||
{
|
||||
log->flight_data.datas[log->flight_data.flight_number++] = time_cost_sec;
|
||||
log->flight_data.crc16 = crc16_calc(log->flight_data.datas, sizeof(log->flight_data.datas[0]) * log->flight_data.flight_number);
|
||||
app_log_do_save(log);
|
||||
}
|
||||
s_cm.flight_time_start = 0;
|
||||
|
||||
os_free(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 清除全部计时记录
|
||||
*
|
||||
*/
|
||||
void app_log_flight_time_clr(void)
|
||||
{
|
||||
log_app_t *log = os_malloc(sizeof(log_app_t));
|
||||
if (log == NULL)
|
||||
{
|
||||
SYS_LOG_WRN("malloc fail");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&log->flight_data, 0, sizeof(log->flight_data));
|
||||
app_log_do_save(log);
|
||||
|
||||
os_free(log);
|
||||
}
|
||||
74
app/config/app_log.h
Normal file
74
app/config/app_log.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @file app_log.h
|
||||
* @author LokLiang
|
||||
* @brief 用于应用控制程序的统一配置的数据结构
|
||||
* @version 0.1
|
||||
* @date 2023-11-24
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
* 本模块实现功能:
|
||||
* 1. 统一定义应用程序需要存储的所有数据;
|
||||
* 2. 依赖 nfs 模块,使当前数据与内部存储的数据实现同步;
|
||||
* 3. 依赖 sh_vset 模块,并提供其对应的所有设置实现函数;
|
||||
*
|
||||
* 对数据的读操作:
|
||||
* 上层应用:应用和模式管理模块和控制模块
|
||||
* 对外提 app_log_read() 读取数据
|
||||
*
|
||||
* 对数据的写操作:
|
||||
* 上层应用:
|
||||
* 为所有成员提供专门的写入接口,内部数据被立即更新。
|
||||
*
|
||||
* 数据的默认值:
|
||||
* 当出现以下情况时,配置数据被恢复到默认值:
|
||||
* nvs 未初始化或操作失败;
|
||||
* 使用 app_log_factory_set() 恢复到默认值;
|
||||
* 结构体的长度 log_app_t 发生改变;
|
||||
* APP_LOG_DATA_VER 定义的值发生改变(在 app_log.c 内部定义);
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sys_types.h"
|
||||
|
||||
#define APP_LOG_DATA_VER 1 /* 对应 log_app_t::version */
|
||||
|
||||
/* 数据结构 ------------------------------------------------------------------------------------ */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t flight_number; // 当前记录的飞行次数
|
||||
uint16_t crc16; // CRC16
|
||||
uint16_t datas[2048];
|
||||
} flight_data_t;
|
||||
|
||||
typedef struct // 设备配置统一数据结构
|
||||
{
|
||||
uint32_t version; // 配置版本,修改 APP_LOG_DATA_VER 的值后, nvs 已同步的数据被恢复到默认值
|
||||
|
||||
flight_data_t flight_data;
|
||||
|
||||
uint32_t crc32; // 校验数据(可放于任何位置)
|
||||
} log_app_t;
|
||||
|
||||
/* nvs 接口 ------------------------------------------------------------------------------------ */
|
||||
|
||||
void app_log_init(void); // 初始化
|
||||
|
||||
int app_log_factory_set(void); // 使内存的数据恢复到默认设置,注意不会被立即保存到 nvs 中
|
||||
|
||||
int app_log_do_save(log_app_t *log); // 保存配置数据 到 nvs 的动作
|
||||
|
||||
/* 读接口 -------------------------------------------------------------------------------------- */
|
||||
|
||||
int app_log_read(log_app_t *out_log);
|
||||
|
||||
/* 操作接口 ------------------------------------------------------------------------------------ */
|
||||
|
||||
/* 写接口 -------------------------------------------------------------------------------------- */
|
||||
|
||||
void app_log_flight_time_start(void);
|
||||
void app_log_flight_time_stop(void);
|
||||
void app_log_flight_time_clr(void);
|
||||
Reference in New Issue
Block a user