-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathtinyFlash.c
executable file
·205 lines (168 loc) · 5.84 KB
/
tinyFlash.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "tinyFlash.h"
static unsigned char _buf[TINY_BUFFER_SIZE] = { 0 };
static unsigned long tinyFlash_Used_Addr = 0; //当前使用的扇区地址
static unsigned long tinyFlash_Swap_Addr = 0; //当前未使用的扇区地址
bool tinyFlash_Init()
{
memset(_buf, 0 , TINY_BUFFER_SIZE);
_flash_read(TINY_START_ADDR, TINY_BUFFER_SIZE, _buf);
if(_buf[0] != 0XFF) //第一个扇区在使用
{
tinyFlash_Used_Addr = TINY_START_ADDR;
tinyFlash_Swap_Addr = TINY_START_ADDR + TINY_SECTOR_SIZE;
}
else //第二个扇区在使用
{
tinyFlash_Used_Addr = TINY_START_ADDR + TINY_SECTOR_SIZE;
tinyFlash_Swap_Addr = TINY_START_ADDR;
}
return true;
}
int tinyFlash_Read(unsigned char KEY, unsigned char * outbuf, unsigned char * len)
{
unsigned long _addr_start = tinyFlash_Used_Addr + TINY_SECHAD_SIZE;;
unsigned long _addr_end = tinyFlash_Used_Addr + TINY_SECTOR_SIZE;
while(1)
{
if(_addr_start > _addr_end -3) //该扇区查找完毕
{
break;
}
_flash_read(_addr_start, TINY_BUFFER_SIZE, _buf);
if(_buf[0] == KEY) //目标KEY
{
if(_buf[1] == (KEY ^ 0xFF)) //该KEY正在使用中
{
if(len == NULL) //删除操作
{
_buf[0] = 0;
_flash_write(_addr_start + 1 , 1 , _buf);
}
else if(outbuf == NULL) //读取长度
{
*len = _buf[2];
}
else //读取数据
{
memcpy(outbuf, _buf + 3, _buf[2]);
*len = _buf[2];
}
return 0;
}
else //该KEY已被删除
{
_addr_start += (_buf[2] + 3);
continue;
}
}
else if((_buf[0] != 0) && (_buf[0] != 0xff)) //其他KEY
{
_addr_start += (_buf[2] + 3);
continue;
}
else //读取到扇区尾部未使用的区域
{
break;
}
}
return -1;
}
int tinyFlash_Write(unsigned char KEY, unsigned char * buf, unsigned char len)
{
tinyFlash_Read(KEY, NULL, NULL);
unsigned long _addr_start = tinyFlash_Used_Addr + TINY_SECHAD_SIZE;;
unsigned long _addr_end = tinyFlash_Used_Addr + TINY_SECTOR_SIZE;
unsigned long dirty_data_len = 0;
while(1)
{
if(_addr_start > _addr_end -3 - len) //该扇区已查找完毕,无可用空间
{
if(dirty_data_len > 0) //当前扇区中存在脏数据
{
tinyFlash_Swap(); //交换新旧扇区,清理脏数据
_addr_start = tinyFlash_Used_Addr + TINY_SECHAD_SIZE;;
_addr_end = tinyFlash_Used_Addr + TINY_SECTOR_SIZE;
}
else //无可用空间
{
return -1;
}
}
_flash_read(_addr_start, TINY_BUFFER_SIZE, _buf);
if(_buf[0] == 0xFF) //该区域可使用
{
//at_print_hexstr(&_addr_start, 2);
_buf[0] = KEY;
_buf[1] = (KEY ^ 0xFF);
_buf[2] = len;
memcpy(_buf +3, buf, len);
_flash_write(_addr_start, len + 3, _buf);//写入数据
return 0;
}
else if(_buf[0] != 0) //已存储其他KEY
{
if(_buf[1] == 0) //脏数据
{
dirty_data_len += (_buf[2] + 3);
}
else if (_buf[1] == (KEY ^ 0xFF)) //当前要写入的Key
{
_buf[0] = 0;
_flash_write(_addr_start + 1 , 1 , _buf);//删除数据
}
_addr_start += (_buf[2] + 3);
continue;
}
else //读取到错误的数据
{
break;
}
}
return 1;
}
void tinyFlash_Swap() //扇区使用完了,需要清理数据,才能存储别的数据
{
unsigned long _addr_start = tinyFlash_Used_Addr + TINY_SECHAD_SIZE; //当前使用的扇区的起始地址
unsigned long _addr_end = tinyFlash_Used_Addr + TINY_SECTOR_SIZE; //当前使用的扇区的结束地址
unsigned long _new_addr_start = tinyFlash_Swap_Addr + TINY_SECHAD_SIZE; //将要使用的扇区的起始地址
unsigned long tmp = 0;
while(1)
{
if(_addr_start > _addr_end -3) //该扇区已查找完毕,无可用空间
{
break;
}
_flash_read(_addr_start, TINY_BUFFER_SIZE, _buf);
if(_buf[0] == 0xFF) //数据转移完毕
{
break;
}
else if(_buf[0] == 0) //读取到了错误的数据
{
break;
}
else //读取到正确的Key数据
{
_addr_start += (_buf[2] + 3);
if(_buf[1] == (_buf[0] ^ 0xFF)) //数据仍有效(未删除)
{
tmp = _new_addr_start & 0xff;
_flash_write(_new_addr_start, _buf[2] + 3, _buf);
_new_addr_start += (_buf[2] + 3);
}
continue;
}
}
_buf[0] = 0xaa;
_flash_write(tinyFlash_Swap_Addr, 1, _buf); //将新扇区标记为在使用
_flash_sector_erase(tinyFlash_Used_Addr); //擦除旧扇区
_new_addr_start = tinyFlash_Swap_Addr;
tinyFlash_Swap_Addr = tinyFlash_Used_Addr;
tinyFlash_Used_Addr = _new_addr_start;
}
/*擦除所有扇区*/
void tinyFlash_Format(void)
{
_flash_sector_erase(tinyFlash_Used_Addr);//擦除旧扇区
_flash_sector_erase(tinyFlash_Swap_Addr);//擦除旧扇区
}