diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2b1dac24003a8db25cc671b82ee93dfc9bd6b790 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# DataStructSave + +#### 介绍 +基于flash设计的用于数据参数存储库. + diff --git a/demo/drv_data_struct_save_demo.c b/demo/drv_data_struct_save_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..f4858df6901d4c7cb35252046fe396808872f0c7 --- /dev/null +++ b/demo/drv_data_struct_save_demo.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2024, ˮԴ Water Source (WoodData). + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-06 WoodData the first version + */ + +#include "string.h" +#include "drv_data_struct_save.h" +/* debug print function. Must be implement by user. */ +#ifdef MOUDLE_DATA_SAVE_DEBUG +#define LOG_TAG "SAVE" +#include "print_log.h" +#else +#define LOG_ASSERT(f) +#define LOG_A(...) +#define LOG_E(...) +#define LOG_W(...) +#define LOG_I(...) +#define LOG_D(...) +#endif + +#include "sfud.h" +extern uint8_t sfud_demo_test_buf[]; + +typedef struct test_data_t +{ + uint32_t timetick; + uint32_t count; + uint32_t pluse; + +}test_data_t; + +test_data_t test_data; +data_manage_save_t test_data_dm1; + + +#if UART_SHELL == NR_MICRO_SHELL +#include "nr_micro_shell.h" +void data_save_demo(char argc, char *argv) +{ + int i; + data_struct_init(&test_data_dm1,"DataSave",0,2,4096); + data_struct_bind(&test_data_dm1,&test_data,sizeof(test_data),1,NULL); + printf("timetick = 0x%0X\r\n",test_data.timetick); + printf("count = 0x%0X\r\n",test_data.count); + printf("pluse = 0x%0X\r\n\r\n",test_data.pluse); + for(i=0;i<10;i++) + { + test_data.timetick = get_system_us(); + test_data.count ++; + test_data.pluse += 100; + data_struct_write(&test_data_dm1); + printf("timetick = %u\r\n",test_data.timetick); + printf("count = %u\r\n",test_data.count); + printf("pluse = %u\r\n",test_data.pluse); + delay_ms(500); + } + delay_ms(1000); + data_struct_read(&test_data_dm1); + printf("timetick = 0x%0X\r\n",test_data.timetick); + printf("count = 0x%0X\r\n",test_data.count); + printf("pluse = 0x%0X\r\n\r\n",test_data.pluse); + + + sfud_err result = SFUD_SUCCESS; + const sfud_flash *flash = sfud_get_device_table() + 0; + /* read test */ + result = sfud_read(flash, 2*1024*1024, 1024, sfud_demo_test_buf); + if (result == SFUD_SUCCESS) + { + printf("Read the %s flash data success. Start from 0x%08X, size is %u. The data is:\r\n", flash->name, 2*1024*1024 , 1024); + printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"); + for (i = 0; i < 1024; i++) { + if (i % 16 == 0) { + printf("[%08X] ", 2*1024*1024 + i); + } + printf("%02X ", sfud_demo_test_buf[i]); + if (((i + 1) % 16 == 0) || i == 2*1024*1024 - 1) { + printf("\r\n"); + } + } + printf("\r\n"); + } else + { + printf("Read the %s flash data failed.\r\n", flash->name); + } +} +NR_SHELL_CMD_EXPORT(save_data, data_save_demo, "Test save data struct."); +#endif + + +////////////////////////////////////////////////////////////////////////////////////////////////// +// +typedef struct test_history_data_t +{ + uint32_t timetick; + int temp; + int humi; + unsigned int ps; + float als; +}test_history_data_t; + +test_history_data_t test_history; +data_manage_save_t test_history_dm; + +#if UART_SHELL == NR_MICRO_SHELL +#include "nr_micro_shell.h" +void data_record_demo(char argc, char *argv) +{ + int i; + data_struct_init(&test_history_dm,"DataSave",2*4096 , 2, 4096); + data_struct_bind(&test_history_dm,&test_history,sizeof(test_history),0,NULL); + + printf("timetick = %u\r\n", test_history.timetick); + printf("t=%d \t rh=%d.\r\n", test_history.temp,test_history.humi); + printf("ps=%u \t l=%0.2f\r\n\r\n", test_history.ps,test_history.als); + for(i=0;i<10;i++) + { + test_history.timetick = get_system_us(); + SHTC3_GetMode1_TempRH(&test_history.temp, &test_history.humi); + delay_ms(10); + RPR0521RS_get_psalsval(&test_history.ps, &test_history.als); + data_struct_write(&test_history_dm); + + printf("timetick = %u\r\n", test_history.timetick); + printf("t=%d \t rh=%d.\r\n", test_history.temp,test_history.humi); + printf("ps=%u \t l=%0.2f\r\n\r\n", test_history.ps,test_history.als); + delay_ms(1000); + } + delay_ms(2000); + data_struct_read(&test_history_dm); + printf("timetick = %u\r\n", test_history.timetick); + printf("t=%d \t rh=%d.\r\n", test_history.temp,test_history.humi); + printf("ps=%u \t l=%0.2f\r\n\r\n", test_history.ps,test_history.als); + + sfud_err result = SFUD_SUCCESS; + const sfud_flash *flash = sfud_get_device_table() + 0; + /* read test */ + result = sfud_read(flash, 2*1024*1024 + 2*4096, 1024, sfud_demo_test_buf); + if (result == SFUD_SUCCESS) + { + printf("Read the %s flash data success. Start from 0x%08X, size is %u. The data is:\r\n", flash->name, 2*1024*1024 + 2*4096 , 1024); + printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"); + for (i = 0; i < 1024; i++) { + if (i % 16 == 0) { + printf("[%08X] ", 2*1024*1024 + 2*4096 + i); + } + printf("%02X ", sfud_demo_test_buf[i]); + if (((i + 1) % 16 == 0) || (i == (2*1024*1024 + 2*4096 - 1))) { + printf("\r\n"); + } + } + printf("\r\n"); + } else + { + printf("Read the %s flash data failed.\r\n", flash->name); + } +} +NR_SHELL_CMD_EXPORT(record_d, data_record_demo, "Test record data struct."); + + +void data_record_history(char argc, char *argv) +{ + test_history_data_t history; + + if(data_struct_read_history(&test_history_dm, &history)) + { + printf("error!\r\n"); + } + + printf("timetick = %u\r\n", history.timetick); + printf("t=%d \t rh=%d.\r\n", history.temp,history.humi); + printf("ps=%u \t l=%0.2f\r\n\r\n", history.ps,history.als); +} +NR_SHELL_CMD_EXPORT(record_h, data_record_history, "Read record history data struct."); +#endif + diff --git a/src/drv_data_struct_save.c b/src/drv_data_struct_save.c new file mode 100644 index 0000000000000000000000000000000000000000..1b85bed5cab5f7ed549808a3891a204f3ff3efce --- /dev/null +++ b/src/drv_data_struct_save.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2024, ˮԴ Water Source (WoodData). + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-06 WoodData the first version + */ + +#include "string.h" +#include "drv_data_struct_save.h" +/* debug print function. Must be implement by user. */ +#ifdef MOUDLE_DATA_SAVE_DEBUG +#define LOG_TAG "SAVE" +#include "print_log.h" +#else +#define LOG_ASSERT(f) +#define LOG_A(...) +#define LOG_E(...) +#define LOG_W(...) +#define LOG_I(...) +#define LOG_D(...) +#endif + +extern uint32_t ds_flash_init(data_manage_save_t * dm); +extern uint32_t ds_flash_write_port(data_manage_save_t * dm, uint32_t addr, uint8_t *buff, uint32_t len); +extern uint32_t ds_flash_read_port(data_manage_save_t * dm, uint32_t addr, uint8_t *buff, uint32_t len); +extern uint32_t ds_flash_erase_port(data_manage_save_t * dm, uint32_t addr, uint8_t *buff, uint32_t len); + +static int ds_check_data_is_null(data_manage_save_t * dm,uint8_t * buff,uint32_t len) +{ + int i; + for(i=0;ipart_erase_data) return (i+1); + } + return 0; +} + +int data_struct_init(data_manage_save_t * dm, char *name, uint32_t addr_start,uint16_t block_num, uint16_t block_size) +{ + LOG_ASSERT(dm); + LOG_ASSERT(block_num ); + LOG_ASSERT(block_size ); + + if((block_num < 2)||(block_size == 0)) + { + LOG_E("block_num must be at least 2!block_size must be more than 0!"); + return -1; + } + if(addr_start & (block_size - 1)) //address must be multiple block size number + { + LOG_E("addr_start must be multiple block size!"); + return -1; + } + + dm->part_name = name; + dm->part_addr_start = addr_start; + dm->part_block_num = block_num; + dm->part_block_size = block_size; + dm->part_erase_data = DATA_ERASE_VALUE; //erase data must be 0xff or 0x00. + dm->part_use_bind = 0; + + dm->cur_page_addr = 0; + dm->cur_read_page_i = 0xffff; + dm->cur_read_block_i = 0xffff; + + ds_flash_init(dm); + dm->part_ok = 1; + return 0; +} + +int data_struct_bind(data_manage_save_t * dm, void * data_struct, uint16_t data_size, uint16_t data_mode, int (* data_struct_check)(void * data_struct)) +{ + uint16_t temp,i; + LOG_ASSERT(dm); + LOG_ASSERT(data_struct); + LOG_ASSERT(data_size); + + //check data_size + if(data_size > 0x7fff) + { + LOG_E("data_size is too big!"); + return -1; + } + if(dm->part_ok == 0) + { + LOG_E("You must init data_manage_save_t part infomation!"); + return -1; + } + dm->data_struct = data_struct; + dm->data_struct_size = data_size; + dm->data_page_size = (((data_size + 7) >>3 ) << 3); //data page = N*8 + if(dm->data_page_size > dm->part_block_size) + { + LOG_E("Not support data struct size big than block size!"); + return -1; + } + dm->data_page_num = dm->part_block_size / dm->data_page_size; + if(dm->data_page_num == 0) + { + LOG_E("flash part size too small!"); + return -1; + } + dm->data_struct_check = data_struct_check; + if(data_struct_check == NULL) + { + LOG_W("Data struct check function is NULL!"); + } + dm->data_auto_erase_old_block = (data_mode & 0x0001) ? 1:0; + dm->part_use_bind = 1; + return data_struct_read(dm); +} + + +int data_struct_read(data_manage_save_t * dm) +{ + uint32_t block_i,page_i; + uint32_t _min,_max; + uint32_t _addr; + + LOG_ASSERT(dm); + LOG_ASSERT(dm->data_struct); + + if((dm->part_ok == 0) || (dm->part_use_bind == 0)) + { + LOG_E("Flash part data struct not ready!"); + return -1; + } + //Binary search the right data struct in all block + if(dm->data_auto_erase_old_block == 0) + { + _min = 0; + _max = dm->part_block_num; + while(1) + { + block_i = (_min + _max) >> 1; + if(ds_flash_read_port(dm, block_i * dm->part_block_size,(uint8_t *)dm->data_struct,dm->data_struct_size)==0) + { + LOG_E("Flash read data error!"); + return -2; + } + if(ds_check_data_is_null(dm, (uint8_t *)dm->data_struct, dm->data_struct_size) == 0) + { + _max = block_i;//null + }else + { + _min = block_i;//not null + } + if(_max == (_min + 1)) + { + block_i = _min; + LOG_I("datablock=%u.",block_i); + break; + } + } + }else + { + for(block_i = 0;block_ipart_block_num;block_i++) + { + if(ds_flash_read_port(dm, block_i * dm->part_block_size,(uint8_t *)dm->data_struct,dm->data_struct_size) == 0) + { + LOG_E("Flash read data error!"); + return -2; + } + if(ds_check_data_is_null(dm, (uint8_t *)dm->data_struct, dm->data_struct_size) ) + { + //not null + break; + } + } + if(block_i == dm->part_block_num) + { + block_i = 0; + } + LOG_I("DataBlock=%u.",block_i); + } + // Search the right data struct in block. + for(page_i = (dm->data_page_num - 1);page_i > 0; page_i--) + { + if(ds_flash_read_port(dm, block_i * dm->part_block_size + page_i * dm->data_page_size,(uint8_t *)dm->data_struct,dm->data_struct_size) == 0) + { + LOG_E("Flash read data error!"); + return -2; + } + if(ds_check_data_is_null(dm, (uint8_t *)dm->data_struct, dm->data_struct_size)) + { + //not null + break; + } + } + if(page_i == 0) + { + if(ds_flash_read_port(dm, block_i * dm->part_block_size,(uint8_t *)dm->data_struct,dm->data_struct_size) == 0) + { + LOG_E("Flash read data error!"); + return -2; + } + _addr = block_i * dm->part_block_size; + if(ds_check_data_is_null(dm, (uint8_t *)dm->data_struct, dm->data_struct_size)) + { + dm->cur_page_addr = _addr + dm->data_page_size;//not null + }else + { + dm->cur_page_addr = _addr; + dm->cur_read_page_i = 0xffff; + dm->cur_read_block_i = 0xffff; + LOG_W("Flash data is none!"); + return 1; + } + }else + { + _addr = block_i * dm->part_block_size + page_i * dm->data_page_size; + dm->cur_page_addr = _addr + dm->data_page_size; + if(dm->cur_page_addr > ((block_i + 1) * dm->part_block_size)) + { + dm->cur_page_addr = (block_i + 1) * dm->part_block_size; + } + } + if(dm->cur_page_addr >= (dm->part_block_num * dm->part_block_size)) + { + dm->cur_page_addr = 0; + } + dm->cur_read_page_i = page_i; + dm->cur_read_block_i = block_i; + if(dm->cur_page_addr != _addr) + { + if(dm->cur_read_page_i) + { + dm->cur_read_page_i--; + }else + { + dm->cur_read_page_i = dm->data_page_num - 1; + if(dm->cur_read_block_i) dm->cur_read_block_i--; + else dm->cur_read_block_i = dm->part_block_num -1; + } + //Search history data and check data.Find the latest correct data. + if(ds_check_data_is_null(dm, (uint8_t *)dm->data_struct, dm->data_struct_size) == 0) + { + LOG_E("Data struct is not vaild!"); + return -4;//null + } + if((dm->data_struct_check != NULL) && (dm->data_struct_check(dm->data_struct))) + { + LOG_W("Save data struct check error! addr=0x%0X",_addr); + return -5; + }else + { + LOG_I("Save data struct not check valid."); + } + if((dm->cur_page_addr % dm->part_block_size) == 0) + { + if(ds_flash_erase_port(dm,dm->cur_page_addr,NULL,dm->part_block_size) == 0) + { + LOG_E("Flash erase error!"); + return -3; + } + } + } + return 0; +} + + +int data_struct_write(data_manage_save_t * dm) +{ + uint32_t _addr; + LOG_ASSERT(dm); + LOG_ASSERT(dm->data_struct); + if((dm->part_ok == 0) || (dm->part_use_bind == 0)) + { + LOG_E("Flash part data struct not ready!"); + return -1; + } + if(ds_flash_write_port(dm,dm->cur_page_addr,(uint8_t *)dm->data_struct,dm->data_struct_size) == 0) + { + LOG_E("Flash write error!"); + return -2; + } + _addr = dm->cur_page_addr; + dm->cur_page_addr += dm->data_page_size; + if((_addr / dm->part_block_size) < (dm->cur_page_addr/dm->part_block_size)) + { + dm->cur_page_addr = (dm->cur_page_addr / dm->part_block_size) * dm->part_block_size; + } + if(dm->cur_page_addr >= (dm->part_block_num * dm->part_block_size)) + { + dm->cur_page_addr = 0; + } + + if(dm->data_auto_erase_old_block == 0) + { + if((dm->cur_page_addr % dm->part_block_size) == 0) + { + if(ds_flash_erase_port(dm,dm->cur_page_addr,NULL,dm->part_block_size) == 0) + { + LOG_E("Flash erase error!"); + return -3; + } + } + }else + { + if((_addr % dm->part_block_size) == 0) + { + if(_addr == 0) _addr = dm->part_block_size * (dm->part_block_num - 1); + else _addr -= dm->part_block_size; + if(ds_flash_erase_port(dm,_addr,NULL,dm->part_block_size) == 0) + { + LOG_E("Flash erase error!"); + return -3; + } + } + } + return 0; +} + +int data_struct_erase(data_manage_save_t * dm) +{ + uint32_t _addr; + LOG_ASSERT(dm); + if((dm->part_ok == 0) || (dm->part_use_bind == 0)) + { + LOG_E("Flash part data struct not ready!"); + return -1; + } + for(_addr = 0; _addr < (dm->part_block_size * dm->part_block_num); _addr += dm->part_block_size) + { + if(ds_flash_erase_port(dm,_addr,NULL,dm->part_block_size) == 0) + { + LOG_E("Flash erase error!"); + return -3; + } + } + return data_struct_read(dm); +} + + +int data_struct_read_history(data_manage_save_t * dm,void * data_struct) +{ + uint32_t _addr; + + LOG_ASSERT(dm); + LOG_ASSERT(data_struct); + + if((dm->part_ok == 0) || (dm->part_use_bind == 0)) + { + LOG_E("Flash part data struct not ready!"); + return -1; + } + if((dm->cur_read_page_i == 0xffff) || (dm->cur_read_block_i == 0xffff)) + { + LOG_E("History data is null"); + return -2; + } + + //Search history data and check data.Find the latest correct data. + _addr = dm->cur_read_block_i * dm->part_block_size + dm->cur_read_page_i * dm->data_page_size; + if(ds_flash_read_port(dm, _addr,(uint8_t *)data_struct,dm->data_struct_size) == 0) + { + LOG_E("Flash read data error!"); + return -2; + } + + if(dm->cur_read_page_i) + { + dm->cur_read_page_i--; + }else + { + dm->cur_read_page_i = dm->data_page_num - 1; + if(dm->cur_read_block_i) dm->cur_read_block_i--; + else dm->cur_read_block_i = dm->part_block_num -1; + } + + if(ds_check_data_is_null(dm, (uint8_t *)data_struct, dm->data_struct_size) == 0) + { + LOG_E("Data struct is not vaild!"); + return -4;//null + } + + if((dm->data_struct_check != NULL) && (dm->data_struct_check(dm->data_struct))) + { + LOG_W("Save data struct check error! addr=0x%0X",_addr); + return -5; + } + + return 0; +} + + + + + diff --git a/src/drv_data_struct_save.h b/src/drv_data_struct_save.h new file mode 100644 index 0000000000000000000000000000000000000000..d7c726fc77cba9b6b4a51177ad863c44fba06ee3 --- /dev/null +++ b/src/drv_data_struct_save.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024, ˮԴ Water Source (WoodData). + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-06 WoodData the first version + */ + + /* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DRV_DATA_STRUCT_H__ +#define __DRV_DATA_STRUCT_H__ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "stdint.h" +#include "drv_data_struct_save_cfg.h" + +#ifndef DATA_ERASE_VALUE +#define DATA_ERASE_VALUE 0xFF +#endif + + +typedef struct +{ + //Falsh name and size to save data struct + char * part_name; //Flash save region name + uint32_t part_addr_start; //Save region start address. + uint16_t part_block_num; //Save region block number. Total size = block_num * block_size + uint16_t part_block_size; //Save region block size. A block is a erase size. + uint32_t part_erase_data : 8; //must be 0xFF or 0x00. + uint32_t part_ok : 1; // + uint32_t part_use_bind : 1; // + + //Save data struct information + void * data_struct; //Data struct pointer. + uint16_t data_struct_size; //Data struct size + uint16_t data_page_size; //Data struct page sizemust 2^N size4,8,16,32,64,... + uint16_t data_page_num; //Data struct page number. + uint16_t data_auto_erase_old_block : 1; //Data struct flag + + int (* data_struct_check)(void * data_struct); //Check whether the data struct has errors. + + //Current saved information flag + uint32_t cur_page_addr; //Current write to save next data struct address. + uint16_t cur_read_block_i; //Current read history data struct block index. + uint16_t cur_read_page_i; //Current read history data struct page index. + +}data_manage_save_t; + +extern int data_struct_init(data_manage_save_t * dm, char *name, uint32_t addr_start,uint16_t block_num, uint16_t block_size); +extern int data_struct_bind(data_manage_save_t * dm, void * data_struct, uint16_t data_size, uint16_t data_mode, int (* data_struct_check)(void * data_struct)); +extern int data_struct_read(data_manage_save_t * dm); +extern int data_struct_write(data_manage_save_t * dm); +extern int data_struct_erase(data_manage_save_t * dm); +extern int data_struct_read_history(data_manage_save_t * dm,void * data_struct); + +#ifdef __cplusplus +} +#endif +#endif /* __DRV_DATA_STRUCT_H__ */ + + diff --git a/src/drv_data_struct_save_cfg.h b/src/drv_data_struct_save_cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..26ab7618e994f79cf7f01c1608f8a7bdf4315bef --- /dev/null +++ b/src/drv_data_struct_save_cfg.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024, ˮԴ Water Source (WoodData). + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-06 WoodData the first version + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DRV_DATA_STRUCT_CFG_H__ +#define __DRV_DATA_STRUCT_CFG_H__ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MOUDLE_DATA_SAVE_DEBUG +#define DATA_ERASE_VALUE 0xFF + + + +#ifdef __cplusplus +} +#endif +#endif /* __DRV_DATA_STRUCT_CFG_H__ */ + + diff --git a/src/drv_data_struct_save_flash_port.c b/src/drv_data_struct_save_flash_port.c new file mode 100644 index 0000000000000000000000000000000000000000..e87de47fb9af01db1e994db5c84997c645f6c32e --- /dev/null +++ b/src/drv_data_struct_save_flash_port.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024, ˮԴ Water Source (WoodData). + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-06 WoodData the first version + */ + +#include "string.h" +#include "drv_data_struct_save.h" +/* debug print function. Must be implement by user. */ +#ifdef MOUDLE_DATA_SAVE_DEBUG +#define LOG_TAG "SAVE" +#include "print_log.h" +#else +#define LOG_ASSERT(f) +#define LOG_A(...) +#define LOG_E(...) +#define LOG_W(...) +#define LOG_I(...) +#define LOG_D(...) +#endif + +#include "sfud.h" +#include "fal.h" + +static struct fal_partition * pfal = NULL; + +uint32_t ds_flash_init(data_manage_save_t * dm) +{ + LOG_ASSERT(dm); + LOG_ASSERT(dm->part_name); + + if(fal_init_check() == 0) + { + fal_init(); + } + dm->part_block_size = fal_flash_device_find("norflash0")->blk_size; + if(pfal == NULL) + { + pfal = (struct fal_partition * )fal_partition_find(dm->part_name); + } + return 0; +} + + +uint32_t ds_flash_write_port(data_manage_save_t * dm, uint32_t addr, uint8_t *buff, uint32_t len) +{ + LOG_ASSERT(dm); + LOG_ASSERT(buff); + LOG_ASSERT(len); + LOG_ASSERT(dm->part_name); + + if(pfal == NULL) return 0; + if(fal_partition_write(pfal,addr + dm->part_addr_start, buff, len) < 0) return 0; + return len; +} + +uint32_t ds_flash_read_port(data_manage_save_t * dm, uint32_t addr, uint8_t *buff, uint32_t len) +{ + LOG_ASSERT(dm); + LOG_ASSERT(buff); + LOG_ASSERT(len); + LOG_ASSERT(dm->part_name); + + if(pfal == NULL) return 0; + if(fal_partition_read(pfal,addr + dm->part_addr_start, buff, len) < 0) return 0; + return len; +} + +uint32_t ds_flash_erase_port(data_manage_save_t * dm, uint32_t addr, uint8_t *buff, uint32_t len) +{ + LOG_ASSERT(dm); + LOG_ASSERT(buff); + LOG_ASSERT(len); + LOG_ASSERT(dm->part_name); + + if(pfal == NULL) return 0; + if(fal_partition_erase(pfal,addr + dm->part_addr_start, len) < 0) return 0; + return len; +} + diff --git a/src/print_log.h b/src/print_log.h new file mode 100644 index 0000000000000000000000000000000000000000..798ead6596ac30ae54a62da2652e7ecdf479504d --- /dev/null +++ b/src/print_log.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2024, ˮԴ Water Source (WoodData). + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-06 WoodData the first version + */ + +#ifndef __PRINT_LOG_H__ +#define __PRINT_LOG_H__ + +#include +#include + +//config +#define CONFIG_DBG_LEVEL OSAL_DBG_INFO +#define CONFIG_LOG_PRINTF printf + + +//============================================================================= +/* DEBUG level */ +#define OSAL_DBG_NONE 0 +#define OSAL_DBG_ASSERT 1 +#define OSAL_DBG_ERROR 1 +#define OSAL_DBG_WARNING 2 +#define OSAL_DBG_INFO 3 +#define OSAL_DBG_DEBUG 4 + +#ifndef CONFIG_LOG_PRINTF +#define CONFIG_LOG_PRINTF printf +#endif + +#ifndef CONFIG_DBG_LEVEL +#define CONFIG_DBG_LEVEL OSAL_DBG_INFO +#endif + +#ifndef LOG_TAG +#define LOG_TAG "tag" +#endif + +/* + * The color for terminal (foreground) + * BLACK 30 + * RED 31 + * GREEN 32 + * YELLOW 33 + * BLUE 34 + * PURPLE 35 + * CYAN 36 + * WHITE 37 + */ +#ifdef CONFIG_LOG_PRINTF_COLOR_ENABLE +//#define _OSAL_DBG_COLOR(n) CONFIG_LOG_PRINTF("\033[" #n "m") +#define _OSAL_DBG_LOG_HDR(lvl_name, color_n) \ + CONFIG_LOG_PRINTF("\033[" #color_n "m[" lvl_name "/" LOG_TAG "] ") +#define _OSAL_DBG_LOG_X_END CONFIG_LOG_PRINTF("\033[0m \r\n") +#else +//#define _OSAL_DBG_COLOR(n) +#define _OSAL_DBG_LOG_HDR(lvl_name, color_n) \ + CONFIG_LOG_PRINTF("[" lvl_name "/" LOG_TAG "] ") +#define _OSAL_DBG_LOG_X_END CONFIG_LOG_PRINTF("\r\n") +#endif + +#define osal_dbg_log_line(lvl, color_n, fmt, ...) \ + do { \ + _OSAL_DBG_LOG_HDR(lvl, color_n); \ + CONFIG_LOG_PRINTF(fmt, ##__VA_ARGS__); \ + _OSAL_DBG_LOG_X_END; \ + } while (0) + +#if (CONFIG_DBG_LEVEL >= OSAL_DBG_DEBUG) +#define LOG_D(fmt, ...) osal_dbg_log_line("D", 0, fmt, ##__VA_ARGS__) +#else +#define LOG_D(...) +#endif + +#if (CONFIG_DBG_LEVEL >= OSAL_DBG_INFO) +#define LOG_I(fmt, ...) osal_dbg_log_line("I", 32, fmt, ##__VA_ARGS__) +#else +#define LOG_I(...) +#endif + +#if (CONFIG_DBG_LEVEL >= OSAL_DBG_WARNING) +#define LOG_W(fmt, ...) osal_dbg_log_line("W", 33, fmt, ##__VA_ARGS__) +#else +#define LOG_W(...) +#endif + +#if (CONFIG_DBG_LEVEL >= OSAL_DBG_ERROR) +#define LOG_E(fmt, ...) osal_dbg_log_line("E", 31, fmt, ##__VA_ARGS__) +#else +#define LOG_E(...) +#endif + +#if (CONFIG_DBG_LEVEL >= OSAL_DBG_ASSERT) +#define LOG_A(fmt, ...) osal_dbg_log_line("A", 31, fmt, ##__VA_ARGS__) +#else +#define LOG_A(...) +#endif + +#define LOG_ASSERT(f) \ + do { \ + if (!(f)){ \ + CONFIG_LOG_PRINTF("(%s) has assert failed at %s:%u.\n", #f, __FILE__,__LINE__); \ + while(1); \ + } \ + } while (0) + +#endif /* __PRINT_LOG_H__ */