0%

AliOS-Things KV

AliOS-Things 中 KV 代码分析。

block

block 的头部如下:

1
2
3
4
5
6
/* Flash block header description */
typedef struct _block_header_t {
uint8_t magic; /* The magic number of block */
uint8_t state; /* The state of the block */
uint8_t reserved[2];
} __attribute__((packed)) block_hdr_t;
magic state reserved
ASCII ‘K’ 1B 2B

magic 是 ASCII 码 ‘K’:

1
static const uint8_t BLK_MAGIC_NUM  = 'K'; /* The block header magic number */

state 有 3 种:

1
2
3
#define BLK_STATE_USED  0xCC /* Block state: USED --> block is inused and without dirty data */
#define BLK_STATE_CLEAN 0xEE /* Block state: CLEAN --> block is clean, ready for used */
#define BLK_STATE_DIRTY 0x44 /* Block state: DIRTY --> block is inused and with dirty data */

item

item 的头部如下:

1
2
3
4
5
6
7
8
9
/* Key-value item header description */
typedef struct _item_header_t {
uint8_t magic; /* The magic number of key-value item */
uint8_t state; /* The state of key-value item */
uint8_t crc; /* The crc-8 value of key-value item */
uint8_t key_len; /* The length of the key */
uint16_t val_len; /* The length of the value */
uint16_t origin_off; /* The origin key-value item offset, it will be used when updating */
} __attribute__((packed)) item_hdr_t;
magic state crc key_len val_len origin_off
ASCII ‘I’ 1B 1B 1B 2B 2B

magic 是 ASCII 码 ‘I’:

1
static const uint8_t ITEM_MAGIC_NUM = 'I'; /* The key-value item header magic number */

state 有 2 种:

1
2
#define ITEM_STATE_NORMAL 0xEE /* Key-value item state: NORMAL --> the key-value item is valid */
#define ITEM_STATE_DELETE 0 /* Key-value item state: DELETE --> the key-value item is deleted */

crc 是 key 和 value 的 8 bit 校验码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* CRC-8: the poly is 0x31 (x^8 + x^5 + x^4 + 1) */
static uint8_t utils_crc8(uint8_t *buf, uint16_t length)
{
uint8_t crc = 0x00;
uint8_t i;

while (length--) {
crc ^= *buf++;
for (i = 8; i > 0; i--) {
if (crc & 0x80) {
crc = (crc << 1) ^ 0x31;
} else {
crc <<= 1;
}
}
}

return crc;
}

key_len 是 key 的长度

val_len 是 value 的长度

origin_off 是上个旧 item 的 offset

通过一个实验来理解,例如,我 set name snowyang,然后 set name snowyang-1992,再 set name snowyang-19920202,最后 dump 出来的 binary 如下:

1
2
3
4
5
6
00000000h: 4B 44 00 00 49 00 98 04 08 00 00 00 6E 61 6D 65 ; KD..I.......name
00000010h: 73 6E 6F 77 79 61 6E 67 49 00 37 04 0D 00 04 00 ; snowyangI.7.....
00000020h: 6E 61 6D 65 73 6E 6F 77 79 61 6E 67 2D 31 39 39 ; namesnowyang-199
00000030h: 32 00 00 00 49 EE D6 04 11 00 18 00 6E 61 6D 65 ; 2...IîÖ.....name
00000040h: 73 6E 6F 77 79 61 6E 67 2D 31 39 39 32 30 32 30 ; snowyang-1992020
00000050h: 32 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF ; 2...ÿÿÿÿÿÿÿÿÿÿÿÿ

可见第二个 item 的 origin_off 是 0x04,也就是第一个 item 的地址,同样地,第三个 item 的 origin_off 是第二个 item 的地址 0x18

具体作用不明

描述 item 的结构体如下:

1
2
3
4
5
6
7
/* Key-value item description */
typedef struct _kv_item_t {
item_hdr_t hdr; /* The header of the key-value item, detail see the item_hdr_t structure */
char *store; /* The store buffer for key-value */
uint16_t len; /* The length of the buffer */
uint16_t pos; /* The store position of the key-value item */
} kv_item_t;

需要注意:这个结构体是用来描述一个 item 的,是一个变量,不是描述 item 的存储结构的

hdr 是上述头部

store 是实际存储 key 和 value 的 buffer,一般是 malloc 来的

len 是 header + key + value 的长度,注意是 4 字节对齐

1
len = (ITEM_HEADER_SIZE + hdr->key_len + hdr->val_len + ~KV_ALIGN_MASK) & KV_ALIGN_MASK;

pos 是 item 在 flash 中的地址

坚持原创技术分享,您的支持将鼓励我继续创作!