5 changed files with 360 additions and 0 deletions
-
39components/flash/flash_map.hpp
-
157components/flash/znvs.cpp
-
77components/flash/znvs.hpp
-
79components/flash/zsimple_flash.cpp
-
8components/flash/zsimple_flash.hpp
@ -0,0 +1,39 @@ |
|||
#pragma once
|
|||
#include "main.h"
|
|||
|
|||
/*******************************************************************************
|
|||
* STM32F407xx * |
|||
*******************************************************************************/ |
|||
#ifdef STM32F407xx
|
|||
|
|||
/**
|
|||
* @brief WARNING:需要注意407flash大小是有两款不同容量的,一款512K,一款1M |
|||
*/ |
|||
#define Z_FLASH_MAX_SECTOR_NUM 11
|
|||
|
|||
#define Z_FLASH_SECTOR_00_ADDR 0x08000000 // off:0
|
|||
#define Z_FLASH_SECTOR_01_ADDR 0x08004000 // off:16k
|
|||
#define Z_FLASH_SECTOR_02_ADDR 0x08008000 // off:32k
|
|||
#define Z_FLASH_SECTOR_03_ADDR 0x0800C000 // off:48k
|
|||
#define Z_FLASH_SECTOR_04_ADDR 0x08010000 // off:64k
|
|||
#define Z_FLASH_SECTOR_05_ADDR 0x08020000 // off:128k
|
|||
#define Z_FLASH_SECTOR_06_ADDR 0x08040000 // off:256k
|
|||
#define Z_FLASH_SECTOR_07_ADDR 0x08060000 // off:384k
|
|||
#define Z_FLASH_SECTOR_08_ADDR 0x08080000 // off:512k
|
|||
#define Z_FLASH_SECTOR_09_ADDR 0x080A0000 // off:640k
|
|||
#define Z_FLASH_SECTOR_10_ADDR 0x080C0000 // off:768k
|
|||
#define Z_FLASH_SECTOR_11_ADDR 0x080E0000 // off:896k
|
|||
|
|||
#define Z_FLASH_SECTOR_00_SIZE (16 * 1024)
|
|||
#define Z_FLASH_SECTOR_01_SIZE (16 * 1024)
|
|||
#define Z_FLASH_SECTOR_02_SIZE (16 * 1024)
|
|||
#define Z_FLASH_SECTOR_03_SIZE (16 * 1024)
|
|||
#define Z_FLASH_SECTOR_04_SIZE (64 * 1024)
|
|||
#define Z_FLASH_SECTOR_05_SIZE (128 * 1024)
|
|||
#define Z_FLASH_SECTOR_06_SIZE (128 * 1024)
|
|||
#define Z_FLASH_SECTOR_07_SIZE (128 * 1024)
|
|||
#define Z_FLASH_SECTOR_08_SIZE (128 * 1024)
|
|||
#define Z_FLASH_SECTOR_09_SIZE (128 * 1024)
|
|||
#define Z_FLASH_SECTOR_10_SIZE (128 * 1024)
|
|||
#define Z_FLASH_SECTOR_11_SIZE (128 * 1024)
|
|||
#endif
|
@ -0,0 +1,157 @@ |
|||
#include "znvs.hpp"
|
|||
|
|||
#include <string.h>
|
|||
|
|||
#include "sdk\components\flash\zsimple_flash.hpp"
|
|||
#define TAG "config"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace std; |
|||
#define MARK_S 0x123456
|
|||
#define MARK_E 0x87654321
|
|||
|
|||
#define GET_CFG(typename) \
|
|||
cfg_t* cfg = get_cfg(key); \ |
|||
if (cfg == nullptr || cfg->type != kcfg_type_##typename) { \ |
|||
allocate_cfg(key, kcfg_type_##typename, (uint8_t*)&default_val, sizeof(default_val)); \ |
|||
cfg = get_cfg(key); \ |
|||
} \ |
|||
return *(typename*)cfg->val; |
|||
|
|||
#define SET_CFG(typename) \
|
|||
cfg_t* cfg = get_cfg(key); \ |
|||
if (cfg == nullptr || cfg->type != kcfg_type_##typename) { \ |
|||
allocate_cfg(key, kcfg_type_##typename, (uint8_t*)&val, sizeof(val)); \ |
|||
cfg = get_cfg(key); \ |
|||
} else { \ |
|||
*(typename*)cfg->val = val; \ |
|||
flush(); \ |
|||
} |
|||
|
|||
ZNVS& ZNVS::ins() { |
|||
static ZNVS instance; |
|||
return instance; |
|||
} |
|||
void ZNVS::initialize() { |
|||
zsimple_flash_init(IFLYTOP_NVS_CONFIG_FLASH_SECTOR); |
|||
zsimple_flash_read((uint8_t*)&m_cfg, sizeof(m_cfg)); |
|||
if (m_cfg.config_start != MARK_S || m_cfg.config_end != MARK_E) { |
|||
ZLOGW(TAG, "config uninitialized, initialize it"); |
|||
memset(&m_cfg, 0, sizeof(m_cfg)); |
|||
m_cfg.config_start = MARK_S; |
|||
m_cfg.config_end = MARK_E; |
|||
zsimple_flash_write((uint8_t*)&m_cfg, sizeof(m_cfg)); |
|||
} else { |
|||
ZLOGI(TAG, "config initialized"); |
|||
} |
|||
} |
|||
|
|||
void ZNVS::factory_reset() { |
|||
memset(&m_cfg, 0, sizeof(m_cfg)); |
|||
m_cfg.config_start = MARK_S; |
|||
m_cfg.config_end = MARK_E; |
|||
zsimple_flash_write((uint8_t*)&m_cfg, sizeof(m_cfg)); |
|||
} |
|||
|
|||
ZNVS::cfg_t* ZNVS::get_cfg(const char* key) { |
|||
for (int i = 0; i < IFLYTOP_NVS_CONFIG_MAX_ITEM_NUM; i++) { |
|||
if (strcmp(m_cfg.cfgs[i].key, key) == 0) { |
|||
return &m_cfg.cfgs[i]; |
|||
} |
|||
} |
|||
return nullptr; |
|||
} |
|||
|
|||
void ZNVS::allocate_cfg(const char* key, type_t type, uint8_t* default_val, uint8_t len) { |
|||
cfg_t* cfg = get_cfg(key); |
|||
for (int i = 0; i < IFLYTOP_NVS_CONFIG_MAX_ITEM_NUM; i++) { |
|||
if (m_cfg.cfgs[i].is_initialed == false) { |
|||
cfg = &m_cfg.cfgs[i]; |
|||
strcpy(cfg->key, key); |
|||
cfg->is_initialed = true; |
|||
cfg->type = (uint8_t)type; |
|||
memcpy(cfg->val, default_val, len); |
|||
/**
|
|||
* @brief 刷新flash |
|||
* |
|||
* TODO:优化这里的代码,不要每次都刷新flash |
|||
*/ |
|||
zsimple_flash_write((uint8_t*)&m_cfg, sizeof(m_cfg)); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
ZNVS::cfg_t* ZNVS::get_and_create_cfg(const char* key, type_t type, uint8_t* default_val, uint8_t len) { |
|||
cfg_t* cfg = get_cfg(key); |
|||
if (cfg == nullptr) { |
|||
allocate_cfg(key, type, default_val, len); |
|||
cfg = get_cfg(key); |
|||
} |
|||
return cfg; |
|||
} |
|||
|
|||
void ZNVS::dumpcfg() { |
|||
ZLOGI(TAG, "=================dump nvs config =================="); |
|||
ZLOGI(TAG, "="); |
|||
for (int i = 0; i < IFLYTOP_NVS_CONFIG_MAX_ITEM_NUM; i++) { |
|||
if (m_cfg.cfgs[i].is_initialed) { |
|||
dumpcfg(&m_cfg.cfgs[i]); |
|||
} |
|||
} |
|||
ZLOGI(TAG, "============="); |
|||
} |
|||
|
|||
void ZNVS::dumpcfg(cfg_t* cfg) { |
|||
if (!cfg->is_initialed) return; |
|||
switch (cfg->type) { |
|||
case kcfg_type_int8_t: |
|||
ZLOGI(TAG, "= %s val:%d", cfg->key, *(int8_t*)cfg->val); |
|||
break; |
|||
case kcfg_type_int16_t: |
|||
ZLOGI(TAG, "= %s val:%d", cfg->key, *(int16_t*)cfg->val); |
|||
break; |
|||
case kcfg_type_int32_t: |
|||
ZLOGI(TAG, "= %s val:%d", cfg->key, *(int32_t*)cfg->val); |
|||
break; |
|||
|
|||
case kcfg_type_uint8_t: |
|||
ZLOGI(TAG, "= %s val:%u", cfg->key, *(int8_t*)cfg->val); |
|||
break; |
|||
case kcfg_type_uint16_t: |
|||
ZLOGI(TAG, "= %s val:%u", cfg->key, *(int16_t*)cfg->val); |
|||
break; |
|||
case kcfg_type_uint32_t: |
|||
ZLOGI(TAG, "= %s val:%u", cfg->key, *(int32_t*)cfg->val); |
|||
break; |
|||
case kcfg_type_float: |
|||
ZLOGI(TAG, "= %s val:%f", cfg->key, *(float*)cfg->val); |
|||
break; |
|||
case kcfg_type_bool: |
|||
ZLOGI(TAG, "= %s val:%d", cfg->key, *(bool*)cfg->val); |
|||
break; |
|||
default: |
|||
ZLOGI(TAG, "= %s val:unknow type", cfg->key); |
|||
break; |
|||
} |
|||
return; |
|||
} |
|||
|
|||
int8_t ZNVS::get_config_int8(const char* key, int8_t default_val) { GET_CFG(int8_t); } |
|||
void ZNVS::set_config_int8(const char* key, int8_t val) { SET_CFG(int8_t); } |
|||
uint8_t ZNVS::get_config_uint8(const char* key, uint8_t default_val) { GET_CFG(uint8_t); } |
|||
void ZNVS::set_config_uint8(const char* key, uint8_t val) { SET_CFG(uint8_t); } |
|||
int16_t ZNVS::get_config_int16(const char* key, int16_t default_val) { GET_CFG(int16_t); } |
|||
void ZNVS::set_config_int16(const char* key, int16_t val) { SET_CFG(int16_t); } |
|||
uint16_t ZNVS::get_config_uint16(const char* key, uint16_t default_val) { GET_CFG(uint16_t); } |
|||
void ZNVS::set_config_uint16(const char* key, uint16_t val) { SET_CFG(uint16_t); } |
|||
int32_t ZNVS::get_config_int32(const char* key, int32_t default_val) { GET_CFG(int32_t); } |
|||
void ZNVS::set_config_int32(const char* key, int32_t val) { SET_CFG(int32_t); } |
|||
uint32_t ZNVS::get_config_uint32(const char* key, uint32_t default_val) { GET_CFG(uint32_t); } |
|||
void ZNVS::set_config_uint32(const char* key, uint32_t val) { SET_CFG(uint32_t); } |
|||
float ZNVS::get_config_float(const char* key, float default_val) { GET_CFG(float); } |
|||
void ZNVS::set_config_float(const char* key, float val) { SET_CFG(float); } |
|||
bool ZNVS::get_config_bool(const char* key, bool default_val) { GET_CFG(bool); } |
|||
void ZNVS::set_config_bool(const char* key, bool val) { SET_CFG(bool); } |
|||
|
|||
void ZNVS::flush() { zsimple_flash_write((uint8_t*)&m_cfg, sizeof(m_cfg)); } |
@ -0,0 +1,77 @@ |
|||
#pragma once
|
|||
#include "project_configs.h"
|
|||
#include "sdk/os/zos.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
|
|||
class ZNVS { |
|||
typedef enum { |
|||
kcfg_type_int8_t, |
|||
kcfg_type_uint8_t, |
|||
kcfg_type_int16_t, |
|||
kcfg_type_uint16_t, |
|||
kcfg_type_int32_t, |
|||
kcfg_type_uint32_t, |
|||
kcfg_type_float, |
|||
kcfg_type_bool, |
|||
} type_t; |
|||
|
|||
#pragma pack(1)
|
|||
typedef struct { |
|||
char key[64]; |
|||
uint8_t val[8]; |
|||
uint8_t type; |
|||
bool is_initialed; |
|||
} cfg_t; |
|||
|
|||
typedef struct { |
|||
uint32_t config_start; |
|||
cfg_t cfgs[IFLYTOP_NVS_CONFIG_MAX_ITEM_NUM]; |
|||
uint32_t config_end; |
|||
} config_t; |
|||
#pragma pack()
|
|||
|
|||
config_t m_cfg; |
|||
|
|||
public: |
|||
static ZNVS& ins(); |
|||
|
|||
void initialize(); |
|||
void factory_reset(); |
|||
void dumpcfg(); |
|||
|
|||
int8_t get_config_int8(const char* key, int8_t default_val); |
|||
void set_config_int8(const char* key, int8_t val); |
|||
|
|||
uint8_t get_config_uint8(const char* key, uint8_t default_val); |
|||
void set_config_uint8(const char* key, uint8_t val); |
|||
|
|||
int16_t get_config_int16(const char* key, int16_t default_val); |
|||
void set_config_int16(const char* key, int16_t val); |
|||
|
|||
uint16_t get_config_uint16(const char* key, uint16_t default_val); |
|||
void set_config_uint16(const char* key, uint16_t val); |
|||
|
|||
int32_t get_config_int32(const char* key, int32_t default_val); |
|||
void set_config_int32(const char* key, int32_t val); |
|||
|
|||
uint32_t get_config_uint32(const char* key, uint32_t default_val); |
|||
void set_config_uint32(const char* key, uint32_t val); |
|||
|
|||
float get_config_float(const char* key, float default_val); |
|||
void set_config_float(const char* key, float val); |
|||
|
|||
bool get_config_bool(const char* key, bool default_val); |
|||
void set_config_bool(const char* key, bool val); |
|||
|
|||
private: |
|||
void dumpcfg(cfg_t* cfg); |
|||
|
|||
cfg_t* get_cfg(const char* key); |
|||
void allocate_cfg(const char* key, type_t type, uint8_t* default_val, uint8_t len); |
|||
cfg_t* get_and_create_cfg(const char* key, type_t type, uint8_t* default_val, uint8_t len); |
|||
void flush(); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,79 @@ |
|||
#include <stdio.h>
|
|||
#include <string.h>
|
|||
|
|||
#include "flash_map.hpp"
|
|||
#include "main.h"
|
|||
#include "project_configs.h"
|
|||
|
|||
static uint32_t m_sector_num = 0; |
|||
namespace iflytop { |
|||
uint32_t* zsimple_flash_get_add(int sector_num) { |
|||
switch (sector_num) { |
|||
case 0: |
|||
return (uint32_t*)Z_FLASH_SECTOR_00_ADDR; |
|||
case 1: |
|||
return (uint32_t*)Z_FLASH_SECTOR_01_ADDR; |
|||
case 2: |
|||
return (uint32_t*)Z_FLASH_SECTOR_02_ADDR; |
|||
case 3: |
|||
return (uint32_t*)Z_FLASH_SECTOR_03_ADDR; |
|||
case 4: |
|||
return (uint32_t*)Z_FLASH_SECTOR_04_ADDR; |
|||
case 5: |
|||
return (uint32_t*)Z_FLASH_SECTOR_05_ADDR; |
|||
case 6: |
|||
return (uint32_t*)Z_FLASH_SECTOR_06_ADDR; |
|||
case 7: |
|||
return (uint32_t*)Z_FLASH_SECTOR_07_ADDR; |
|||
case 8: |
|||
return (uint32_t*)Z_FLASH_SECTOR_08_ADDR; |
|||
case 9: |
|||
return (uint32_t*)Z_FLASH_SECTOR_09_ADDR; |
|||
case 10: |
|||
return (uint32_t*)Z_FLASH_SECTOR_10_ADDR; |
|||
case 11: |
|||
return (uint32_t*)Z_FLASH_SECTOR_11_ADDR; |
|||
default: |
|||
assert_param(0); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static HAL_StatusTypeDef pri_earse_sector() { |
|||
HAL_StatusTypeDef status; |
|||
uint32_t sector_error_point; |
|||
FLASH_EraseInitTypeDef flash_erase_structer = { |
|||
//
|
|||
.TypeErase = FLASH_TYPEERASE_SECTORS, //
|
|||
.Sector = m_sector_num, //
|
|||
.NbSectors = 1, //
|
|||
.VoltageRange = FLASH_VOLTAGE_RANGE_3 //
|
|||
}; |
|||
|
|||
HAL_FLASH_Unlock(); // 解锁
|
|||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); // 清除一些错误标志
|
|||
status = HAL_FLASHEx_Erase(&flash_erase_structer, §or_error_point); |
|||
HAL_FLASH_Lock(); // 上锁
|
|||
return status; |
|||
} |
|||
|
|||
void zsimple_flash_init(uint32_t sector_num) { m_sector_num = sector_num; } |
|||
void zsimple_flash_read(uint8_t* data, size_t len) { memcpy(data, zsimple_flash_get_add(m_sector_num), len); } |
|||
void zsimple_flash_write(const uint8_t* data, size_t len) { |
|||
pri_earse_sector(); |
|||
|
|||
uint32_t* from = (uint32_t*)data; |
|||
uint32_t* to = (uint32_t*)zsimple_flash_get_add(m_sector_num); |
|||
uint32_t writesize = len / 4; |
|||
|
|||
HAL_StatusTypeDef status; |
|||
HAL_FLASH_Unlock(); // 解锁
|
|||
for (size_t i = 0; i < writesize; i++) { |
|||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)to, *from); |
|||
from++; |
|||
to++; |
|||
} |
|||
HAL_FLASH_Lock(); // 上锁
|
|||
} |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,8 @@ |
|||
#pragma once
|
|||
#include <stdint.h>
|
|||
#include <stdlib.h>
|
|||
namespace iflytop { |
|||
void zsimple_flash_init(uint32_t sector_num); |
|||
void zsimple_flash_read(uint8_t* data, size_t len); |
|||
void zsimple_flash_write(const uint8_t* data, size_t len); |
|||
} // namespace iflytop
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue