摘要:本次的Flash基础入门中,我们知道因为sdk12使用fstorage代替了pstorage,网上能搜到的资料都用不了了,于是只能去nordic的官方论坛里面找。在论坛里面蹲了两天,终于实现了flash的存储。希望对大家学习Flash基础入门有所帮助。
一、前言
本次的Flash基础入门中,我们知道因为sdk12使用fstorage代替了pstorage,网上能搜到的资料都用不了了,于是只能去nordic的官方论坛里面找。在论坛里面蹲了两天,终于实现了flash的存储。希望对大家学习Flash基础入门有所帮助。
二、实验平台
协议栈版本:nRF5_SDK_12.3.0_d7731ad
例程为ble_app_uart
三、实验流程
1、结构体与全局变量声明
[objc] view plain copy 1. #define DATA_SIZE 8 2. uint32_t m_datas[DATA_SIZE]={0,1,2,3,88,5,6,7}; 3. uint8_t erase_flag=0; 4. uint8_t store_flag=0; 5. FS_REGISTER_CFG(fs_config_t fs_config) = 6. { 7. .callback = fs_evt_handler,// Function for event callbacks. 8. .num_pages = 1, // Number of physical flash pages required. 9. .priority = 0xFE // Priority for flash usage. 10. };
2、flash操作回调函数
[css] view plain copy 1. static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result) 2. { 3. if( (evt->id == FS_EVT_STORE) && (result == FS_SUCCESS) ) 4. { 5. store_flag = 0; 6. printf("store_flag: %d \r\n", store_flag); 7. // NRF_LOG_RAW_INFO("store_flag: %d \r\n", store_flag); 8. } 9. else if( (evt->id == FS_EVT_ERASE) && (result == FS_SUCCESS) ) 10. { 11. erase_flag = 0; 12. //NRF_LOG_RAW_INFO("erase_flag: %d \r\n", erase_flag); 13. printf("erase_flag: %d \r\n", erase_flag); 14. } 15. else if (result != NRF_SUCCESS) 16. { 17. printf("fstorage error and code: %d \r\n", result); 18. // NRF_LOG_RAW_INFO("fstorage error and code: %d \r\n", result); 19. } 20. }
3、flash功能初始(main函数中)
[objc] view plain copy 1. fs_ret_t ret = fs_init(); 2. if( ret == FS_SUCCESS ) 3. { 4. printf("fs init successful\r\n"); 5. } 6. else 7. { 8. printf("fs init failed\r\n"); 9. printf("err_code is:%d\r\n",ret); 10. m_flash_erase(); 11. } 12.
4、flash操作相关函数
[objc] view plain copy 1. uint32_t constconst * address_of_page(uint16_t page_num) 2. { 3. return fs_config.p_start_addr + (page_num * DATA_SIZE); 4. } 5. 6. void m_flash_read(const uint32_t* address) 7. { 8. uint32_t* m_addr = (uint32_t*)address; 9. uint32_t buff[DATA_SIZE]; 10. for(int i=0; i<DATA_SIZE; i++ ) 11. { 12. buff[i] = *m_addr; 13. //NRF_LOG_INFO("Data: %d\r\n",m_tbd_obj.flash_test[i]); 14. m_addr++; 15. } 16. 17. for(int i = 0; i< DATA_SIZE; i++) 18. { 19. printf("%d ",buff[i]); 20. } 21. printf("\r\n"); 22. 23. } 24. 25. void m_flash_write(void) 26. { 27. fs_ret_t ret; 28. erase_flag=1; 29. // Erase one page (page 0). 30. ret = fs_erase(&fs_config, address_of_page(0), 1,NULL); 31. if (ret != FS_SUCCESS) 32. { 33. // NRF_LOG_INFO("fs_erase error\r\n"); 34. <span style="white-space:pre;"> </span> printf("fs_erase error\r\n"); 35. printf("err_code is:%d\r\n",ret); 36. } 37. else 38. { 39. printf("fs_erase FS_SUCCESS\r\n"); 40. //NRF_LOG_INFO("fs_erase FS_SUCCESS\r\n"); 41. } 42. while(erase_flag == 1) { power_manage(); } 43. 44. store_flag=1; 45. ret = fs_store(&fs_config, fs_config.p_start_addr, m_datas, DATA_SIZE,NULL); 46. if (ret != FS_SUCCESS) 47. { 48. // NRF_LOG_INFO("fs_store error\r\n"); 49. printf("fs_store error\r\n"); 50. printf("err_code is:%d\r\n",ret); 51. } 52. else 53. { 54. //NRF_LOG_INFO("fs_store FS_SUCCESS\r\n"); 55. printf("fs_store FS_SUCCESS\r\n"); 56. 57. } 58. while(store_flag == 1) { power_manage(); } 59. } 60. void m_flash_erase(void) 61. { 62. erase_flag=1; 63. // Erase one page (page 0). 64. fs_ret_t ret = fs_erase(&fs_config, address_of_page(0), 1, NULL); 65. if( ret != FS_SUCCESS ) 66. { 67. // NRF_LOG_INFO("fs_erase error\r\n"); 68. printf("fs_erase error\r\n"); 69. printf("err_code is:%d\r\n",ret); 70. } 71. else 72. { 73. // NRF_LOG_INFO("fs_erase FS_SUCCESS\r\n"); 74. printf("fs_erase FS_SUCCESS\r\n"); 75. 76. } 77. while(erase_flag == 1) { power_manage(); } 78. }
5、在ble_stack_init中添加sys_evt_dispatch
因为fstorage的实现是基于状态机,协议栈会分步进行flash操作。在我们erase/write的操作函数中有一个等待标志位清零的循环,这个标志位就是在flahs回调函数中进行清零的。
在main.c中添加
[objc] view plain copy 1. static void ble_stack_init(void) 2. { 3. ..... 4. err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);//添加系统事件派发 5. APP_ERROR_CHECK(err_code); 6. } 7. 8. static void sys_evt_dispatch(uint32_t sys_evt) 9. { 10. ble_advertising_on_sys_evt(sys_evt); 11. //这函数在fstorage.c中实现 12. fs_sys_event_handler(sys_evt); 13. }
当有系统事件时,会执行fs_sys_event_handler(sys_evt)函数
[css] view plain copy 1. void fs_sys_event_handler(uint32_t sys_evt) 2. { 3. fs_op_t * const p_op = &m_queue.op[m_queue.rp]; 4. 5. if (m_flags & FS_FLAG_PROCESSING) 6. { 7. // A flash operation was initiated by this module. Handle the result. 8. switch (sys_evt) 9. { 10. case NRF_EVT_FLASH_OPERATION_SUCCESS: 11. on_operation_success(p_op); //当flash操作成功时 12. break; 13. 14. case NRF_EVT_FLASH_OPERATION_ERROR: 15. on_operation_failure(p_op); //当flash操作失败时 16. break; 17. } 18. } 19. else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING)) 20. { 21. // A flash operation was initiated outside this module. 22. // A callback which indicates that it has finished was received. 23. m_flags &= ~FS_FLAG_FLASH_REQ_PENDING; 24. 25. // If there are any elements left in the queue, set FS_FLAG_PROCESSING. 26. if (m_queue.count > 0) 27. { 28. m_flags |= FS_FLAG_PROCESSING; 29. } 30. } 31. 32. // Resume processing the queue, if necessary. 33. queue_process(); 34. }
我们进入flash操作成功的分支,进入on_operation_success(fs_op_t * const p_op)
[css] view plain copy 1. static void on_operation_success(fs_op_t * const p_op) 2. { 3. m_retry_count = 0; 4. 5. switch (p_op->op_code) 6. { 7. case FS_OP_STORE: 8. { 9. uint16_t chunk_len; 10. 11. if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS) 12. { 13. chunk_len = p_op->store.length_words - p_op->store.offset; 14. } 15. else 16. { 17. chunk_len = FS_MAX_WRITE_SIZE_WORDS; 18. } 19. 20. p_op->store.offset += chunk_len; 21. 22. if (p_op->store.offset == p_op->store.length_words) 23. { 24. // The operation has finished. 25. send_event(p_op, FS_SUCCESS); //flash操作完成之后执行 26. queue_advance(); 27. } 28. } 29. break; 30. 31. case FS_OP_ERASE: 32. { 33. p_op->erase.page++; 34. p_op->erase.pages_erased++; 35. 36. if (p_op->erase.pages_erased == p_op->erase.pages_to_erase) 37. { 38. send_event(p_op, FS_SUCCESS); 39. queue_advance(); 40. } 41. } 42. break; 43. 44. default: 45. // Should not happen. 46. break; 47. } 48. }
进入send_event(p_op, FS_SUCCESS)
[css] view plain copy 1. static void send_event(fs_op_t const * const p_op, fs_ret_t result) 2. { 3. fs_evt_t evt; 4. memset(&evt, 0x00, sizeof(fs_evt_t)); 5. 6. switch (p_op->op_code) 7. { 8. case FS_OP_STORE: 9. evt.id = FS_EVT_STORE; 10. evt.store.p_data = p_op->store.p_dest; 11. evt.store.length_words = p_op->store.length_words; 12. break; 13. 14. case FS_OP_ERASE: 15. evt.id = FS_EVT_ERASE; 16. evt.erase.first_page = p_op->erase.page - p_op->erase.pages_erased; 17. evt.erase.last_page = p_op->erase.page; 18. break; 19. 20. default: 21. // Should not happen. 22. break; 23. } 24. evt.p_context = p_op->p_context; 25. 26. p_op->p_config->callback(&evt, result); //这里就调用了之前注册的回调函数 27. }
四、实验结果
上电初始化之后,串口输出
[css] view plain copy 1. fs init successful
调用m_flash_write()之后,串口输出
[css] view plain copy 1. m_flash_write..fs_erase FS_SUCCESS 2. erase_flag: 0 3. fs_store FS_SUCCESS 4. store_flag: 0
这样代表了已经存储成功
调用m_flash_read(),输出
[css] view plain copy 1. m_flash_read..0 1 2 3 88 5 6 7
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标常用软件Flash频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号