Flash基础入门:nrf51822 SDK12.3.0的flash读写
Vivian 2018-05-30 来源 : 阅读 4372 评论 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频道!

本文由 @Vivian 发布于职坐标。未经许可,禁止转载。
喜欢 | 4 不喜欢 | 0
看完这篇文章有何感觉?已经有4人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程