app_flash.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. #include "app_flash.h"
  2. #include "bsp_wdt.h"
  3. /*************************************
  4. *DEFINITION
  5. */
  6. #define FLASH_HEAD 0xAA5555AA
  7. #define FLASH_TAIL_H 0xA5 //高位字节不能为0,因为结构体强制4字节对齐缘故,会导致解析错误。
  8. #define FLASH_TAIL_L 0x55 //低字节随意,最好是0101组合
  9. #define FLASH_ADDR_INFO_PAGENUM 1
  10. #define FLASH_ADDR_STEP_PAGENUM 2
  11. #define FLASH_ADDR_BACKUP_PAGENUM 1
  12. #define MaxLength(a,b) a>b?a:b
  13. /*********************************************************************
  14. * LOCAL VARIABLES
  15. */
  16. static uint32_t info_zone;
  17. static uint32_t step_zone;
  18. static uint32_t backup_zone;
  19. Flash_t mFlash;
  20. FlashBackup_t mBackup;
  21. /*********************************************************************
  22. * LOCAL FUCTIONS
  23. */
  24. /**
  25. @brief crc16校验码
  26. @param crc - [in] 默认0
  27. @param buf - [in] 指向需要校验的数据
  28. @param len - [in] 校验数据的长度
  29. @return 返回crc16校验码
  30. */
  31. static int CalCrc(int crc, const char *buf, int len)
  32. {
  33. unsigned int byte;
  34. unsigned char k;
  35. unsigned short ACC,TOPBIT;
  36. unsigned short remainder = crc;
  37. TOPBIT = 0x8000;
  38. for (byte = 0; byte < len; ++byte)
  39. {
  40. ACC = buf[byte];
  41. remainder ^= (ACC <<8);
  42. for (k = 8; k > 0; --k)
  43. {
  44. if (remainder & TOPBIT)
  45. {
  46. remainder = (remainder << 1) ^0x8005;
  47. }
  48. else
  49. {
  50. remainder = (remainder << 1);
  51. }
  52. }
  53. }
  54. remainder=remainder^0x0000;
  55. return remainder;
  56. }
  57. /****************************************************接口****************************************************/
  58. void Flash_Initialize(void)
  59. {
  60. uint8_t ret = 0;
  61. uint32_t* addr_R;
  62. Fstorage_FlashInit();
  63. SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone));
  64. SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone));
  65. SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone));
  66. addr_R = (uint32_t*)info_zone;
  67. SEGGER_RTT_printf(0,"Flash head read(%04X).\n",*addr_R);
  68. if((*addr_R)!=FLASH_HEAD){ SEGGER_RTT_printf(0,"Flash first init(%04X),write infomation to flash.\n",*addr_R);
  69. memset((uint8_t*)(&mFlash),0,sizeof(Flash_t));
  70. mFlash.head = FLASH_HEAD;
  71. mFlash.m_struct_size = sizeof(mFlash);
  72. Flash_SaveInfomation();
  73. SEGGER_RTT_printf(0,"Flash head second read(%04X).\n",*addr_R);
  74. if((*addr_R)!=FLASH_HEAD){
  75. SEGGER_RTT_printf(0,"Flash write head fail.\n");
  76. app_err_Set(ERR_NUM_FLASH,1);
  77. ret = 1;
  78. return;
  79. }
  80. SEGGER_RTT_printf(0,"System reset...\n",*addr_R);
  81. #if WATCHDOG_ENANBLE
  82. for(uint8_t i =0;i<6;i++){
  83. nrf_delay_ms(500);
  84. feed_watchdog();
  85. }
  86. #else
  87. nrf_delay_ms(3000);
  88. #endif
  89. NVIC_SystemReset();
  90. }
  91. if(ret==0){
  92. SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash)\n");
  93. SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash):%d \n",Flash_GetInfomation(&mFlash));
  94. SEGGER_RTT_printf(0,"Flash_GetInfomation(&mBackup):%d \n",Flash_GetBackup(&mBackup));
  95. }
  96. if(mFlash.mStep.stepCur[0]<mFlash.mStep.step[0])
  97. mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
  98. SEGGER_RTT_printf(0,"mFlash.mStep.num=%d\n",mFlash.mStep.num);
  99. SEGGER_RTT_printf(0,"mFlash.mStep.stepCur[0]=%d,mFlash.mStep.stepCur[1]=%d\n",mFlash.mStep.stepCur[0],mFlash.mStep.stepCur[1]);
  100. SEGGER_RTT_printf(0,"err code :%s\n",mFlash.mFlashLog.logData);
  101. SEGGER_RTT_printf(0,"Flash init ok.\n");
  102. mFlash.isHost = _IS_HOST;
  103. #ifdef PIN_SEL
  104. nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLUP);
  105. nrf_delay_ms(100);
  106. mFlash.isHost = (uint8_t)nrf_gpio_pin_read(PIN_SEL);
  107. nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_NOPULL);
  108. #endif
  109. if(mFlash.isHost){
  110. SEGGER_RTT_printf(0,"======= Left shooe ======= \n");
  111. }else{
  112. SEGGER_RTT_printf(0,"======= Right shooe ======= \n");
  113. }
  114. //TestHalFlashInterface();
  115. }
  116. /**
  117. @brief 存储步数
  118. @param 无
  119. @return 错误代码
  120. */
  121. uint32_t Flash_SaveStep(void)
  122. {
  123. uint32_t err_code;
  124. uint32_t flash_data;
  125. static uint32_t Max_Hour = PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM;
  126. if(mFlash.mStep.num < Max_Hour)
  127. {
  128. uint32_t step = app_step_GetStep_L() + app_step_GetStep_R(); //获取左右鞋步数
  129. flash_data = ((step<<24 & 0xff000000) | (step<<8 & 0x00ff0000) | (step>>8 & 0x0000ff00) | (step>>24 & 0x000000ff));
  130. err_code = Zone_Write(step_zone + (mFlash.mStep.num * 4), &flash_data, 4);
  131. if(err_code != ZONE_OP_SUCCESS)return err_code;
  132. mFlash.mStep.num++;
  133. mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
  134. mFlash.mStep.step[1] = mFlash.mStep.stepCur[1];
  135. }
  136. else return ZONE_ERROR_WRITE_FAIL;
  137. return ZONE_OP_SUCCESS;
  138. }
  139. /**
  140. @brief 获取步数区域首地址
  141. @param 无
  142. @return 错误代码
  143. */
  144. uint32_t Flash_GetStepZoneStartAddr(void)
  145. {
  146. return step_zone;
  147. }
  148. /**
  149. @brief 获取步数区域数据
  150. @param 无
  151. @return 错误代码
  152. */
  153. uint32_t Flash_GetStep(uint32_t destination_addr, uint32_t *pData, uint32_t dataLen)
  154. {
  155. return Zone_Read(destination_addr,pData,dataLen);
  156. }
  157. /**
  158. @brief 删除所有步数
  159. @param 无
  160. @return 错误代码
  161. */
  162. uint32_t Flash_DeleteAllStep(void)
  163. {
  164. mFlash.mStep.num = 0;
  165. return Zone_Erase(step_zone);
  166. }
  167. /**
  168. @brief 存储基本信息
  169. @param 无
  170. @return 错误代码
  171. */
  172. uint32_t Flash_SaveInfomation(void)
  173. {
  174. uint32_t err_code;
  175. uint32_t zone_bytes;
  176. Flash_t temp_flash;
  177. int32_t offset;
  178. uint16_t crc;
  179. uint8_t tail_h;
  180. memset(&temp_flash,0,sizeof(temp_flash));
  181. err_code = Zone_GetByteSize(info_zone, &zone_bytes);
  182. if(err_code != ZONE_OP_SUCCESS)return err_code;
  183. //从区域尾开始找起,找到最新的帧尾
  184. for(offset = zone_bytes - 1; offset >= 0; offset--)
  185. {
  186. err_code = Zone_Read(info_zone + offset, (uint32_t*)&tail_h, 1);
  187. if(err_code != ZONE_OP_SUCCESS)return err_code;
  188. if(tail_h == FLASH_TAIL_H)break;
  189. }
  190. //重新获取crc16校验码
  191. mFlash.tail_crc16 = 0;
  192. crc = CalCrc(0, (char*)&mFlash, sizeof(mFlash));//计算得到的16位CRC校验码
  193. mFlash.tail_crc16 = (uint32_t)((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
  194. //写入
  195. if(offset < 0){ //意味着整个区域是干净的,直接写开头。
  196. err_code = Zone_Write(info_zone, (uint32_t*)&mFlash, sizeof(mFlash));
  197. if(err_code != ZONE_OP_SUCCESS)return err_code;
  198. SEGGER_RTT_printf(0,"write zone all clear,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16);
  199. }else{
  200. //这里要偏移才能对齐成员
  201. offset++;
  202. //获取最新的帧尾
  203. err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16), (uint32_t*)&temp_flash.tail_crc16, sizeof(temp_flash.tail_crc16));
  204. if(err_code != ZONE_OP_SUCCESS)return err_code;
  205. //获取最新的帧长度
  206. 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));
  207. if(err_code != ZONE_OP_SUCCESS)return err_code;
  208. //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。
  209. 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);
  210. err_code = Zone_Write(info_zone + offset + pad_len, (uint32_t*)&mFlash, sizeof(mFlash));
  211. // if(err_code == ZONE_OP_SUCCESS)SEGGER_RTT_printf(0,"write zone forward ,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16);
  212. if(err_code != ZONE_OP_SUCCESS){ //如果写失败了
  213. //擦除该区域
  214. err_code = Zone_Erase(info_zone);
  215. if(err_code != ZONE_OP_SUCCESS)return err_code;
  216. //写在开头
  217. err_code = Zone_Write(info_zone, (uint32_t*)&mFlash, sizeof(mFlash));
  218. if(err_code != ZONE_OP_SUCCESS)return err_code;
  219. // SEGGER_RTT_printf(0,"write zone all erase ,mFlash.tail_crc16:0x%x\r\n",mFlash.tail_crc16);
  220. }
  221. }
  222. return ZONE_OP_SUCCESS;
  223. }
  224. /**
  225. @brief 获取基本信息
  226. @param 无
  227. @return 错误代码
  228. */
  229. uint32_t Flash_GetInfomation(Flash_t *pflash)
  230. {
  231. uint32_t err_code;
  232. uint32_t zone_bytes;
  233. Flash_t temp_flash;
  234. int32_t offset;
  235. uint16_t crc;
  236. uint8_t tail_h;
  237. memset(&temp_flash,0,sizeof(temp_flash));
  238. err_code = Zone_GetByteSize(info_zone, &zone_bytes);
  239. if(err_code != ZONE_OP_SUCCESS)return err_code;
  240. //从区域尾开始找起,找到最新的帧尾
  241. for(offset = zone_bytes - 1; offset >= 0; offset--)
  242. {
  243. err_code = Zone_Read(info_zone + offset, (uint32_t*)&tail_h, 1);
  244. if(err_code != ZONE_OP_SUCCESS)return err_code;
  245. if(tail_h == FLASH_TAIL_H)break;
  246. }
  247. //意味着整个区域是干净的
  248. if(offset < 0){
  249. memset(pflash,0,sizeof(Flash_t));
  250. pflash->head = FLASH_HEAD;
  251. pflash->m_struct_size = sizeof(Flash_t); //这里是包括填充字节的
  252. crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码,这里注意,有可能会将填充的字节也拿来做运算
  253. pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; //这里最后才加,是因为不知道填充字节的个数
  254. SEGGER_RTT_printf(0,"read zone all clear,pflash->tail_crc16:0x%x\r\n",pflash->tail_crc16);
  255. return ZONE_OP_SUCCESS;
  256. }
  257. //这里要偏移才能对齐成员
  258. offset++;
  259. //获取最新的帧尾
  260. err_code = Zone_Read(info_zone + offset - sizeof(temp_flash.tail_crc16), (uint32_t*)&temp_flash.tail_crc16, sizeof(temp_flash.tail_crc16));
  261. if(err_code != ZONE_OP_SUCCESS)return err_code;
  262. //获取最新的帧长度
  263. 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));
  264. if(err_code != ZONE_OP_SUCCESS)return err_code;
  265. //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。
  266. 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);
  267. // 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);
  268. //获取最新的帧
  269. 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);
  270. if(err_code != ZONE_OP_SUCCESS)return err_code;
  271. //校验数据
  272. Flash_t crc_buf;//单纯做一个缓冲区
  273. memset(&crc_buf,0,sizeof(crc_buf));
  274. char *buf = (char*)&crc_buf;
  275. //获取成员head ~ m_struct_size
  276. // 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);
  277. memcpy(buf,&temp_flash,temp_flash.m_struct_size - sizeof(temp_flash.tail_crc16)-sizeof(temp_flash.m_struct_size)-pad_len);
  278. // 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));
  279. 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));
  280. //计算得到的16位CRC校验码
  281. crc = CalCrc(0, buf, temp_flash.m_struct_size);
  282. if(crc == (temp_flash.tail_crc16 & 0xFFFF)){
  283. SEGGER_RTT_printf(0,"read crc success :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF);
  284. *pflash = temp_flash;//校验通过
  285. }
  286. else{
  287. //校验没通过
  288. SEGGER_RTT_printf(0,"read crc fail :0x%x 0x%x \r\n",crc,temp_flash.tail_crc16 & 0xFFFF);
  289. memset(pflash,0,sizeof(Flash_t));
  290. pflash->head = FLASH_HEAD;
  291. pflash->m_struct_size = sizeof(Flash_t);
  292. //将备份区域的数据拷贝
  293. FlashBackup_t temp_backup;
  294. Flash_GetBackup(&temp_backup);
  295. for(int i=0;i<6;i++){
  296. pflash->mClient.macAddr[i] = temp_backup.macAddr_R[i];
  297. pflash->macHost[i] = temp_backup.macAddr_L[i];
  298. }
  299. pflash->mClient.isConfig = temp_backup.isConfig;
  300. pflash->mClient.hardVersion = temp_backup.hardVersion;
  301. pflash->mClient.sotfVersion = temp_backup.sotfVersion;
  302. crc = CalCrc(0, (char*)pflash, sizeof(Flash_t));//计算得到的16位CRC校验码
  303. pflash->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
  304. err_code = Zone_Erase(info_zone);
  305. if(err_code != ZONE_OP_SUCCESS)return err_code;
  306. }
  307. return ZONE_OP_SUCCESS;
  308. }
  309. /**
  310. @brief 存储备份信息
  311. @param 无
  312. @return 错误代码
  313. */
  314. uint32_t Flash_SaveBackup(void)
  315. {
  316. uint32_t err_code;
  317. uint32_t zone_bytes;
  318. FlashBackup_t temp_backup;
  319. int32_t offset;
  320. uint16_t crc;
  321. uint8_t tail_h;
  322. memset(&temp_backup,0,sizeof(temp_backup));
  323. err_code = Zone_GetByteSize(backup_zone, &zone_bytes);
  324. if(err_code != ZONE_OP_SUCCESS)return err_code;
  325. //从区域尾开始找起,找到最新的帧尾
  326. for(offset = zone_bytes - 1; offset >= 0; offset--)
  327. {
  328. err_code = Zone_Read(backup_zone + offset, (uint32_t*)&tail_h, 1);
  329. if(err_code != ZONE_OP_SUCCESS)return err_code;
  330. if(tail_h == FLASH_TAIL_H)break;
  331. }
  332. //重新获取crc16校验码
  333. mBackup.tail_crc16 = 0;
  334. crc = CalCrc(0, (char*)&mBackup, sizeof(mBackup));//计算得到的16位CRC校验码
  335. mBackup.tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
  336. //写入
  337. if(offset < 0){ //意味着整个区域是干净的,直接写开头。
  338. err_code = Zone_Write(backup_zone, (uint32_t*)&mBackup, sizeof(mBackup));
  339. if(err_code != ZONE_OP_SUCCESS)return err_code;
  340. // SEGGER_RTT_printf(0,"write zone all clear,mBackup.tail_crc16:0x%x\r\n",mBackup.tail_crc16);
  341. }else{
  342. //这里要偏移才能对齐成员
  343. offset++;
  344. //获取最新的帧尾
  345. err_code = Zone_Read(backup_zone + offset - sizeof(temp_backup.tail_crc16), (uint32_t*)&temp_backup.tail_crc16, sizeof(temp_backup.tail_crc16));
  346. if(err_code != ZONE_OP_SUCCESS)return err_code;
  347. //获取最新的帧长度
  348. 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));
  349. if(err_code != ZONE_OP_SUCCESS)return err_code;
  350. //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。
  351. 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);
  352. err_code = Zone_Write(backup_zone + offset + pad_len, (uint32_t*)&mBackup, sizeof(mBackup));
  353. // if(err_code == ZONE_OP_SUCCESS)SEGGER_RTT_printf(0,"write zone forward ,mBackup.tail_crc16:0x%x\r\n",mBackup.tail_crc16);
  354. if(err_code != ZONE_OP_SUCCESS){ //如果写失败了
  355. //擦除该区域
  356. err_code = Zone_Erase(backup_zone);
  357. if(err_code != ZONE_OP_SUCCESS)return err_code;
  358. //写在开头
  359. err_code = Zone_Write(backup_zone, (uint32_t*)&mBackup, sizeof(mBackup));
  360. if(err_code != ZONE_OP_SUCCESS)return err_code;
  361. // SEGGER_RTT_printf(0,"write zone all erase ,mBackup.tail_crc16:0x%x\r\n",mBackup.tail_crc16);
  362. }
  363. }
  364. return ZONE_OP_SUCCESS;
  365. }
  366. /**
  367. @brief 获取备份信息
  368. @param 无
  369. @return 错误代码
  370. */
  371. uint32_t Flash_GetBackup(FlashBackup_t *pbackup)
  372. {
  373. uint32_t err_code;
  374. uint32_t zone_bytes;
  375. FlashBackup_t temp_backup;
  376. int32_t offset;
  377. uint16_t crc;
  378. uint8_t tail_h;
  379. memset(&temp_backup,0,sizeof(temp_backup));
  380. err_code = Zone_GetByteSize(backup_zone, &zone_bytes);
  381. if(err_code != ZONE_OP_SUCCESS)return err_code;
  382. //从区域尾开始找起,找到最新的帧尾
  383. for(offset = zone_bytes - 1; offset >= 0; offset--)
  384. {
  385. err_code = Zone_Read(backup_zone + offset, (uint32_t*)&tail_h, 1);
  386. if(err_code != ZONE_OP_SUCCESS)return err_code;
  387. if(tail_h == FLASH_TAIL_H)break;
  388. }
  389. //意味着整个区域是干净的
  390. if(offset < 0){
  391. memset(pbackup,0,sizeof(FlashBackup_t));
  392. pbackup->head = FLASH_HEAD;
  393. pbackup->m_struct_size = sizeof(FlashBackup_t); //这里是包括填充字节的
  394. crc = CalCrc(0, (char*)pbackup, sizeof(FlashBackup_t));//计算得到的16位CRC校验码,这里注意,有可能会将填充的字节也拿来做运算
  395. pbackup->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc; //这里最后才加,是因为不知道填充字节的个数
  396. // SEGGER_RTT_printf(0,"read zone all clear,pbackup->tail_crc16:0x%x\r\n",pbackup->tail_crc16);
  397. return ZONE_OP_SUCCESS;
  398. }
  399. //这里要偏移才能对齐成员
  400. offset++;
  401. //获取最新的帧尾
  402. err_code = Zone_Read(backup_zone + offset - sizeof(temp_backup.tail_crc16), (uint32_t*)&temp_backup.tail_crc16, sizeof(temp_backup.tail_crc16));
  403. if(err_code != ZONE_OP_SUCCESS)return err_code;
  404. //获取最新的帧长度
  405. 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));
  406. if(err_code != ZONE_OP_SUCCESS)return err_code;
  407. //因为结构体强制4字节对齐缘故,所以tail_crc16未必是真实存储的帧尾,后面可能带一些数据为0的填充字节。所以要做校准。
  408. 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);
  409. // SEGGER_RTT_printf(0,"read pad_len 0x%x\r\n",pad_len);
  410. //获取最新的帧
  411. 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);
  412. if(err_code != ZONE_OP_SUCCESS)return err_code;
  413. //校验数据
  414. FlashBackup_t crc_buf;//单纯做一个缓冲区
  415. memset(&crc_buf,0,sizeof(crc_buf));
  416. char *buf = (char*)&crc_buf;
  417. //获取成员head ~ m_struct_size
  418. memcpy(buf,&temp_backup,temp_backup.m_struct_size - sizeof(temp_backup.tail_crc16)-sizeof(temp_backup.m_struct_size)-pad_len);
  419. 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));
  420. //计算得到的16位CRC校验码
  421. crc = CalCrc(0, buf, temp_backup.m_struct_size);
  422. if(crc == (temp_backup.tail_crc16 & 0xFFFF)){
  423. // SEGGER_RTT_printf(0,"read crc success :0x%x 0x%x \r\n",crc,temp_backup.tail_crc16 & 0xFFFF);
  424. *pbackup = temp_backup;//校验通过
  425. }
  426. else{
  427. //校验没通过
  428. // SEGGER_RTT_printf(0,"read crc fail :0x%x 0x%x \r\n",crc,temp_backup.tail_crc16 & 0xFFFF);
  429. memset(pbackup,0,sizeof(FlashBackup_t));
  430. pbackup->head = FLASH_HEAD;
  431. pbackup->m_struct_size = sizeof(FlashBackup_t);
  432. crc = CalCrc(0, (char*)pbackup, sizeof(FlashBackup_t));//计算得到的16位CRC校验码
  433. pbackup->tail_crc16 = ((uint32_t)(FLASH_TAIL_H << 8 | FLASH_TAIL_L) << 16) | crc;
  434. err_code = Zone_Erase(backup_zone);
  435. if(err_code != ZONE_OP_SUCCESS)return err_code;
  436. }
  437. return ZONE_OP_SUCCESS;
  438. }
  439. /**
  440. @brief 保存日志信息
  441. @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
  442. @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
  443. unavailable.
  444. @param[in] info Optional additional information regarding the fault. The value of the @p id
  445. parameter dictates how to interpret this parameter. Refer to the documentation
  446. for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
  447. details about interpreting @p info.
  448. @return 错误代码
  449. */
  450. uint32_t Flash_SaveLog(uint32_t id, uint32_t pc, uint32_t info)
  451. {
  452. memset((uint8_t*)(&mFlash.mFlashLog),0,sizeof(FlashLog));
  453. mFlash.mFlashLog.Errorflag =1;
  454. switch (id)
  455. {
  456. #if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
  457. case NRF_FAULT_ID_SD_ASSERT:
  458. memcpy(mFlash.mFlashLog.logData,"SD: ASSERTION FAILED",MaxLength(sizeof("SD: ASSERTION FAILED"),sizeof(mFlash.mFlashLog.logData)));
  459. break;
  460. case NRF_FAULT_ID_APP_MEMACC:
  461. memcpy(mFlash.mFlashLog.logData,"SD: INVALID MEMORY ACCESS",MaxLength(sizeof("SD: INVALID MEMORY ACCESS"),sizeof(mFlash.mFlashLog.logData)));
  462. break;
  463. #endif
  464. case NRF_FAULT_ID_SDK_ASSERT:
  465. {
  466. assert_info_t * p_info = (assert_info_t *)info;
  467. sprintf((char *)mFlash.mFlashLog.logData,"ASSERTION FAILED %s:%u",
  468. p_info->p_file_name,
  469. p_info->line_num);
  470. break;
  471. }
  472. case NRF_FAULT_ID_SDK_ERROR:
  473. {
  474. error_info_t * p_info = (error_info_t *)info;
  475. sprintf((char *)mFlash.mFlashLog.logData,"error:%u,%s:%u",
  476. p_info->err_code,
  477. p_info->p_file_name,
  478. p_info->line_num);
  479. SEGGER_RTT_printf(0,">>>>>err code :%d,%s",p_info->err_code,mFlash.mFlashLog.logData);
  480. break;
  481. }
  482. default:
  483. sprintf((char *)mFlash.mFlashLog.logData,"UNKNOWN FAULT 0x%08X\n", pc);
  484. break;
  485. }
  486. return Flash_SaveInfomation();
  487. }
  488. /**
  489. @brief 返回主机标志位
  490. @param 无
  491. @return 主机标志位
  492. */
  493. uint8_t Get_isHost(void)
  494. {
  495. return mFlash.isHost;
  496. }
  497. /**
  498. @brief 测试halflash接口
  499. @param 无
  500. @return 无
  501. */
  502. void TestHalFlashInterface(void)
  503. {
  504. Fstorage_FlashInit();
  505. SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone):%d\n",Zone_Alloca(FLASH_ADDR_INFO_PAGENUM, &info_zone));
  506. SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone):%d\n",Zone_Alloca(FLASH_ADDR_STEP_PAGENUM, &step_zone));
  507. SEGGER_RTT_printf(0,"Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone):%d\n",Zone_Alloca(FLASH_ADDR_BACKUP_PAGENUM, &backup_zone));
  508. SEGGER_RTT_printf(0,"Flash_GetInfomation(&mFlash):%d \n",Flash_GetInfomation(&mFlash));
  509. SEGGER_RTT_printf(0,"Flash_GetInfomation(&mBackup):%d \n",Flash_GetBackup(&mBackup));
  510. uint32_t i;
  511. // Flash_t m_testflash;
  512. // FlashBackup_t m_testbackup;
  513. // //测试基本信息和备份信息的写入和读取
  514. // for(i=0;i<10000;i++)
  515. // {
  516. // mFlash.mStep.num = i;
  517. // SEGGER_RTT_printf(0,"Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
  518. //
  519. // mBackup.hardVersion = i;
  520. // SEGGER_RTT_printf(0,"Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
  521. // }
  522. //
  523. // SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
  524. // SEGGER_RTT_printf(0,"m_testflash:%d \n",m_testflash.mStep.num);
  525. //
  526. // SEGGER_RTT_printf(0,"Flash_GetBackup[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
  527. // SEGGER_RTT_printf(0,"m_testbackup:%d \n",m_testbackup.hardVersion);
  528. //测试步数信息的写入和读取
  529. for(i=0;i<(PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM+100);i++)
  530. {
  531. mFlash.mStep.stepCur[0] = 0;
  532. mFlash.mStep.stepCur[1] = i;
  533. SEGGER_RTT_printf(0,"Flash_SaveStep[%d]:%d \n\n",i,Flash_SaveStep());
  534. }
  535. uint8_t checkflash[4] = {0};
  536. for(i=0;i<(PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM);i+=4)
  537. {
  538. // Zone_Read(step_zone + i, (uint32_t*)&step, 4);
  539. // SEGGER_RTT_printf(0,"step[%d]:0x%x ",i,step);
  540. Zone_Read(step_zone + i,(uint32_t*)&checkflash[0], 4);
  541. SEGGER_RTT_printf(0,"checkflash[%d]:%02x,%02x,%02x,%02x ",i,checkflash[0],checkflash[1],checkflash[2],checkflash[3]);
  542. if(i%5 == 0)SEGGER_RTT_printf(0,"\n");
  543. nrf_delay_ms(5);
  544. }
  545. ////uint32_t Flash_SaveStep(void);
  546. //////存储基本信息
  547. ////uint32_t Flash_SaveInfomation(void);
  548. //////存储备份信息
  549. ////uint32_t Flash_SaveBackup(void);
  550. //////获取基本信息
  551. ////uint32_t Flash_GetInfomation(Flash_t *pflash);
  552. //////获取备份信息
  553. ////uint32_t Flash_GetBackup(FlashBackup_t *pbackup);
  554. //
  555. // uint32_t i;
  556. // Flash_t m_testflash;
  557. // FlashBackup_t m_testbackup;
  558. // Fstorage_FlashInit();
  559. //
  560. // #define INFO_PAGE_SIZE 1
  561. // #define BACKUP_PAGE_SIZE 1
  562. // #define STEP_PAGE_SIZE 2
  563. //
  564. // static uint32_t info_index;
  565. // static uint32_t backup_index;
  566. // static uint32_t step_index;
  567. //
  568. // Zone_Init(INFO_PAGE_SIZE, &info_index);
  569. // Zone_Init(BACKUP_PAGE_SIZE, &backup_index);
  570. // Zone_Init(STEP_PAGE_SIZE, &step_index);
  571. //
  572. // SEGGER_RTT_printf(0,"info_index=%d backup_index=%d step_index=%d\n",info_index,backup_index,step_index);
  573. //
  574. //
  575. //
  576. // while(1);
  577. //
  578. // //测试基本信息和备份信息的写入和读取
  579. // for(i=0;i<10000;i++)
  580. // {
  581. // mFlash.mStep.num = i;
  582. // SEGGER_RTT_printf(0,"Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
  583. //
  584. // mBackup.hardVersion = i;
  585. // SEGGER_RTT_printf(0,"Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
  586. // }
  587. //
  588. // SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
  589. // SEGGER_RTT_printf(0,"m_testflash:%d \n",m_testflash.mStep.num);
  590. //
  591. // SEGGER_RTT_printf(0,"Flash_GetInfomation[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
  592. // SEGGER_RTT_printf(0,"m_testbackup:%d \n",m_testbackup.hardVersion);
  593. // //测试步数信息的写入和读取
  594. // for(i=0;i<1500;i++)
  595. // {
  596. // mFlash.mStep.num = i;
  597. // mFlash.mStep.stepCur[0] = i;
  598. // mFlash.mStep.stepCur[1] = i+i;
  599. //
  600. // SEGGER_RTT_printf(0,"Flash_SaveStep[%d]:%d \n\n",i,Flash_SaveStep());
  601. // }
  602. // uint32_t checkflash[750];
  603. // Read_N_Byte_flash(FLASH_ADDR_STEP , (uint32_t*)checkflash, sizeof(checkflash));
  604. //
  605. // for(i=0;i<750;i++)
  606. // {
  607. // SEGGER_RTT_printf(0,"checkflash[%d]:0x%x ",i,checkflash[i]);
  608. // if(i%5 == 0)SEGGER_RTT_printf(0,"\n");
  609. // nrf_delay_ms(5);
  610. // }
  611. SEGGER_RTT_printf(0,"TestHalFlashInterface done !!!!!!!\n");
  612. }