Vivian
2018-05-30
来源 :
阅读 5258
评论 0
摘要:本次的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频道!
喜欢 | 4
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号