对申报的RVB2601创意项目经过一段时间的分模块开发后,本人准备开始将模块整合为完整的系统,特将整合过程分篇记录下来,本篇记录KV组件。
KV,即“Key-Value”,是YoC(Yun on Chip)中一个进行持久化存储的轻量级组件,主要用于Nor Flash。来自于SDK(kv v7.4.3)的README.md中的API说明如下图所示。
图2-1 KV接口说明
KV存储,必须建立在Flash分区的基础之上,所以必须要先建立分区,在“Hello World”案例中,分区初始化的代码是注释掉的,所以需要把注释去掉才可以——这里也算一个坑吧,当时困扰了许久(其实也是不细心)。
图2-2 分区初始化默认被注释了
本人的项目中需要存储若干配置参数,为了这些参数搞个文件系统,实在没有必要,而KV组件正好可以满足需求。
这里导入的是“Hello World Demo”,并在“app/src/init.c”中添加KV初始化的代码。
#include <stdbool.h>
#include <aos/aos.h>
#include <yoc/yoc.h>
#include <yoc/partition.h>
#include <devices/devicelist.h>
#include "board.h"
#include "app_init.h"
#include "drv/pin.h"
const char *TAG = "INIT";
#ifndef CONSOLE_UART_IDX
#define CONSOLE_UART_IDX 0
#endif
/* --------------------by AITA Mr.Fei, global variables--------------------- */
#define ENDIAN_LIMIT 32 //endian counts limit
char GID[9]; //gateway id
char EID[ENDIAN_LIMIT][9];//endians' id
int endian_count = 1; //actually endian counts
int period = 10; //polling period -- minutes
int timeout = 15; //timeout of waiting USR220 resp -- seconds
int repeat = 3; //repeat times when timeout
int aita_InitKV(void) {
char buf[10] = {0};
int ret = -1;
ret = partition_init();
if (ret > 0) {
LOGI(TAG, "find %d partitions\n", ret);
} else {
LOGE(TAG, "partition init failed\n");
return ret;
}
ret = aos_kv_init("kv");
if(ret == 0) {
LOGE(TAG, "kv init done\n");
} else {
LOGE(TAG, "kv init failed\n");
return -1;
}
ret = aos_kv_getstring("endian_count", &buf, 10);
if(ret > 0) {
endian_count = atoi(buf);
endian_count = (endian_count<ENDIAN_LIMIT) ? endian_count : ENDIAN_LIMIT;
printf("endian_count: %d\n", endian_count);
char eid[5] = "EIDx";
for(int i=0; i<endian_count; i++) {
eid[3] = i+0x30;
aos_kv_getstring(eid, EID[i], 9);
printf("EID No.%d : %s\n", i, EID[i]);
}
} else {
LOGE(TAG, "Endian Count load failed\n");
return ret;
}
ret = aos_kv_getstring("period", &buf, 10);
if(ret > 0) {
period = atoi(buf);
printf("period: %d\n", period);
} else {
LOGE(TAG, "period load failed\n");
return ret;
}
ret = aos_kv_getstring("timeout", &buf, 10);
if(ret > 0) {
timeout = atoi(buf);
printf("timeout: %d\n", timeout);
} else {
LOGE(TAG, "timeout load failed\n");
return ret;
}
ret = aos_kv_getstring("repeat", &buf, 10);
if(ret > 0) {
repeat = atoi(buf);
printf("repeat: %d\n", repeat);
} else {
LOGE(TAG, "repeat load failed\n");
return ret;
}
return 0;
}
void board_yoc_init()
{
board_init();
// uart_csky_register(CONSOLE_UART_IDX);
console_init(CONSOLE_UART_IDX, 115200, 128);
ulog_init();
aos_set_log_level(AOS_LL_DEBUG);
LOGI(TAG, "Build:%s,%s",__DATE__, __TIME__);
aita_InitKV();
board_cli_init();
}
main.c则先对KV组件进行测试,系统启动时在控制台输出KV值。为了不受定时输出的“Hello World”影响,代码中改为了流水灯功能,具体实现大家可以参考博主TL-LED的博文“【平头哥RVB2601开发板试用体验】 GPIO输出测试(https://bbs.eeworld.com.cn/thread-1197715-1-1.html)”。
#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include "oled.h"
#define TAG "app"
int main(void) {
board_yoc_init();
LOGD(TAG, "%s\n", aos_get_app_version());
aita_InitBSP();
while (1) {
aita_FlashLED();
}
return 0;
}
void aita_InitBSP(void) {
oled_init();
aita_InitLED();
}
给出我自己的LED GPIO初始化和流水灯实现的代码。
#include <aos/aos.h>
#include <drv/pin.h>
#include <drv/gpio_pin.h>
csi_gpio_pin_t aita_led_red_pin;
csi_gpio_pin_t aita_led_green_pin;
csi_gpio_pin_t aita_led_blue_pin;
void aita_InitLED(void) {
//set pin gpio function
csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
csi_pin_set_mux(PA4, PIN_FUNC_GPIO);
//init pin device & set direction
csi_gpio_pin_init(&aita_led_red_pin, PA7);
csi_gpio_pin_dir(&aita_led_red_pin, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&aita_led_green_pin, PA25);
csi_gpio_pin_dir(&aita_led_green_pin, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&aita_led_blue_pin, PA4);
csi_gpio_pin_dir(&aita_led_blue_pin, GPIO_DIRECTION_OUTPUT);
//set leds' state at startup
csi_gpio_pin_write(&aita_led_red_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_green_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_blue_pin, GPIO_PIN_HIGH);
}
void aita_FlashLED(void) {
csi_gpio_pin_write(&aita_led_red_pin, GPIO_PIN_LOW);
csi_gpio_pin_write(&aita_led_green_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_blue_pin, GPIO_PIN_HIGH);
aos_msleep(1000);
csi_gpio_pin_write(&aita_led_red_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_green_pin, GPIO_PIN_LOW);
csi_gpio_pin_write(&aita_led_blue_pin, GPIO_PIN_HIGH);
aos_msleep(1000);
csi_gpio_pin_write(&aita_led_red_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_green_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_blue_pin, GPIO_PIN_LOW);
aos_msleep(1000);
csi_gpio_pin_write(&aita_led_red_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_green_pin, GPIO_PIN_HIGH);
csi_gpio_pin_write(&aita_led_blue_pin, GPIO_PIN_HIGH);
aos_msleep(1000);
}
图2-3 启动时控制台输出KV存储值
当然,这些KV值都是提前写入的。项目开启了KV的控制台命令,这样可以随时修改项目参数。考虑到实际应用时,现场也可以接入串口进行调试,因此,控制台作为配置参数的方式。开启控制台KV命令,只需调用api即可,本例写在board_cli_init()函数中。
#include <aos/debug.h>
#include <aos/cli.h>
void board_cli_init()
{
aos_cli_init();
extern void cli_reg_cmd_ps(void);
cli_reg_cmd_ps();
extern void cli_reg_cmd_free(void);
cli_reg_cmd_free();
//cli command of kv func
extern void cli_reg_cmd_kvtool(void);
cli_reg_cmd_kvtool();
}
引用: freebsder 发表于 2022-4-12 17:16 KV这块有可以独立使用的源代码吗?
只是几个API呀,这里添加了控制台命令,也是为了编辑KV值方便而已。