nrf51822 SDK12.3.0的flash读写
来源:互联网 发布:win10好多软件打不开 编辑:程序博客网 时间:2024/05/29 08:14
一、前言
因为sdk12使用fstorage代替了pstorage,网上能搜到的资料都用不了了,于是只能去nordic的官方论坛里面找。在论坛里面蹲了两天,终于实现了flash的存储。
二、实验平台
协议栈版本:nRF5_SDK_12.3.0_d7731ad
例程为ble_app_uart
三、实验流程
1、结构体与全局变量声明
#define DATA_SIZE 8uint32_t m_datas[DATA_SIZE]={0,1,2,3,88,5,6,7};uint8_t erase_flag=0;uint8_t store_flag=0;FS_REGISTER_CFG(fs_config_t fs_config) ={.callback = fs_evt_handler,// Function for event callbacks..num_pages = 1, // Number of physical flash pages required..priority = 0xFE // Priority for flash usage.};
2、flash操作回调函数
static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result){ if( (evt->id == FS_EVT_STORE) && (result == FS_SUCCESS) ) { store_flag = 0; printf("store_flag: %d \r\n", store_flag); // NRF_LOG_RAW_INFO("store_flag: %d \r\n", store_flag); } else if( (evt->id == FS_EVT_ERASE) && (result == FS_SUCCESS) ) { erase_flag = 0; //NRF_LOG_RAW_INFO("erase_flag: %d \r\n", erase_flag); printf("erase_flag: %d \r\n", erase_flag); } else if (result != NRF_SUCCESS) { printf("fstorage error and code: %d \r\n", result); // NRF_LOG_RAW_INFO("fstorage error and code: %d \r\n", result); }}
3、flash功能初始(main函数中)
fs_ret_t ret = fs_init();if( ret == FS_SUCCESS ){ printf("fs init successful\r\n");}else{ printf("fs init failed\r\n"); printf("err_code is:%d\r\n",ret); m_flash_erase();}
4、flash操作相关函数
uint32_t const * address_of_page(uint16_t page_num){ return fs_config.p_start_addr + (page_num * DATA_SIZE);}void m_flash_read(const uint32_t* address){ uint32_t* m_addr = (uint32_t*)address; uint32_t buff[DATA_SIZE]; for(int i=0; i<DATA_SIZE; i++ ) { buff[i] = *m_addr; //NRF_LOG_INFO("Data: %d\r\n",m_tbd_obj.flash_test[i]); m_addr++; } for(int i = 0; i< DATA_SIZE; i++) { printf("%d ",buff[i]); } printf("\r\n"); }void m_flash_write(void){ fs_ret_t ret; erase_flag=1; // Erase one page (page 0). ret = fs_erase(&fs_config, address_of_page(0), 1,NULL); if (ret != FS_SUCCESS) {// NRF_LOG_INFO("fs_erase error\r\n"); printf("fs_erase error\r\n"); printf("err_code is:%d\r\n",ret); } else {printf("fs_erase FS_SUCCESS\r\n");//NRF_LOG_INFO("fs_erase FS_SUCCESS\r\n"); } while(erase_flag == 1) { power_manage(); } store_flag=1;ret = fs_store(&fs_config, fs_config.p_start_addr, m_datas, DATA_SIZE,NULL);if (ret != FS_SUCCESS){// NRF_LOG_INFO("fs_store error\r\n"); printf("fs_store error\r\n"); printf("err_code is:%d\r\n",ret);}else{//NRF_LOG_INFO("fs_store FS_SUCCESS\r\n"); printf("fs_store FS_SUCCESS\r\n"); }while(store_flag == 1) { power_manage(); }}void m_flash_erase(void){ erase_flag=1; // Erase one page (page 0). fs_ret_t ret = fs_erase(&fs_config, address_of_page(0), 1, NULL); if( ret != FS_SUCCESS ) { // NRF_LOG_INFO("fs_erase error\r\n"); printf("fs_erase error\r\n"); printf("err_code is:%d\r\n",ret); } else { // NRF_LOG_INFO("fs_erase FS_SUCCESS\r\n"); printf("fs_erase FS_SUCCESS\r\n"); } while(erase_flag == 1) { power_manage(); }}
5、在ble_stack_init中添加sys_evt_dispatch
因为fstorage的实现是基于状态机,协议栈会分步进行flash操作。在我们erase/write的操作函数中有一个等待标志位清零的循环,这个标志位就是在flahs回调函数中进行清零的。
在main.c中添加
static void ble_stack_init(void){ ..... err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);//添加系统事件派发 APP_ERROR_CHECK(err_code);}static void sys_evt_dispatch(uint32_t sys_evt){ ble_advertising_on_sys_evt(sys_evt); //这函数在fstorage.c中实现 fs_sys_event_handler(sys_evt);}当有系统事件时,会执行fs_sys_event_handler(sys_evt)函数
void fs_sys_event_handler(uint32_t sys_evt){ fs_op_t * const p_op = &m_queue.op[m_queue.rp]; if (m_flags & FS_FLAG_PROCESSING) { // A flash operation was initiated by this module. Handle the result. switch (sys_evt) { case NRF_EVT_FLASH_OPERATION_SUCCESS: on_operation_success(p_op); //当flash操作成功时 break; case NRF_EVT_FLASH_OPERATION_ERROR: on_operation_failure(p_op); //当flash操作失败时 break; } } else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING)) { // A flash operation was initiated outside this module. // A callback which indicates that it has finished was received. m_flags &= ~FS_FLAG_FLASH_REQ_PENDING; // If there are any elements left in the queue, set FS_FLAG_PROCESSING. if (m_queue.count > 0) { m_flags |= FS_FLAG_PROCESSING; } } // Resume processing the queue, if necessary. queue_process();}我们进入flash操作成功的分支,进入on_operation_success(fs_op_t * const p_op)
static void on_operation_success(fs_op_t * const p_op){ m_retry_count = 0; switch (p_op->op_code) { case FS_OP_STORE: { uint16_t chunk_len; if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS) { chunk_len = p_op->store.length_words - p_op->store.offset; } else { chunk_len = FS_MAX_WRITE_SIZE_WORDS; } p_op->store.offset += chunk_len; if (p_op->store.offset == p_op->store.length_words) { // The operation has finished. send_event(p_op, FS_SUCCESS); //flash操作完成之后执行 queue_advance(); } } break; case FS_OP_ERASE: { p_op->erase.page++; p_op->erase.pages_erased++; if (p_op->erase.pages_erased == p_op->erase.pages_to_erase) { send_event(p_op, FS_SUCCESS); queue_advance(); } } break; default: // Should not happen. break; }}进入send_event(p_op, FS_SUCCESS)
static void send_event(fs_op_t const * const p_op, fs_ret_t result){ fs_evt_t evt; memset(&evt, 0x00, sizeof(fs_evt_t)); switch (p_op->op_code) { case FS_OP_STORE: evt.id = FS_EVT_STORE; evt.store.p_data = p_op->store.p_dest; evt.store.length_words = p_op->store.length_words; break; case FS_OP_ERASE: evt.id = FS_EVT_ERASE; evt.erase.first_page = p_op->erase.page - p_op->erase.pages_erased; evt.erase.last_page = p_op->erase.page; break; default: // Should not happen. break; } evt.p_context = p_op->p_context; p_op->p_config->callback(&evt, result); //这里就调用了之前注册的回调函数}
四、实验结果
上电初始化之后,串口输出
fs init successful调用m_flash_write()之后,串口输出
m_flash_write..fs_erase FS_SUCCESSerase_flag: 0 fs_store FS_SUCCESSstore_flag: 0这样代表了已经存储成功
调用m_flash_read(),输出
m_flash_read..0 1 2 3 88 5 6 7
如有错误,请留言。
阅读全文
0 0
- nrf51822 SDK12.3.0的flash读写
- NRF51822 SDK12的空中升级
- nrf51822 写flash 失败
- 51822 SDK12.3 fstorage的使用
- FLASH的读写
- flash的读写擦除
- flash 的读写
- flash-W25Q32BV的读写
- FLASH的读写
- STR710的内部Flash读写
- 实现STM32 Flash的读写
- DM642对FLASH的读写
- flash的读写和擦除
- 第十二节 Flash的读写
- nand flash的读写操作
- nand flash 的读写 操作
- ESP8266读写flash的实现
- nrf51822 --- flash(操作单片机自带)
- SpringBoot 集成redis和redisTemplate
- freemaker学习笔记
- 深入JAVA连接池
- Java 字节码 指令集 汇编
- 1、java多线程--生产者和消费者模拟
- nrf51822 SDK12.3.0的flash读写
- PHP 单点登录实现方案
- MFC实现Flash动画播放
- 属性动画图片点击弹出
- git修改历史提交信息commit message
- 利用QT实现截屏的四种方法
- display:inline、block、inline-block的区别
- AJAX
- uml静态结构