XFusion API v1.3.0
载入中...
搜索中...
未找到
xf_fal.c
浏览该文件的文档.
1
12/* ==================== [Includes] ========================================== */
13
14#include "xf_utils.h"
15#include "xf_fal.h"
16
17/* ==================== [Defines] =========================================== */
18
19#define TAG "xf_fal"
20
21/* ==================== [Typedefs] ========================================== */
22
23/* ==================== [Static Prototypes] ================================= */
24
25/* ==================== [Static Variables] ================================== */
26
29#define sp_fal() (sp_fal_ctx)
30
31/* ==================== [Macros] ============================================ */
32
33#define XF_FAL_CTX_MUTEX_TRY_INIT() \
34 do { \
35 if (NULL == sp_fal()->mutex) { \
36 xf_lock_init(&sp_fal()->mutex); \
37 } \
38 } while (0)
39
40#define XF_FAL_CTX_MUTEX_TRY_DEINIT() \
41 do { \
42 if (NULL != sp_fal()->mutex) { \
43 xf_lock_destroy(sp_fal()->mutex); \
44 sp_fal()->mutex = NULL; \
45 } \
46 } while (0)
47
48#define XF_FAL_CTX_TRYLOCK__RETURN_ON_FAILURE(_ret) \
49 do { \
50 if (sp_fal()->mutex) { \
51 if (XF_LOCK_FAIL == xf_lock_trylock(sp_fal()->mutex)) { \
52 return _ret; \
53 } \
54 break; \
55 } \
56 if (true == sp_fal()->is_lock) { \
57 return _ret; \
58 } \
59 sp_fal()->is_lock = true; \
60 } while (0)
61
62#define XF_FAL_CTX_TRYLOCK__ANYWAY() \
63 do { \
64 if (sp_fal()->mutex) { \
65 xf_lock_trylock(sp_fal()->mutex); \
66 break; \
67 } \
68 sp_fal()->is_lock = true; \
69 } while (0)
70
71#define XF_FAL_CTX_UNLOCK() \
72 do { \
73 if (sp_fal()->mutex) { \
74 xf_lock_unlock(sp_fal()->mutex); \
75 break; \
76 } \
77 sp_fal()->is_lock = false; \
78 } while (0);
79
80#if XF_FAL_LOCK_IS_ENABLE == 0
81#undef XF_FAL_CTX_MUTEX_TRY_INIT
82#undef XF_FAL_CTX_MUTEX_TRY_DEINIT
83#undef XF_FAL_CTX_TRYLOCK__RETURN_ON_FAILURE
84#undef XF_FAL_CTX_TRYLOCK__ANYWAY
85#undef XF_FAL_CTX_UNLOCK
86#define XF_FAL_CTX_MUTEX_TRY_INIT()
87#define XF_FAL_CTX_MUTEX_TRY_DEINIT()
88#define XF_FAL_CTX_TRYLOCK__RETURN_ON_FAILURE(_ret)
89#define XF_FAL_CTX_TRYLOCK__ANYWAY()
90#define XF_FAL_CTX_UNLOCK()
91#endif
92
93/* ==================== [Global Functions] ================================== */
94
96{
97 xf_err_t xf_ret = XF_OK;
98 int idle_idx;
99
100 if (NULL == p_dev) {
101 return XF_ERR_INVALID_ARG;
102 }
103 if ((NULL == p_dev->ops.read)
104 || (NULL == p_dev->ops.write)
105 || (NULL == p_dev->ops.erase)
106 ) {
107 return XF_ERR_INVALID_PORT;
108 }
109
111
113
114 /* TODO 未检查 flash 设备名是否重复 */
115 idle_idx = -1;
116 for (size_t i = 0; i < XF_FAL_FLASH_DEVICE_NUM; i++) {
117 if (p_dev == sp_fal()->flash_device_table[i]) {
118 xf_ret = XF_ERR_INITED;
119 goto l_unlock_ret;
120 }
121 if ((NULL == sp_fal()->flash_device_table[i])
122 && (-1 == idle_idx)) {
123 idle_idx = i;
124 }
125 }
126 if (idle_idx == -1) {
127 xf_ret = XF_ERR_RESOURCE;
128 goto l_unlock_ret;
129 }
130
131 sp_fal()->flash_device_table[idle_idx] = p_dev;
132
133l_unlock_ret:;
135
136 return xf_ret;
137}
138
140 const xf_fal_partition_t *p_table, size_t table_len)
141{
142 xf_err_t xf_ret = XF_OK;
143 int idle_idx;
144
145 if ((NULL == p_table)
146 || ((0 == table_len))) {
147 return XF_ERR_INVALID_ARG;
148 }
149
151
153
154 /* TODO 未检查分区名是否重复 */
155 idle_idx = -1;
156 for (size_t i = 0; i < XF_FAL_PARTITION_TABLE_NUM; i++) {
157 if (p_table == sp_fal()->partition_table[i]) {
158 xf_ret = XF_ERR_INITED;
159 goto l_unlock_ret;
160 }
161 if ((NULL == sp_fal()->partition_table[i])
162 && (-1 == idle_idx)) {
163 idle_idx = i;
164 }
165 }
166 if (idle_idx == -1) {
167 xf_ret = XF_ERR_RESOURCE;
168 goto l_unlock_ret;
169 }
170
171 sp_fal()->partition_table[idle_idx] = p_table;
172 sp_fal()->partition_table_len[idle_idx] = table_len;
173
174l_unlock_ret:;
176
177 return xf_ret;
178}
179
181{
182 xf_err_t xf_ret = XF_OK;
183 int dev_idx;
184
185 if (NULL == p_dev) {
186 return XF_ERR_INVALID_ARG;
187 }
188
190
192
193 dev_idx = -1;
194 for (size_t i = 0; i < XF_FAL_FLASH_DEVICE_NUM; i++) {
195 if ((p_dev == sp_fal()->flash_device_table[i])) {
196 dev_idx = i;
197 break;
198 }
199 }
200 if (dev_idx == -1) {
201 xf_ret = XF_ERR_NOT_FOUND;
202 goto l_unlock_ret;
203 }
204
205 sp_fal()->flash_device_table[dev_idx] = NULL;
206
207l_unlock_ret:;
209
210 return xf_ret;
211}
212
214{
215 xf_err_t xf_ret = XF_OK;
216 int table_idx;
217
218 if (NULL == p_table) {
219 return XF_ERR_INVALID_ARG;
220 }
221
223
225
226 table_idx = -1;
227 for (size_t i = 0; i < XF_FAL_PARTITION_TABLE_NUM; i++) {
228 if ((p_table == sp_fal()->partition_table[i])) {
229 table_idx = i;
230 }
231 }
232 if (table_idx == -1) {
233 xf_ret = XF_ERR_NOT_FOUND;
234 goto l_unlock_ret;
235 }
236
237 sp_fal()->partition_table[table_idx] = NULL;
238 sp_fal()->partition_table_len[table_idx] = 0;
239
240l_unlock_ret:;
242
243 return xf_ret;
244}
245
247{
248 if (0 == sp_fal()->cached_num) {
249 return false;
250 }
251 return true;
252}
253
255{
256 return (const xf_fal_ctx_t *)sp_fal();
257}
258
260{
261 xf_err_t xf_ret;
262 const xf_fal_flash_dev_t *device_table;
263
264 if (sp_fal()->is_init) {
265 return XF_ERR_INITED;
266 }
267
268 /* 逐个初始化 */
269 for (size_t i = 0; i < XF_FAL_FLASH_DEVICE_NUM; i++) {
270 device_table = sp_fal()->flash_device_table[i];
271 if ((!device_table) || (!device_table->ops.init)) {
272 continue;
273 }
274 device_table->ops.init();
275 XF_LOGD(TAG, "Flash device | %*.*s | "
276 "addr: 0x%08x | len: 0x%08x | sector_size: 0x%08x | "
277 "initialized finish.",
279 device_table->addr, (int)device_table->len, (int)device_table->sector_size);
280 }
281
283 if (xf_ret != XF_OK) {
284 XF_LOGE(TAG, "partition init failed.");
285 return xf_ret;
286 }
287
288 sp_fal()->is_init = true;
289
290 return XF_OK;
291}
292
294{
295 const xf_fal_flash_dev_t *device_table;
296
298 return XF_ERR_INVALID_PORT;
299 }
300 if (!sp_fal()->is_init) {
301 return XF_ERR_UNINIT;
302 }
303
304 for (size_t i = 0; i < XF_FAL_FLASH_DEVICE_NUM; i++) {
305 device_table = sp_fal()->flash_device_table[i];
306 if ((!device_table) || (!device_table->ops.deinit)) {
307 continue;
308 }
309 device_table->ops.deinit();
310 }
311
312 sp_fal()->cached_num = 0;
313 sp_fal()->is_init = false;
314
315 return XF_OK;
316}
317
319{
320 const xf_fal_flash_dev_t *flash_device;
321 size_t i;
322
323 if (!name) {
324 return NULL;
325 }
326
327 /* 暂无递归互斥锁,此处不加锁没太大问题 */
328
329 for (i = 0; i < XF_FAL_FLASH_DEVICE_NUM; i++) {
330 flash_device = sp_fal()->flash_device_table[i];
331 if (!flash_device) {
332 continue;
333 }
334 if (0 == xf_strncmp(name, flash_device->name, XF_FAL_DEV_NAME_MAX)) {
335 return flash_device;
336 }
337 }
338
339 return NULL;
340}
341
343 const xf_fal_partition_t *part)
344{
345 const xf_fal_flash_dev_t *flash_dev = NULL;
346 size_t i;
347
348 if (!part) {
349 return NULL;
350 }
351
354 for (i = 0; i < sp_fal()->cached_num; i++) {
355 if (sp_fal()->cache[i].partition == part) {
356 flash_dev = sp_fal()->cache[i].flash_dev;
357 break;
358 }
359 }
360 }
361 /* 未注册或未找到时遍历 */
362 if (!flash_dev) {
363 flash_dev = xf_fal_flash_device_find(part->flash_name);
364 }
366
367 return flash_dev;
368}
369
371{
372 const xf_fal_partition_t *p_table;
373 const xf_fal_partition_t *part = NULL;
374 size_t table_len;
375 size_t i;
376 size_t j;
377
378 if (!name) {
379 return NULL;
380 }
381
383
384 for (i = 0; i < XF_FAL_PARTITION_TABLE_NUM; i++) {
385 p_table = sp_fal()->partition_table[i];
386 table_len = sp_fal()->partition_table_len[i];
387 if ((NULL == p_table) || (0 == table_len)) {
388 continue;
389 }
390 for (j = 0; j < table_len; j++) {
391 if (0 == xf_strncmp(name, p_table[j].name, XF_FAL_DEV_NAME_MAX)) {
392 part = &p_table[j];
393 goto l_unlock_ret;
394 }
395 }
396 }
397
398l_unlock_ret:;
400
401 return part;
402}
403
405 const xf_fal_partition_t *part,
406 size_t src_offset, void *dst, size_t size)
407{
408 xf_err_t xf_ret = XF_OK;
409 const xf_fal_flash_dev_t *flash_dev = NULL;
410
412 return XF_ERR_INVALID_PORT;
413 }
414 if (!sp_fal()->is_init) {
415 return XF_ERR_UNINIT;
416 }
417 if (!part || !dst || !size) {
418 return XF_ERR_INVALID_ARG;
419 }
420 if (src_offset + size > part->len) {
421 XF_LOGE(TAG, "Partition read error! "
422 "Partition(%s) address(0x%08x) out of bound(0x%08x).",
423 part->name, (int)(src_offset + size), (int)part->len);
424 return XF_ERR_INVALID_ARG;
425 }
426
427 flash_dev = xf_fal_flash_device_find_by_part(part);
428 if (flash_dev == NULL) {
429 XF_LOGE(TAG, "Partition read error! "
430 "Do NOT found the flash device(%s).", part->flash_name);
431 return XF_ERR_INVALID_ARG;
432 }
433
434 xf_ret = flash_dev->ops.read(part->offset + src_offset, dst, size);
435 if (xf_ret != XF_OK) {
436 XF_LOGE(TAG, "Partition read error! "
437 "Flash device(%s) read failed.", part->flash_name);
438 }
439
440 return xf_ret;
441}
442
444 const xf_fal_partition_t *part,
445 size_t dst_offset, const void *src, size_t size)
446{
447 xf_err_t xf_ret = XF_OK;
448 const xf_fal_flash_dev_t *flash_dev = NULL;
449
451 return XF_ERR_INVALID_PORT;
452 }
453 if (!sp_fal()->is_init) {
454 return XF_ERR_UNINIT;
455 }
456 if (!part || !src || !size) {
457 return XF_ERR_INVALID_ARG;
458 }
459 if (dst_offset + size > part->len) {
460 XF_LOGE(TAG, "Partition write error! "
461 "Partition(%s) address(0x%08x) out of bound(0x%08x).",
462 part->name, (int)(dst_offset + size), (int)part->len);
463 return XF_ERR_INVALID_ARG;
464 }
465
466 flash_dev = xf_fal_flash_device_find_by_part(part);
467 if (flash_dev == NULL) {
468 XF_LOGE(TAG, "Partition write error! "
469 "Do NOT found the flash device(%s).", part->flash_name);
470 return XF_ERR_INVALID_ARG;
471 }
472
473 xf_ret = flash_dev->ops.write(part->offset + dst_offset, src, size);
474 if (xf_ret != XF_OK) {
475 XF_LOGE(TAG, "Partition write error! "
476 "Flash device(%s) write failed.", part->flash_name);
477 }
478
479 return xf_ret;
480}
481
483 const xf_fal_partition_t *part, size_t offset, size_t size)
484{
485 xf_err_t xf_ret = XF_OK;
486 const xf_fal_flash_dev_t *flash_dev = NULL;
487
489 return XF_ERR_INVALID_PORT;
490 }
491 if (!sp_fal()->is_init) {
492 return XF_ERR_UNINIT;
493 }
494 if (!part || !size) {
495 return XF_ERR_INVALID_ARG;
496 }
497 if (offset + size > part->len) {
498 XF_LOGE(TAG, "Partition write error! "
499 "Partition(%s) address(0x%08x) out of bound(0x%08x).",
500 part->name, (int)(offset + size), (int)part->len);
501 return XF_ERR_INVALID_ARG;
502 }
503
504 flash_dev = xf_fal_flash_device_find_by_part(part);
505 if (flash_dev == NULL) {
506 XF_LOGE(TAG, "Partition write error! "
507 "Do NOT found the flash device(%s).", part->flash_name);
508 return XF_ERR_INVALID_ARG;
509 }
510
511 xf_ret = flash_dev->ops.erase(part->offset + offset, size);
512 if (xf_ret != XF_OK) {
513 XF_LOGE(TAG, "Partition write error! "
514 "Flash device(%s) write failed.", part->flash_name);
515 }
516
517 return xf_ret;
518}
519
521{
522 return xf_fal_partition_erase(part, 0, part->len);
523}
524
526{
527 const xf_fal_partition_t *p_table;
528 size_t table_len;
529 const xf_fal_partition_t *part;
530 size_t i;
531 size_t j;
532 char *item1 = "name";
533 char *item2 = "flash_dev";
534 size_t part_name_max = strlen(item1);
535 size_t flash_dev_name_max = strlen(item2);
536 size_t len_max;
537
538 for (i = 0; i < XF_FAL_PARTITION_TABLE_NUM; i++) {
539 p_table = sp_fal()->partition_table[i];
540 table_len = sp_fal()->partition_table_len[i];
541 if ((NULL == p_table) || (0 == table_len)) {
542 continue;
543 }
544 for (j = 0; j < table_len; j++) {
545 part = &p_table[j];
546 len_max = xf_strlen(part->name);
547 if (part_name_max < len_max) {
548 part_name_max = len_max;
549 }
550 len_max = xf_strlen(part->flash_name);
551 if (flash_dev_name_max < len_max) {
552 flash_dev_name_max = len_max;
553 }
554 }
555 }
556
557 XF_LOGI(TAG, "==================== FAL partition table ===================");
558 XF_LOGI(TAG, "| %-*.*s | %-*.*s | offset | length |",
559 (int)part_name_max, XF_FAL_DEV_NAME_MAX, item1,
560 (int)flash_dev_name_max, XF_FAL_DEV_NAME_MAX, item2);
561 XF_LOGI(TAG, "-------------------------------------------------------------");
562 for (i = 0; i < XF_FAL_PARTITION_TABLE_NUM; i++) {
563 p_table = sp_fal()->partition_table[i];
564 table_len = sp_fal()->partition_table_len[i];
565 if ((NULL == p_table) || (0 == table_len)) {
566 continue;
567 }
568 for (j = 0; j < table_len; j++) {
569 part = &p_table[j];
570 XF_LOGI(TAG, "| %-*.*s | %-*.*s | 0x%08lx | 0x%08lx |",
571 (int)part_name_max, XF_FAL_DEV_NAME_MAX, part->name,
572 (int)flash_dev_name_max, XF_FAL_DEV_NAME_MAX, part->flash_name,
573 part->offset, part->len);
574 }
575 }
576 XF_LOGI(TAG, "=============================================================");
577}
578
580{
581 xf_err_t xf_ret = XF_OK;
582 const xf_fal_flash_dev_t *flash_dev;
583 const xf_fal_partition_t *p_table;
584 const xf_fal_partition_t *part;
585 size_t table_len;
586 size_t i;
587 size_t j;
588
590 sp_fal()->cached_num = 0;
591 for (i = 0; i < XF_FAL_PARTITION_TABLE_NUM; i++) {
592 p_table = sp_fal()->partition_table[i];
593 table_len = sp_fal()->partition_table_len[i];
594 if ((NULL == p_table) || (0 == table_len)) {
595 continue;
596 }
597 for (j = 0; j < table_len; j++) {
598 part = &p_table[j];
599 flash_dev = xf_fal_flash_device_find(part->flash_name);
600 if (flash_dev == NULL) {
601 XF_LOGD(TAG, "Warning: Do NOT found the flash device(%s).",
602 part->flash_name);
603 continue;
604 }
605
606 if (part->offset >= (size_t)flash_dev->len) {
607 XF_LOGE(TAG, "Initialize failed! "
608 "Partition(%s) offset address(%ld) out of flash bound(<%d).",
609 part->name, part->offset, (int)flash_dev->len);;
610 xf_ret = XF_FAIL;
611 goto l_unlock_ret;
612 }
613
614 if (sp_fal()->cached_num >= XF_FAL_CACHE_NUM) {
615 XF_LOGW(TAG, "The cache is too small.");
616 continue;
617 }
618
619 sp_fal()->cache[sp_fal()->cached_num].flash_dev = flash_dev;
620 sp_fal()->cache[sp_fal()->cached_num].partition = part;
621 ++sp_fal()->cached_num;
622 }
623 }
624
625l_unlock_ret:;
627
628 return xf_ret;
629}
630
631/* ==================== [Static Functions] ================================== */
xf_err_t xf_fal_partition_read(const xf_fal_partition_t *part, size_t src_offset, void *dst, size_t size)
从指定分区读取数据。
Definition xf_fal.c:404
xf_err_t xf_fal_register_flash_device(const xf_fal_flash_dev_t *p_dev)
注册一个 flash 设备到 xf_fal 中。
Definition xf_fal.c:95
xf_err_t xf_fal_deinit(void)
反初始化 FAL.
Definition xf_fal.c:293
xf_err_t xf_fal_partition_erase(const xf_fal_partition_t *part, size_t offset, size_t size)
擦除指定分区数据。
Definition xf_fal.c:482
xf_err_t xf_fal_partition_erase_all(const xf_fal_partition_t *part)
擦除指定分区所有数据。
Definition xf_fal.c:520
bool xf_fal_check_register_state(void)
检查 xf_fal 注册状态。
Definition xf_fal.c:246
xf_err_t xf_fal_init(void)
初始化 FAL.
Definition xf_fal.c:259
xf_err_t xf_fal_check_and_update_cache(void)
更新分区表中的分区与关联的 flash 设备的缓存。
Definition xf_fal.c:579
xf_err_t xf_fal_unregister_partition_table(const xf_fal_partition_t *p_table)
从 xf_fal 中注销一个分区表。
Definition xf_fal.c:213
const xf_fal_ctx_t * xf_fal_get_ctx(void)
获取 xf_fal 上下文。
Definition xf_fal.c:254
xf_err_t xf_fal_partition_write(const xf_fal_partition_t *part, size_t dst_offset, const void *src, size_t size)
将数据写入指定分区。
Definition xf_fal.c:443
const xf_fal_flash_dev_t * xf_fal_flash_device_find(const char *name)
根据 flash 名称查找 flash 设备。
Definition xf_fal.c:318
void xf_fal_show_part_table(void)
打印分区表信息。
Definition xf_fal.c:525
xf_err_t xf_fal_register_partition_table(const xf_fal_partition_t *p_table, size_t table_len)
注册一个分区表到 xf_fal 中。
Definition xf_fal.c:139
const xf_fal_partition_t * xf_fal_partition_find(const char *name)
根据分区名称查找分区句柄。
Definition xf_fal.c:370
xf_err_t xf_fal_unregister_flash_device(const xf_fal_flash_dev_t *p_dev)
从 xf_fal 中注销一个 flash 设备。
Definition xf_fal.c:180
const xf_fal_flash_dev_t * xf_fal_flash_device_find_by_part(const xf_fal_partition_t *part)
通过给定分区查找 flash 设备。
Definition xf_fal.c:342
int32_t xf_err_t
整形错误类型。 错误码具体值见 xf_err_code_t.
Definition xf_err.h:69
@ XF_ERR_INVALID_PORT
Definition xf_err.h:49
@ XF_FAIL
Definition xf_err.h:42
@ XF_ERR_INVALID_ARG
Definition xf_err.h:46
@ XF_ERR_INITED
Definition xf_err.h:55
@ XF_OK
Definition xf_err.h:43
@ XF_ERR_BUSY
Definition xf_err.h:52
@ XF_ERR_RESOURCE
Definition xf_err.h:57
@ XF_ERR_NOT_FOUND
Definition xf_err.h:50
@ XF_ERR_UNINIT
Definition xf_err.h:54
#define xf_strlen(str)
Definition xf_string.h:48
#define xf_strncmp(dest, src, n)
Definition xf_string.h:47
xf_fal 对象上下文结构体。
flash 设备结构体。
xf_fal_flash_ops_t ops
flash 操作集,见 xf_fal_flash_ops_t .
size_t sector_size
扇区大小。扇区大小是最小擦除大小。单位: byte.
xf_err_t(* write)(size_t dst_offset, const void *src, size_t size)
写数据到 flash 的指定偏移地址。
xf_err_t(* read)(size_t src_offset, void *dst, size_t size)
从 flash 的指定偏移地址读取数据。
xf_err_t(* deinit)(void)
反初始化 flash 设备。
xf_err_t(* init)(void)
初始化 flash 设备。
xf_err_t(* erase)(size_t offset, size_t size)
擦除 flash 的指定偏移地址指定长度。
flash 分区结构体。
size_t len
flash 设备上的该分区长度。
size_t offset
flash 设备上的该分区偏移地址。
Flash 抽象层 FAL (Flash Abstraction Layer).
static xf_fal_ctx_t s_fal_ctx
Definition xf_fal.c:27
static xf_fal_ctx_t * sp_fal_ctx
Definition xf_fal.c:28
#define XF_FAL_CTX_TRYLOCK__RETURN_ON_FAILURE(_ret)
Definition xf_fal.c:48
#define sp_fal()
Definition xf_fal.c:29
#define XF_FAL_CTX_MUTEX_TRY_INIT()
Definition xf_fal.c:33
#define XF_FAL_CTX_UNLOCK()
Definition xf_fal.c:71
#define TAG
Definition xf_fal.c:19
#define XF_FAL_CACHE_NUM
#define XF_FAL_FLASH_DEVICE_NUM
#define XF_FAL_PARTITION_TABLE_NUM
#define XF_FAL_DEV_NAME_MAX
#define XF_LOGI(tag, format,...)
#define XF_LOGE(tag, format,...)
#define XF_LOGW(tag, format,...)
#define XF_LOGD(tag, format,...)