#include "app_flash.h" #include "bsp_wdt.h" #include "exception.h" #include "system.h" /************************************* *DEFINITION */ #define FLASH_HEAD 0xAA5555AA #define FLASH_TAIL_H 0xA5 //高位字节不能为0,因为结构体强制4字节对齐缘故,会导致解析错误。 #define FLASH_TAIL_L 0x55 //低字节随意,最好是0101组合 #define FLASH_ADDR_INFO_PAGENUM 1 #define FLASH_ADDR_STEP_PAGENUM 2 #define FLASH_ADDR_BACKUP_PAGENUM 1 #define MaxLength(a,b) a>b?a:b /********************************************************************* * LOCAL VARIABLES */ static uint32_t info_zone; static uint32_t step_zone; static uint32_t backup_zone; Flash_t mFlash={0}; FlashBackup_t mBackup; /********************************************************************* * LOCAL FUCTIONS */ /** @brief crc16校验码 @param crc - [in] 默认0 @param buf - [in] 指向需要校验的数据 @param len - [in] 校验数据的长度 @return 返回crc16校验码 */ static int CalCrc(int crc, const char *buf, int len) { unsigned int byte; unsigned char k; unsigned short ACC,TOPBIT; unsigned short remainder = crc; TOPBIT = 0x8000; for (byte = 0; byte < len; ++byte) { ACC = buf[byte]; remainder ^= (ACC <<8); for (k = 8; k > 0; --k) { if (remainder & TOPBIT) { remainder = (remainder << 1) ^0x8005; } else { remainder = (remainder << 1); } } } remainder=remainder^0x0000; return remainder; } /****************************************************接口****************************************************/ void Flash_Initialize(void) { uint8_t ret = 0; uint32_t* addr_R; uint32_t* BackupHead; Fstorage_FlashInit(); DEBUG_LOG("Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone)); DEBUG_LOG("Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone)); DEBUG_LOG("Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone)); uint32_t sucess = Flash_GetBackup(&mBackup); DEBUG_LOG("Flash_GetBackup (&mBackup):%d\n",sucess); if(mBackup.ErrorStartFlag >= 5){//连续五次重启的情况下,清空所有的flash数据 Flash_DeleteAllInformation(); Flash_DeleteAllStep(); mBackup.ErrorStartFlag =0; if(Flash_SaveBackup() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_FLASH,"save backup fail"); DEBUG_LOG("mBackup.ErrorStartFlag >= 5!!!!!!!!!!!\n"); NVIC_SystemReset(); } else{ mBackup.ErrorStartFlag++; if(Flash_SaveBackup() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_FLASH,"save backup fail"); } addr_R = (uint32_t*)info_zone; DEBUG_LOG("Flash head read(%04X).\n",*addr_R); if((*addr_R)!=FLASH_HEAD){ DEBUG_LOG("Flash first init(%04X),write infomation to flash.\n",*addr_R); memset((uint8_t*)(&mFlash),0,sizeof(Flash_t)); mFlash.head = FLASH_HEAD; mFlash.m_struct_size = sizeof(mFlash); BackupHead = (uint32_t*)backup_zone;//备份区域有数据的话,拷贝备份区域的数据到information if((*BackupHead) == FLASH_HEAD){ uint8_t i =0; for(i=0;i<6;i++){ mFlash.macHost[i] = mBackup.macAddr_L[i]; //主机地址 mFlash.mClient.macAddr[i] = mBackup.macAddr_R[i];//从机地址 } DEBUG_LOG("Back macAddr_L:");for(i=0;i<6;i++){DEBUG_LOG("%02X:",mBackup.macAddr_L[i]);}DEBUG_LOG("\r\n"); DEBUG_LOG("Back macAddr_R:");for(i=0;i<6;i++){DEBUG_LOG("%02X:",mBackup.macAddr_R[i]);}DEBUG_LOG("\r\n"); mFlash.mClient.hardVersion = mBackup.hardVersion; mFlash.mClient.sotfVersion = mBackup.sotfVersion; mFlash.mClient.isConfig = mBackup.isConfig; DEBUG_LOG("Back Data:ifconfig:%d,hardVer:%d,backup.softversion:%d\n",mBackup.isConfig,mBackup.hardVersion,mBackup.sotfVersion); }else{ memset((uint8_t*)(&mBackup),0,sizeof(FlashBackup_t)); if(Flash_SaveBackup() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_FLASH,"save backup fail"); } Flash_SaveInfomation(); DEBUG_LOG("Flash head second read(%04X).\n",*addr_R); if((*addr_R)!=FLASH_HEAD){ DEBUG_LOG("Flash write head fail.\n"); Except_TxError(EXCEPT_FLASH,"Flash write head fail"); ret = 1; return; } DEBUG_LOG("System reset...\n",*addr_R); for(uint8_t i =0;i<6;i++){ nrf_delay_ms(500); feed_watchdog(); } NVIC_SystemReset(); } if(ret==0){ sucess = Flash_GetInfomation(&mFlash); DEBUG_LOG("Flash_GetInfomation(&mFlash):%d \n",sucess); } DEBUG_LOG("err code :%s\n",mFlash.mFlashLog.logData); DEBUG_LOG("Flash init ok.\n"); mFlash.isHost = _IS_HOST; #ifdef PIN_SEL nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLUP); nrf_delay_ms(100); mFlash.isHost = (uint8_t)nrf_gpio_pin_read(PIN_SEL); if(1 == mFlash.isHost)nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLDOWN); else nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_NOPULL); #endif if(mFlash.isHost){ DEBUG_LOG("======= Left shooe ======= \n"); }else{ DEBUG_LOG("======= Right shooe ======= \n"); } //TestHalFlashInterface(); } /** @brief 设置清空flash的标志 @param 无 @return 无 */ static uint8_t FlashStep_ClearFlag =0; void flash_SetClearStepFlag(void){ FlashStep_ClearFlag =1; } /** @brief 存储步数 @param 无 @return 错误代码 */ uint32_t Flash_SaveStep(void) { uint32_t err_code; uint32_t flash_data; #define Max_Hour PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM if(mFlash.mStep.num < Max_Hour) { uint32_t step = app_step_GetStep_L() + app_step_GetStep_R(); //获取左右鞋步数 flash_data = ((step<<24 & 0xff000000) | (step<<8 & 0x00ff0000) | (step>>8 & 0x0000ff00) | (step>>24 & 0x000000ff)); //清空步数的flash step内容 if(1 == FlashStep_ClearFlag){ if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){ Except_TxError(EXCEPT_DATEStep,"clear step fail"); return ZONE_ERROR_WRITE_FAIL; } mFlash.mStep.num = 0; FlashStep_ClearFlag = 0; } err_code = Zone_Write(step_zone + (mFlash.mStep.num * 4), &flash_data, 4); if(err_code != ZONE_OP_SUCCESS)return err_code; mFlash.mStep.num++; mFlash.mStep.step[0] = mFlash.mStep.stepCur[0]; mFlash.mStep.step[1] = mFlash.mStep.stepCur[1]; if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_FLASH,"save information fail"); } else return ZONE_ERROR_WRITE_FAIL; return ZONE_OP_SUCCESS; } /** @brief 获取步数区域首地址 @param 无 @return 错误代码 */ uint32_t Flash_GetStepZoneStartAddr(void) { return step_zone; } /** @brief 获取步数区域数据 @param 无 @return 错误代码 */ uint32_t Flash_GetStep(uint32_t destination_addr, uint32_t *pData, uint32_t dataLen) { return Zone_Read(destination_addr,pData,dataLen); } /** @brief 删除所有步数 @param 无 @return 错误代码 */ uint32_t Flash_DeleteAllStep(void) { return Zone_Erase(step_zone); } /** @brief 删除所有的信息区域 @param 无 @return 错误代码 */ uint32_t Flash_DeleteAllInformation(void) { return Zone_Erase(info_zone); } /** @brief 存储基本信息 @param 无 @return 错误代码 */ uint32_t Flash_SaveInfomation(void) { uint32_t err_code; uint32_t zone_bytes; Flash_t temp_flash; int32_t offset; uint16_t crc; uint8_t tail_h; memset(&temp_flash,0,sizeof(temp_flash)); err_code = Zone_GetByteSize(info_zone, &zone_bytes); if(err_code != ZONE_OP_SUCCESS)return err_code; //从区域尾开始找起,找到最新的帧尾 for(offset = zone_bytes - 1; offset >= 0; offset--) { err_code = Zone_Read(info_zone + offset, (uint32_t*)&tail_h, 1); if(err_code != ZONE_OP_SUCCESS)return err_code; if(tail_h == FLASH_TAIL_H)break; } //重新获取crc16校验码 mFlash.tail_crc16 = 0; mFlash.m_struct_size = sizeof(mFlash); mFlash.head = FLASH_HEAD; crc = CalCrc(0, (char*)&mFlash, sizeof(mFlash));//计算得到的16位CRC校验码 mFlash.tail_crc16 = (uint32_t)((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; //写入 if(offset < 0){ //意味着整个区域是干净的,直接写开头。 err_code = Zone_Write(info_zone, (uint32_t*)&mFlash, sizeof(mFlash)); if(err_code != ZONE_OP_SUCCESS)return err_code; DEBUG_LOG("write zone all clear,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16); }else{ //这里要偏移才能对齐成员 offset++; //获取最新的帧尾 err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16), (uint32_t*)&temp_flash.tail_crc16, sizeof(temp_flash.tail_crc16)); if(err_code != ZONE_OP_SUCCESS)return err_code; //获取最新的帧长度 err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16) - sizeof(temp_flash.m_struct_size) , (uint32_t*)&temp_flash.m_struct_size, sizeof(temp_flash.m_struct_size)); if(err_code != ZONE_OP_SUCCESS)return err_code; //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。 // uint32_t pad_len = temp_flash.m_struct_size - ((uint32_t)&temp_flash.tail_crc16 + sizeof(temp_flash.tail_crc16) - (uint32_t)&temp_flash.head); uint32_t pad_len = 0; // DEBUG_LOG("save info_zone:0x%x offset:%d pad_len:%d temp_flash.m_struct_size:%d\n",info_zone,offset,pad_len,temp_flash.m_struct_size); if(offset + pad_len < temp_flash.m_struct_size)pad_len = temp_flash.m_struct_size - offset; err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head)); if(err_code != ZONE_OP_SUCCESS)return err_code; // DEBUG_LOG("save >>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size); while(temp_flash.head != FLASH_HEAD){ pad_len++; err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head)); if(err_code != ZONE_OP_SUCCESS)return err_code; // DEBUG_LOG("save >>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size); // nrf_delay_ms(5); } err_code = Zone_Write(info_zone + offset + pad_len, (uint32_t*)&mFlash, sizeof(mFlash)); // if(err_code == ZONE_OP_SUCCESS)DEBUG_LOG("write zone forward ,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16); if(err_code != ZONE_OP_SUCCESS){ //如果写失败了 //擦除该区域 err_code = Zone_Erase(info_zone); if(err_code != ZONE_OP_SUCCESS)return err_code; //写在开头 err_code = Zone_Write(info_zone, (uint32_t*)&mFlash, sizeof(mFlash)); if(err_code != ZONE_OP_SUCCESS)return err_code; // DEBUG_LOG("write zone all erase ,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16); } } return ZONE_OP_SUCCESS; } /** @brief 获取基本信息 @param 无 @return 错误代码 */ uint32_t Flash_GetInfomation(Flash_t *pflash) { uint32_t err_code; uint32_t zone_bytes; Flash_t temp_flash; int32_t offset; uint16_t crc; uint8_t tail_h; memset(&temp_flash,0,sizeof(temp_flash)); DEBUG_LOG("Zone_GetByteSize(info_zone, &zone_bytes):%d\n",zone_bytes); err_code = Zone_GetByteSize(info_zone, &zone_bytes); if(err_code != ZONE_OP_SUCCESS)return err_code; DEBUG_LOG("Zone_GetByteSize(info_zone, &zone_bytes):%d\n",zone_bytes); //从区域尾开始找起,找到最新的帧尾 for(offset = zone_bytes - 1; offset >= 0; offset--) { err_code = Zone_Read(info_zone + offset, (uint32_t*)&tail_h, 1); if(err_code != ZONE_OP_SUCCESS)return err_code; if(tail_h == FLASH_TAIL_H)break; } //意味着整个区域是干净的 if(offset < 0){ memset(pflash,0,sizeof(Flash_t)); pflash->head = FLASH_HEAD; pflash->m_struct_size = sizeof(Flash_t); //这里是包括填充字节的 crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码,这里注意,有可能会将填充的字节也拿来做运算 pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; //这里最后才加,是因为不知道填充字节的个数 DEBUG_LOG("read zone all clear,pflash->tail_crc16:0x%x\r\n",pflash->tail_crc16); return ZONE_OP_SUCCESS; } //这里要偏移才能对齐成员 offset++; //获取最新的帧尾 err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16), (uint32_t*)&temp_flash.tail_crc16, sizeof(temp_flash.tail_crc16)); if(err_code != ZONE_OP_SUCCESS)return err_code; //获取最新的帧长度 err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16) - sizeof(temp_flash.m_struct_size) , (uint32_t*)&temp_flash.m_struct_size, sizeof(temp_flash.m_struct_size)); if(err_code != ZONE_OP_SUCCESS)return err_code; //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。 // uint32_t pad_len = temp_flash.m_struct_size - ((uint32_t)&temp_flash.tail_crc16 + sizeof(temp_flash.tail_crc16) - (uint32_t)&temp_flash.head); uint32_t pad_len = 0; // DEBUG_LOG("get info_zone:0x%x offset:%d pad_len:%d temp_flash.m_struct_size:%d\n",info_zone,offset,pad_len,temp_flash.m_struct_size); if(offset + pad_len < temp_flash.m_struct_size)pad_len = temp_flash.m_struct_size - offset; err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head)); if(err_code != ZONE_OP_SUCCESS)return err_code; // DEBUG_LOG(">>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size); while(temp_flash.head != FLASH_HEAD){ pad_len++; err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size, (uint32_t*)&temp_flash.head, sizeof(temp_flash.head)); if(err_code != ZONE_OP_SUCCESS)return err_code; // DEBUG_LOG(">>>>>>p_head:0x%x,addr:0x%x\n",temp_flash.head,info_zone + offset + pad_len - temp_flash.m_struct_size); // nrf_delay_ms(5); } // DEBUG_LOG("read pad_len 0x%x info_zone + offset + pad_len - temp_flash.m_struct_size:0x%x\r\n",pad_len,info_zone + offset + pad_len - temp_flash.m_struct_size); //获取最新的帧 if(temp_flash.m_struct_size <= (sizeof(temp_flash.tail_crc16)+sizeof(temp_flash.m_struct_size)+pad_len))return ZONE_ERROR_READ_FAIL; err_code = Zone_Read(info_zone + offset + pad_len - temp_flash.m_struct_size , (uint32_t*)&temp_flash, temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len); if(err_code != ZONE_OP_SUCCESS)return err_code; //判断一下是否正确读取到最新的帧 if(temp_flash.m_struct_size <= (sizeof(temp_flash.tail_crc16)+sizeof(temp_flash.m_struct_size)+pad_len))//证明结构体被修改了 { //校验没通过 DEBUG_LOG("struct change,read crc fail :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF); memset(pflash,0,sizeof(Flash_t)); pflash->head = FLASH_HEAD; pflash->m_struct_size = sizeof(Flash_t); //将备份区域的数据拷贝 FlashBackup_t temp_backup; Flash_GetBackup(&temp_backup); for(int i=0;i<6;i++){ pflash->mClient.macAddr[i] = temp_backup.macAddr_R[i]; pflash->macHost[i] = temp_backup.macAddr_L[i]; } pflash->mClient.isConfig = temp_backup.isConfig; pflash->mClient.hardVersion = temp_backup.hardVersion; pflash->mClient.sotfVersion = temp_backup.sotfVersion; crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码 pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; err_code = Zone_Erase(info_zone); if(err_code != ZONE_OP_SUCCESS)return err_code; err_code = Flash_SaveInfomation(); if(err_code != ZONE_OP_SUCCESS)return err_code; return ZONE_OP_SUCCESS; } //校验数据 Flash_t crc_buf;//单纯做一个缓冲区 memset(&crc_buf,0,sizeof(crc_buf)); char *buf = (char*)&crc_buf; //获取成员head ~ m_struct_size // DEBUG_LOG("crc_buf:%d temp_flash.m_struct_size:%d,temp_flash.tail_crc16:%d\n",sizeof(crc_buf),temp_flash.m_struct_size,sizeof(temp_flash.tail_crc16)); // DEBUG_LOG("sizeof(temp_flash.m_struct_size):%d,pad_len:%d\n",sizeof(temp_flash.m_struct_size),pad_len); memcpy(buf,&temp_flash,temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len); // DEBUG_LOG("read pad_len:%d,info_zone:0x%x,offset:%d,pad_len:%d,temp_flash.m_struct_size:%d\r\n",pad_len,info_zone,offset,pad_len,temp_flash.m_struct_size); // DEBUG_LOG("2:buf:0x%x sizeof(temp_flash.m_struct_size):%d\n",buf + temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len,sizeof(temp_flash.m_struct_size)); memcpy(buf + temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len,(uint32_t*)&temp_flash.m_struct_size,sizeof(temp_flash.m_struct_size)); //计算得到的16位CRC校验码 crc = CalCrc(0, buf, temp_flash.m_struct_size); if(crc == (temp_flash.tail_crc16 & 0xFFFF)){ // DEBUG_LOG("read crc success :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF); temp_flash.head = FLASH_HEAD; temp_flash.m_struct_size = sizeof(temp_flash); temp_flash.tail_crc16 = 0; crc = CalCrc(0, (char*)&temp_flash, sizeof(temp_flash));//计算得到的16位CRC校验码 temp_flash.tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; *pflash = temp_flash;//校验通过 } else{ //校验没通过 // DEBUG_LOG("read crc fail :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF); memset(pflash,0,sizeof(Flash_t)); pflash->head = FLASH_HEAD; pflash->m_struct_size = sizeof(Flash_t); //将备份区域的数据拷贝 FlashBackup_t temp_backup; Flash_GetBackup(&temp_backup); for(int i=0;i<6;i++){ pflash->mClient.macAddr[i] = temp_backup.macAddr_R[i]; pflash->macHost[i] = temp_backup.macAddr_L[i]; } pflash->mClient.isConfig = temp_backup.isConfig; pflash->mClient.hardVersion = temp_backup.hardVersion; pflash->mClient.sotfVersion = temp_backup.sotfVersion; crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码 pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; err_code = Zone_Erase(info_zone); if(err_code != ZONE_OP_SUCCESS)return err_code; err_code = Flash_SaveInfomation(); if(err_code != ZONE_OP_SUCCESS)return err_code; } return ZONE_OP_SUCCESS; } /** @brief 存储备份信息 @param 无 @return 错误代码 */ uint32_t Flash_SaveBackup(void) { uint32_t err_code; mBackup.head = FLASH_HEAD; err_code = Zone_Erase(backup_zone); if(err_code != ZONE_OP_SUCCESS)return err_code; err_code = Zone_Write(backup_zone, (uint32_t*)&mBackup, sizeof(mBackup)); return err_code; } /** @brief 获取备份信息 @param 无 @return 错误代码 */ uint32_t Flash_GetBackup(FlashBackup_t *pbackup) { uint32_t err_code; err_code = Zone_Read(backup_zone, (uint32_t*)pbackup, sizeof(FlashBackup_t)); return err_code; } /** @brief 保存日志信息 @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. @param[in] pc The program counter of the instruction that triggered the fault, or 0 if unavailable. @param[in] info Optional additional information regarding the fault. The value of the @p id parameter dictates how to interpret this parameter. Refer to the documentation for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for details about interpreting @p info. @return 错误代码 */ uint32_t Flash_SaveLog(uint32_t id, uint32_t pc, uint32_t info) { memset((uint8_t*)(&mFlash.mFlashLog),0,sizeof(FlashLog)); mFlash.mFlashLog.Errorflag =1; switch (id) { #if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT case NRF_FAULT_ID_SD_ASSERT: memcpy(mFlash.mFlashLog.logData,"SD: ASSERTION FAILED\r\n",MaxLength(sizeof("SD: ASSERTION FAILED\r\n"),sizeof(mFlash.mFlashLog.logData))); break; case NRF_FAULT_ID_APP_MEMACC: memcpy(mFlash.mFlashLog.logData,"SD: INVALID MEMORY ACCESS\r\n",MaxLength(sizeof("SD: INVALID MEMORY ACCESS\r\n"),sizeof(mFlash.mFlashLog.logData))); break; #endif case NRF_FAULT_ID_SDK_ASSERT: { assert_info_t * p_info = (assert_info_t *)info; sprintf((char *)mFlash.mFlashLog.logData,"ASSERTION FAILED %s:%u\r\n", p_info->p_file_name, p_info->line_num); break; } case NRF_FAULT_ID_SDK_ERROR: { error_info_t * p_info = (error_info_t *)info; sprintf((char *)mFlash.mFlashLog.logData,"error:%u,%s:%u\r\n", p_info->err_code, p_info->p_file_name, p_info->line_num); DEBUG_LOG(">>>>>err code :%d,%s",p_info->err_code,mFlash.mFlashLog.logData); break; } default: sprintf((char *)mFlash.mFlashLog.logData,"UNKNOWN FAULT 0x%08X\n", pc); break; } return Flash_SaveInfomation(); } /** @brief 返回主机标志位 @param 无 @return 主机标志位 */ uint8_t Get_isHost(void) { return mFlash.isHost; } /** @brief 测试halflash接口 @param 无 @return 无 */ void TestHalFlashInterface(void) { Fstorage_FlashInit(); DEBUG_LOG("Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone)); DEBUG_LOG("Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone)); DEBUG_LOG("Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone)); DEBUG_LOG("Flash_GetInfomation(&mFlash):%d \n",Flash_GetInfomation(&mFlash)); DEBUG_LOG("Flash_GetInfomation(&mBackup):%d \n",Flash_GetBackup(&mBackup)); // uint32_t i; // Flash_t m_testflash; // FlashBackup_t m_testbackup; // //测试基本信息和备份信息的写入和读取 // for(i=0;i<10000;i++) // { // mFlash.mStep.num = i; // DEBUG_LOG("Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation()); // // mBackup.hardVersion = i; // DEBUG_LOG("Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup()); // } // // DEBUG_LOG("Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash)); // DEBUG_LOG("m_testflash:%d \n",m_testflash.mStep.num); // // DEBUG_LOG("Flash_GetBackup[%d]:%d \n",i,Flash_GetBackup(&m_testbackup)); // DEBUG_LOG("m_testbackup:%d \n",m_testbackup.hardVersion); }