app_flash.c 24 KB

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