Chinaunix首页 | 论坛 | 博客
  • 博客访问: 61145
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-21 13:33
个人简介

业精于勤,荒于嬉;行成于思,毁于随。

文章分类

全部博文(14)

分类: 嵌入式

2017-11-18 10:10:40

    EasyFlash 是一款开源的轻量级嵌入式 Flash 存储器库,主要为MCU(Micro Control Unit)提供便捷、通用的上层应用接口,可以让 Flash 作为小型 KV 数据库。项目源码:
    该库目前提供 三大实用功能 :
  • Env 快速保存产品参数,支持 写平衡(磨损平衡) 及 掉电保护 模式
  • IAP 在线升级再也不是难事儿
  • Log 无需文件系统,日志可直接存储在Flash上
    
下载源码后可以看到三个主要的目录:demo(例程),docs(文档),easyflash.
easyflash目录:

inc(头文件),plugins(插件),port(移植),src(源文件)。
    目前 EasyFlash 会将环境变量以字符串形式存储于 Flash 中,在这种模式下,对于非字符串类型的环境变量在使用时,就必须得增加额外的字符串转换代码。设计 Types 插件就是为了方便用户在使用 EasyFlash 时,以更加简单的方式去操作各种类型的环境变量。
    插件目录下包含了types一个文件夹,里面实现了基本类型,数据类型,结构体类型的操作方法,具体内容看里面的README.md文档。下面列出他的基本接口函数:
1.基本类型:
 bool ef_get_bool(const char *key);
char ef_get_char(const char *key);
short ef_get_short(const char *key);
int ef_get_int(const char *key);
long ef_get_long(const char *key);
float ef_get_float(const char *key);
double ef_get_double(const char *key);
EfErrCode ef_set_bool(const char *key, bool value);
EfErrCode ef_set_char(const char *key, char value);
EfErrCode ef_set_short(const char *key, short value);
EfErrCode ef_set_int(const char *key, int value);
EfErrCode ef_set_long(const char *key, long value);
EfErrCode ef_set_float(const char *key, float value);
EfErrCode ef_set_double(const char *key, double value);
2.数组类型
void ef_get_bool_array(const char *key, bool *value);
void ef_get_char_array(const char *key, char *value);
void ef_get_short_array(const char *key, short *value);
void ef_get_int_array(const char *key, int *value);
void ef_get_long_array(const char *key, long *value);
void ef_get_float_array(const char *key, float *value);
void ef_get_double_array(const char *key, double *value);
void ef_get_string_array(const char *key, char **value);
EfErrCode ef_set_bool_array(const char *key, bool *value, size_t len);
EfErrCode ef_set_char_array(const char *key, char *value, size_t len);
EfErrCode ef_set_short_array(const char *key, short *value, size_t len);
EfErrCode ef_set_int_array(const char *key, int *value, size_t len);
EfErrCode ef_set_long_array(const char *key, long *value, size_t len);
EfErrCode ef_set_float_array(const char *key, float *value, size_t len);
EfErrCode ef_set_double_array(const char *key, double *value, size_t len);
EfErrCode ef_set_string_array(const char *key, char **value, size_t len);
3.结构体类型
void *ef_get_struct(const char *key, ef_types_get_cb get_cb);
EfErrCode ef_set_struct(const char *key, void *value, ef_types_set_cb set_cb);


里面还有一个结构体和jason的使用demo:
/* 定义结构体 */
typedef struct {
    char name[16];
} Hometown;
typedef struct {
    uint8_t id;
    double weight;
    uint8_t score[8];
    char name[16];
    Hometown hometown;
} Student;

/* 定义结构体转 JSON 的方法 */
static cJSON *stu_set_cb(void* struct_obj) {
    Student *struct_student = (Student *)struct_obj;
    /* 创建 Student JSON 对象 */
    s2j_create_json_obj(json_student);
    /* 序列化数据到 Student JSON 对象 */
    s2j_json_set_basic_element(json_student, struct_student, int, id);
    s2j_json_set_basic_element(json_student, struct_student, double, weight);
    s2j_json_set_array_element(json_student, struct_student, int, score, 8);
    s2j_json_set_basic_element(json_student, struct_student, string, name);
    /* 序列化数据到 Student.Hometown JSON 对象 */
    s2j_json_set_struct_element(json_hometown, json_student, struct_hometown, struct_student, Hometown, hometown);
    s2j_json_set_basic_element(json_hometown, struct_hometown, string, name);
    return json_student;
}


/* 定义 JSON 转结构体的方法 */
static void *stu_get_cb(cJSON* json_obj) {
    /* 创建 Student 结构体对象(提示: s2j_ 开头的方法是 struct2json 库提供的) */
    s2j_create_struct_obj(struct_student, Student);
    /* 反序列化数据到 Student 结构体对象 */
    s2j_struct_get_basic_element(struct_student, json_obj, int, id);
    s2j_struct_get_array_element(struct_student, json_obj, int, score);
    s2j_struct_get_basic_element(struct_student, json_obj, string, name);
    s2j_struct_get_basic_element(struct_student, json_obj, double, weight);
    /* 反序列化数据到 Student.Hometown 结构体对象 */
    s2j_struct_get_struct_element(struct_hometown, struct_student, json_hometown, json_obj, Hometown, hometown);
    s2j_struct_get_basic_element(struct_hometown, json_hometown, string, name);
    return struct_student;
}


/* 设置结构体类型环境变量 */
Student orignal_student = {
        .id = 24,
        .weight = 71.2,
        .score = {1, 2, 3, 4, 5, 6, 7, 8},
        .name = "张三",
        .hometown.name = "北京",
};
ef_set_struct("张三学生", &orignal_student, stu_set_cb);


/* 获取结构体类型环境变量 */
Student *student;
ef_get_struct("张三学生", student, stu_get_cb);


/* 打印获取到的结构体内容 */
printf("姓名:%s 籍贯:%s \n", student->name, student->hometown.name);


/* 释放获取结构体类型环境变量过程中开辟的动态内存 */
s2jHook.free_fn(student);


下面打开\demo\env\stm32f10x\non_os_spi_flash的例程。
该例程一个第三方库SFUD库(serial flash universal driver)串行flash通用驱动库
项目源码:
 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,让我们的产品能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。设计原理是基于SFDP标准,该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数,如果该 Flash 不支持 SFDP,则查询配置文件 (  ) 中提供的 Flash 参数信息表 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 )。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。

    我更主张大家去看源官方的文档,毕竟人家是设计者,我们是使用者,理解的深度都不一样了。





    
    




阅读(3373) | 评论(0) | 转发(0) |
0

上一篇:UML建模-概述

下一篇:EasyFlash 配置

给主人留下些什么吧!~~