123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #include "hal_flash.h"
- /*********************************************************************
- *DEFINITION
- */
- typedef struct zone_s
- {
- uint8_t page_num;
- uint32_t zone_start_addr;
- }zone_t;
- /*********************************************************************
- * LOCAL VARIABLES
- */
- static int16_t PageCount = FLASH_PAGE_NUM; //可用页数
- static uint32_t zone_used_index = 0; //zone结构体下标
- static zone_t zone[FLASH_PAGE_NUM]; //zone结构体
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- /**
- @brief 通过区域地址获取区域索引
- @param zone_addr[in] - 分配的区域地址
- @param zone_index[out] - 返回分配的区域索引
- @return 错误代码
- */
- static uint32_t Zone_GetIndex(uint32_t zone_addr, uint32_t *zone_index)
- {
- for(int i=0; i < zone_used_index; i++)
- {
- if( zone[i].zone_start_addr <= zone_addr && (zone[i].zone_start_addr + zone[i].page_num * FLASH_PAGE_SIZE) > zone_addr ){
- if(zone_index != NULL)*zone_index = i;
- return ZONE_OP_SUCCESS;
- }
- }
- return ZONE_ERROR_NO_INDEX;
- }
- /*********************************************************************
- * PUBLIC FUNCTIONS
- */
- /**
- @brief 初始化一个区域
- @param page_size[in] - 该区域使用了几个页
- @param zone_start_addr[out] - 返回分配的区域首地址
- @return 错误代码
- */
- uint32_t Zone_Alloca(uint8_t page_num, uint32_t *zone_start_addr)
- {
- if(page_num <= 0) return ZONE_ERROR_PARAM_PAGE_NUM;
-
- if(PageCount - page_num < 0)return ZONE_ERROR_NO_PAGE;
-
- zone[zone_used_index].page_num = page_num;
- if(zone_used_index == 0)zone[zone_used_index].zone_start_addr = FLASH_ZONE_ADDR_1;
- else zone[zone_used_index].zone_start_addr = zone[zone_used_index-1].zone_start_addr + FLASH_PAGE_SIZE * zone[zone_used_index-1].page_num;
-
- if(zone_start_addr != NULL)*zone_start_addr = zone[zone_used_index].zone_start_addr;
-
- PageCount -= page_num;
- zone_used_index++;
-
- return ZONE_OP_SUCCESS;
- }
- /**
- @brief 读取一个区域中指定位置的数据
- @param destination_addr[in] - 读取区域的地址
- @param pData[in] - 指向存储的buff
- @param dataLen[in] - 读取的长度,单位字节
- @return 错误代码
- */
- uint32_t Zone_Read(uint32_t destination_addr, uint32_t *pData, uint32_t dataLen)
- {
- uint32_t err_code; //错误代码
- uint32_t zone_index; //是否有相对应的区域索引
- uint32_t next_zone_addr; //下个区域的首地址
-
- //验证是否申请了对应区域
- err_code = Zone_GetIndex(destination_addr, &zone_index);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
-
- if(pData != NULL && dataLen != 0)
- {
- next_zone_addr = zone[zone_index].zone_start_addr + zone[zone_index].page_num * FLASH_PAGE_SIZE;
- //不能读到下一个区域
- if((destination_addr + dataLen) > next_zone_addr)return ZONE_ERROR_READ_FAIL;
- //读取
- err_code = Read_N_Byte_flash(destination_addr, pData, dataLen);
- if(err_code != FLASH_OP_SUCCESS)return ZONE_ERROR_READ_FAIL;
- }
-
- return ZONE_OP_SUCCESS;
-
- }
- /**
- @brief 往一个区域指定位置写入数据(支持跨页写)
- @param destination_addr[in] - 写入区域的地址
- @param pData[in] - 指向存储的buff
- @param dataLen[in] - 写入的长度
- @return 错误代码
- */
- uint32_t Zone_Write(uint32_t destination_addr, uint32_t *pData, uint32_t dataLen)
- {
- uint32_t err_code; //错误代码
- uint32_t zone_index; //是否有相对应的区域索引
- uint32_t next_zone_addr; //下个区域的首地址
- //验证是否申请了对应区域
- err_code = Zone_GetIndex(destination_addr, &zone_index);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
-
- if(pData != NULL && dataLen != 0)
- {
- next_zone_addr = zone[zone_index].zone_start_addr + zone[zone_index].page_num * FLASH_PAGE_SIZE;
- //不能写到下一个区域
- if((destination_addr + dataLen) > next_zone_addr)return ZONE_ERROR_WRITE_FAIL;
- //写入
- err_code = Write_N_4Byte_flash(destination_addr, pData, dataLen);
- if(err_code != FLASH_OP_SUCCESS)return ZONE_ERROR_WRITE_FAIL;
- }
- return ZONE_OP_SUCCESS;
- }
- /**
- @brief 擦除一个区域
- @param zone_start_addr[in] - 分配的区域首地址
- @return 错误代码
- */
- uint32_t Zone_Erase(uint32_t zone_start_addr)
- {
- uint32_t err_code; //错误代码
- uint32_t zone_index; //是否有相对应的区域索引
- uint16_t PageNum;
-
- //验证是否申请了对应区域
- err_code = Zone_GetIndex(zone_start_addr, &zone_index);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- //一页一页擦除
- for(uint8_t i = 0; i < zone[zone_index].page_num; i++)
- {
- //获取输入地址对应的页号
- err_code = GetPageNum(zone[zone_index].zone_start_addr + i * FLASH_PAGE_SIZE, &PageNum);
- if(err_code != FLASH_OP_SUCCESS)return ZONE_ERROR_ERASE_FAIL;
- //根据页号擦除一整页
- err_code = Erase_OnePage(PageNum);
- if(err_code != FLASH_OP_SUCCESS)return ZONE_ERROR_ERASE_FAIL;
- }
- return ZONE_OP_SUCCESS;
- }
- /**
- @brief 获取一个区域的总字节大小
- @param zone_start_addr[in] - 分配的区域首地址
- @param bytes[out] - 返回区域的字节大小
- @return 错误代码
- */
- uint32_t Zone_GetByteSize(uint32_t zone_start_addr, uint32_t *bytes)
- {
- uint32_t err_code; //错误代码
- uint32_t zone_index; //是否有相对应的区域索引
-
- //验证是否申请了对应区域
- err_code = Zone_GetIndex(zone_start_addr, &zone_index);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
-
- if(bytes != NULL)*bytes = zone[zone_index].page_num * FLASH_PAGE_SIZE;
-
- return ZONE_OP_SUCCESS;
- }
|