123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 |
- #include "app_flash.h"
- #include "bsp_wdt.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;
- 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;
-
- Fstorage_FlashInit();
-
- SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone));
- SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone));
- SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone));
-
- addr_R = (uint32_t*)info_zone;
-
- SEGGER_RTT_printf(0,"Flash head read(%04X).\n",*addr_R);
- if((*addr_R)!=FLASH_HEAD){ SEGGER_RTT_printf(0,"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);
- Flash_SaveInfomation();
- SEGGER_RTT_printf(0,"Flash head second read(%04X).\n",*addr_R);
- if((*addr_R)!=FLASH_HEAD){
- SEGGER_RTT_printf(0,"Flash write head fail.\n");
- app_err_Set(ERR_NUM_FLASH,1);
- ret = 1;
- return;
- }
- SEGGER_RTT_printf(0,"System reset...\n",*addr_R);
- #if WATCHDOG_ENANBLE
- for(uint8_t i =0;i<6;i++){
- nrf_delay_ms(500);
- feed_watchdog();
- }
- #else
- nrf_delay_ms(3000);
- #endif
- NVIC_SystemReset();
- }
- if(ret==0){
- SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash)\n");
- SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash):%d \n",Flash_GetInfomation(&mFlash));
- SEGGER_RTT_printf(0,"Flash_GetInfomation(&mBackup):%d \n",Flash_GetBackup(&mBackup));
-
- // SEGGER_RTT_printf(0,">>>>>>>>>add:%02x,add1:%02x,add2:%02x,add3:%02x,add4:%02x,add5:%02x\r\n",mFlash.add,mFlash.add2,mFlash.add3,mFlash.add4,mFlash.add5);
- // mFlash.add = 0x11;
- // mFlash.add2 = 0x22;
- // mFlash.add3 = 0x33;
- // mFlash.add4 = 0x44;
- // SEGGER_RTT_printf(0,"Flash_SaveInfomation():%d\n",Flash_SaveInfomation());
- }
- if(mFlash.mStep.stepCur[0]<mFlash.mStep.step[0])
- mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
- SEGGER_RTT_printf(0,"mFlash.mStep.num=%d\n",mFlash.mStep.num);
- SEGGER_RTT_printf(0,"mFlash.mStep.stepCur[0]=%d,mFlash.mStep.stepCur[1]=%d\n",mFlash.mStep.stepCur[0],mFlash.mStep.stepCur[1]);
- SEGGER_RTT_printf(0,"err code :%s\n",mFlash.mFlashLog.logData);
-
- SEGGER_RTT_printf(0,"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){
- SEGGER_RTT_printf(0,"======= Left shooe ======= \n");
- }else{
- SEGGER_RTT_printf(0,"======= Right shooe ======= \n");
- }
-
- //TestHalFlashInterface();
- }
-
- /**
- @brief 存储步数
- @param 无
- @return 错误代码
- */
- uint32_t Flash_SaveStep(void)
- {
- uint32_t err_code;
- uint32_t flash_data;
- static uint32_t 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));
-
- 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];
- }
- 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)
- {
- mFlash.mStep.num = 0;
- return Zone_Erase(step_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;
- SEGGER_RTT_printf(0,"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;
- SEGGER_RTT_printf(0,"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;
- // SEGGER_RTT_printf(0,"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;
- // SEGGER_RTT_printf(0,"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);
- }
-
- // while(1)
- // {
- // SEGGER_RTT_printf(0,"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);
- // nrf_delay_ms(1000);
- // feed_watchdog();
- // }
-
- err_code = Zone_Write(info_zone + offset + pad_len, (uint32_t*)&mFlash, sizeof(mFlash));
- // if(err_code == ZONE_OP_SUCCESS)SEGGER_RTT_printf(0,"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;
- // SEGGER_RTT_printf(0,"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));
-
- SEGGER_RTT_printf(0,"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;
-
- SEGGER_RTT_printf(0,"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; //这里最后才加,是因为不知道填充字节的个数
- SEGGER_RTT_printf(0,"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;
- SEGGER_RTT_printf(0,"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;
- // SEGGER_RTT_printf(0,">>>>>>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;
- // SEGGER_RTT_printf(0,">>>>>>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);
- }
-
- // SEGGER_RTT_printf(0,"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);
- //获取最新的帧
- 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;
- //校验数据
- Flash_t crc_buf;//单纯做一个缓冲区
- memset(&crc_buf,0,sizeof(crc_buf));
- char *buf = (char*)&crc_buf;
- //获取成员head ~ m_struct_size
- // SEGGER_RTT_printf(0,"1:sizeof(crc_buf):%d temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len:%d\n",sizeof(crc_buf),temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-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);
- // SEGGER_RTT_printf(0,"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);
- // SEGGER_RTT_printf(0,"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)){
- SEGGER_RTT_printf(0,"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{
- //校验没通过
- SEGGER_RTT_printf(0,"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;
- uint32_t zone_bytes;
- FlashBackup_t temp_backup;
- int32_t offset;
- uint16_t crc;
- uint8_t tail_h;
-
- memset(&temp_backup,0,sizeof(temp_backup));
-
- err_code = Zone_GetByteSize(backup_zone, &zone_bytes);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
-
- //从区域尾开始找起,找到最新的帧尾
- for(offset = zone_bytes - 1; offset >= 0; offset--)
- {
- err_code = Zone_Read(backup_zone + offset, (uint32_t*)&tail_h, 1);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
-
- if(tail_h == FLASH_TAIL_H)break;
- }
- //重新获取crc16校验码
- mBackup.tail_crc16 = 0;
- mBackup.m_struct_size = sizeof(mBackup);
- mBackup.head = FLASH_HEAD;
- crc = CalCrc(0, (char*)&mBackup, sizeof(mBackup));//计算得到的16位CRC校验码
- mBackup.tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
- //写入
- if(offset < 0){ //意味着整个区域是干净的,直接写开头。
- err_code = Zone_Write(backup_zone, (uint32_t*)&mBackup, sizeof(mBackup));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- // SEGGER_RTT_printf(0,"write zone all clear,mBackup.tail_crc16:0x%x\r\n",mBackup.tail_crc16);
- }else{
- //这里要偏移才能对齐成员
- offset++;
- //获取最新的帧尾
- err_code = Zone_Read(backup_zone + offset - sizeof(temp_backup.tail_crc16), (uint32_t*)&temp_backup.tail_crc16, sizeof(temp_backup.tail_crc16));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- //获取最新的帧长度
- err_code = Zone_Read(backup_zone + offset - sizeof(temp_backup.tail_crc16) - sizeof(temp_backup.m_struct_size) , (uint32_t*)&temp_backup.m_struct_size, sizeof(temp_backup.m_struct_size));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。
- // uint32_t pad_len = temp_backup.m_struct_size - ((uint32_t)&temp_backup.tail_crc16 + sizeof(temp_backup.tail_crc16) - (uint32_t)&temp_backup.head);
-
-
- uint32_t pad_len = 0;
- SEGGER_RTT_printf(0,"save back up info_zone:0x%x offset:%d pad_len:%d temp_backup.m_struct_size:%d\n",backup_zone,offset,pad_len,temp_backup.m_struct_size);
- if(offset + pad_len < temp_backup.m_struct_size)pad_len = temp_backup.m_struct_size - offset;
- err_code = Zone_Read(backup_zone + offset + pad_len - temp_backup.m_struct_size, (uint32_t*)&temp_backup.head, sizeof(temp_backup.head));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- // SEGGER_RTT_printf(0,">>>>>>p_head:0x%x,addr:0x%x\n",temp_backup.head,info_zone + offset + pad_len - temp_backup.m_struct_size);
- while(temp_backup.head != FLASH_HEAD){
- pad_len++;
- err_code = Zone_Read(backup_zone + offset + pad_len - temp_backup.m_struct_size, (uint32_t*)&temp_backup.head, sizeof(temp_backup.head));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- // SEGGER_RTT_printf(0,">>>>>>p_head:0x%x,addr:0x%x\n",temp_backup.head,info_zone + offset + pad_len - temp_backup.m_struct_size);
- // nrf_delay_ms(5);
- }
-
-
-
-
- err_code = Zone_Write(backup_zone + offset + pad_len, (uint32_t*)&mBackup, sizeof(mBackup));
- // if(err_code == ZONE_OP_SUCCESS)SEGGER_RTT_printf(0,"write zone forward ,mBackup.tail_crc16:0x%x\r\n",mBackup.tail_crc16);
- if(err_code != ZONE_OP_SUCCESS){ //如果写失败了
- //擦除该区域
- 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));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- // SEGGER_RTT_printf(0,"write zone all erase ,mBackup.tail_crc16:0x%x\r\n",mBackup.tail_crc16);
- }
- }
-
- return ZONE_OP_SUCCESS;
- }
- /**
- @brief 获取备份信息
- @param 无
- @return 错误代码
- */
- uint32_t Flash_GetBackup(FlashBackup_t *pbackup)
- {
- uint32_t err_code;
- uint32_t zone_bytes;
- FlashBackup_t temp_backup;
- int32_t offset;
- uint16_t crc;
- uint8_t tail_h;
-
- memset(&temp_backup,0,sizeof(temp_backup));
-
- err_code = Zone_GetByteSize(backup_zone, &zone_bytes);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
-
- //从区域尾开始找起,找到最新的帧尾
- for(offset = zone_bytes - 1; offset >= 0; offset--)
- {
- err_code = Zone_Read(backup_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(pbackup,0,sizeof(FlashBackup_t));
- pbackup->head = FLASH_HEAD;
- pbackup->m_struct_size = sizeof(FlashBackup_t); //这里是包括填充字节的
- crc = CalCrc(0, (char*)pbackup, sizeof(FlashBackup_t));//计算得到的16位CRC校验码,这里注意,有可能会将填充的字节也拿来做运算
- pbackup->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; //这里最后才加,是因为不知道填充字节的个数
- // SEGGER_RTT_printf(0,"read zone all clear,pbackup->tail_crc16:0x%x\r\n",pbackup->tail_crc16);
- return ZONE_OP_SUCCESS;
- }
- //这里要偏移才能对齐成员
- offset++;
- //获取最新的帧尾
- err_code = Zone_Read(backup_zone + offset - sizeof(temp_backup.tail_crc16), (uint32_t*)&temp_backup.tail_crc16, sizeof(temp_backup.tail_crc16));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- //获取最新的帧长度
- err_code = Zone_Read(backup_zone + offset - sizeof(temp_backup.tail_crc16) - sizeof(temp_backup.m_struct_size) , (uint32_t*)&temp_backup.m_struct_size, sizeof(temp_backup.m_struct_size));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。
- // uint32_t pad_len = temp_backup.m_struct_size - ((uint32_t)&temp_backup.tail_crc16 + sizeof(temp_backup.tail_crc16) - (uint32_t)&temp_backup.head);
-
-
- uint32_t pad_len = 0;
- SEGGER_RTT_printf(0,"back up info_zone:0x%x offset:%d pad_len:%d temp_backup.m_struct_size:%d\n",backup_zone,offset,pad_len,temp_backup.m_struct_size);
- if(offset + pad_len < temp_backup.m_struct_size)pad_len = temp_backup.m_struct_size - offset;
- err_code = Zone_Read(backup_zone + offset + pad_len - temp_backup.m_struct_size, (uint32_t*)&temp_backup.head, sizeof(temp_backup.head));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- // SEGGER_RTT_printf(0,">>>>>>p_head:0x%x,addr:0x%x\n",temp_backup.head,info_zone + offset + pad_len - temp_backup.m_struct_size);
- while(temp_backup.head != FLASH_HEAD){
- pad_len++;
- err_code = Zone_Read(backup_zone + offset + pad_len - temp_backup.m_struct_size, (uint32_t*)&temp_backup.head, sizeof(temp_backup.head));
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- // SEGGER_RTT_printf(0,">>>>>>p_head:0x%x,addr:0x%x\n",temp_backup.head,info_zone + offset + pad_len - temp_backup.m_struct_size);
- // nrf_delay_ms(5);
- }
-
-
-
-
- // SEGGER_RTT_printf(0,"read pad_len 0x%x\r\n",pad_len);
- //获取最新的帧
- err_code = Zone_Read(backup_zone + offset + pad_len - temp_backup.m_struct_size , (uint32_t*)&temp_backup, temp_backup.m_struct_size - sizeof(temp_backup.tail_crc16)-sizeof(temp_backup.m_struct_size)-pad_len);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- //校验数据
- FlashBackup_t crc_buf;//单纯做一个缓冲区
- memset(&crc_buf,0,sizeof(crc_buf));
- char *buf = (char*)&crc_buf;
- //获取成员head ~ m_struct_size
- memcpy(buf,&temp_backup,temp_backup.m_struct_size - sizeof(temp_backup.tail_crc16)-sizeof(temp_backup.m_struct_size)-pad_len);
- memcpy(buf + temp_backup.m_struct_size - sizeof(temp_backup.tail_crc16)-sizeof(temp_backup.m_struct_size)-pad_len,(uint32_t*)&temp_backup.m_struct_size,sizeof(temp_backup.m_struct_size));
- //计算得到的16位CRC校验码
- crc = CalCrc(0, buf, temp_backup.m_struct_size);
-
-
- if(crc == (temp_backup.tail_crc16 & 0xFFFF)){
- // SEGGER_RTT_printf(0,"read crc success :0x%x 0x%x \r\n",crc,temp_backup.tail_crc16 & 0xFFFF);
- temp_backup.head = FLASH_HEAD;
- temp_backup.m_struct_size = sizeof(temp_backup);
- temp_backup.tail_crc16 = 0;
- crc = CalCrc(0, (char*)&temp_backup, sizeof(temp_backup));//计算得到的16位CRC校验码
- temp_backup.tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
- *pbackup = temp_backup;//校验通过
- }
- else{
- //校验没通过
- // SEGGER_RTT_printf(0,"read crc fail :0x%x 0x%x \r\n",crc,temp_backup.tail_crc16 & 0xFFFF);
- memset(pbackup,0,sizeof(FlashBackup_t));
- pbackup->head = FLASH_HEAD;
- pbackup->m_struct_size = sizeof(FlashBackup_t);
- crc = CalCrc(0, (char*)pbackup, sizeof(FlashBackup_t));//计算得到的16位CRC校验码
- pbackup->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
- err_code = Zone_Erase(backup_zone);
- if(err_code != ZONE_OP_SUCCESS)return err_code;
- }
-
-
- return ZONE_OP_SUCCESS;
- }
- /**
- @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);
- SEGGER_RTT_printf(0,">>>>>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();
-
- SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone));
- SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone));
- SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone));
- SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash):%d \n",Flash_GetInfomation(&mFlash));
- SEGGER_RTT_printf(0,"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;
- // SEGGER_RTT_printf(0,"Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
- //
- // mBackup.hardVersion = i;
- // SEGGER_RTT_printf(0,"Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
- // }
- //
- // SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
- // SEGGER_RTT_printf(0,"m_testflash:%d \n",m_testflash.mStep.num);
- //
- // SEGGER_RTT_printf(0,"Flash_GetBackup[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
- // SEGGER_RTT_printf(0,"m_testbackup:%d \n",m_testbackup.hardVersion);
-
- //测试步数信息的写入和读取
- for(i=0;i<(PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM+100);i++)
- {
- mFlash.mStep.stepCur[0] = 0;
- mFlash.mStep.stepCur[1] = i;
- SEGGER_RTT_printf(0,"Flash_SaveStep[%d]:%d \n\n",i,Flash_SaveStep());
- }
-
- uint8_t checkflash[4] = {0};
- for(i=0;i<(PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM);i+=4)
- {
- // Zone_Read(step_zone + i, (uint32_t*)&step, 4);
- // SEGGER_RTT_printf(0,"step[%d]:0x%x ",i,step);
- Zone_Read(step_zone + i,(uint32_t*)&checkflash[0], 4);
- SEGGER_RTT_printf(0,"checkflash[%d]:%02x,%02x,%02x,%02x ",i,checkflash[0],checkflash[1],checkflash[2],checkflash[3]);
- if(i%5 == 0)SEGGER_RTT_printf(0,"\n");
- nrf_delay_ms(5);
- }
-
-
-
-
-
-
-
- ////uint32_t Flash_SaveStep(void);
- //////存储基本信息
- ////uint32_t Flash_SaveInfomation(void);
- //////存储备份信息
- ////uint32_t Flash_SaveBackup(void);
- //////获取基本信息
- ////uint32_t Flash_GetInfomation(Flash_t *pflash);
- //////获取备份信息
- ////uint32_t Flash_GetBackup(FlashBackup_t *pbackup);
- //
- // uint32_t i;
- // Flash_t m_testflash;
- // FlashBackup_t m_testbackup;
- // Fstorage_FlashInit();
- //
- // #define INFO_PAGE_SIZE 1
- // #define BACKUP_PAGE_SIZE 1
- // #define STEP_PAGE_SIZE 2
- //
- // static uint32_t info_index;
- // static uint32_t backup_index;
- // static uint32_t step_index;
- //
- // Zone_Init(INFO_PAGE_SIZE, &info_index);
- // Zone_Init(BACKUP_PAGE_SIZE, &backup_index);
- // Zone_Init(STEP_PAGE_SIZE, &step_index);
- //
- // SEGGER_RTT_printf(0,"info_index=%d backup_index=%d step_index=%d\n",info_index,backup_index,step_index);
- //
- //
- //
- // while(1);
- //
- // //测试基本信息和备份信息的写入和读取
- // for(i=0;i<10000;i++)
- // {
- // mFlash.mStep.num = i;
- // SEGGER_RTT_printf(0,"Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
- //
- // mBackup.hardVersion = i;
- // SEGGER_RTT_printf(0,"Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
- // }
- //
- // SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
- // SEGGER_RTT_printf(0,"m_testflash:%d \n",m_testflash.mStep.num);
- //
- // SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
- // SEGGER_RTT_printf(0,"m_testbackup:%d \n",m_testbackup.hardVersion);
- // //测试步数信息的写入和读取
- // for(i=0;i<1500;i++)
- // {
- // mFlash.mStep.num = i;
- // mFlash.mStep.stepCur[0] = i;
- // mFlash.mStep.stepCur[1] = i+i;
- //
- // SEGGER_RTT_printf(0,"Flash_SaveStep[%d]:%d \n\n",i,Flash_SaveStep());
- // }
- // uint32_t checkflash[750];
- // Read_N_Byte_flash(FLASH_ADDR_STEP , (uint32_t*)checkflash, sizeof(checkflash));
- //
- // for(i=0;i<750;i++)
- // {
- // SEGGER_RTT_printf(0,"checkflash[%d]:0x%x ",i,checkflash[i]);
- // if(i%5 == 0)SEGGER_RTT_printf(0,"\n");
- // nrf_delay_ms(5);
- // }
-
-
- SEGGER_RTT_printf(0,"TestHalFlashInterface done !!!!!!!\n");
- }
|