当前位置: 首页 > news >正文

个人网站作品推荐小蚁人网站建设

个人网站作品,推荐小蚁人网站建设,简历制作免费模板网站,计算机培训班哪些好目录 0. 个人简介 授权须知1. Flash 和 EEROM 基本情况2. 场景要求3. 软件设计思路4. 代码展示4.1 flash.h4.2 flash.c 0. 个人简介 授权须知 #x1f4cb; 个人简介 #x1f496; 作者简介#xff1a;大家好#xff0c;我是喜欢记录零碎知识点的菜鸟… 目录 0. 个人简介 授权须知1. Flash 和 EEROM 基本情况2. 场景要求3. 软件设计思路4. 代码展示4.1 flash.h4.2 flash.c 0. 个人简介 授权须知 个人简介 作者简介大家好我是喜欢记录零碎知识点的菜鸟打工人。 个人主页欢迎访问我的博客主页… https://blog.csdn.net/qq_39217004?spm1010.2135.3001.5343 支持我点赞收藏⭐️留言 系列专栏嵌入式Linux开发 格言写文档啊不是写文章重要的还是直白 转载文章禁止声明原创不允许直接二次转载转载请根据原文链接联系作者 若无需改版在文首清楚标注作者及来源/原文链接并删除【原创声明】即可直接转载。 但对于未注明转载来源/原文链接的文章我将保留追述的权利。 https://blog.csdn.net/qq_39217004?spm1010.2135.3001.5343 作者积跬步、至千里 场景分析 在嵌入式开发中EEPROM 因其非易失性存储特性常用于保存配置参数等数据。EEPROM 的擦写次数一般在10万次左右。 单片机一般通过 IIC 接口外加一个 EEROM 存储芯片 但是有些小项目为了节省成本或者以前维护的一些项目只能把 flash 划分出一段空间当数据存储空间来用。 这样的缺点是 升级固件时如果固件变大了一旦覆盖了原来划分的数据存储区域那数据就没了。Flash 的擦写次数一般都是在 1万次 左右这个次数可是远小于 EEROM 1万次在很多场景下并不够。 因此本文参考 老板说单片机Flash模拟EEPROM16字节算法轮询存储给我做到100万次的存储次数 的思路通过软件设计提高flash的擦写次数。 1. Flash 和 EEROM 基本情况 独立的EEPROM芯片是可以直接写字节的即使覆盖写也无须擦除单片机的FLASH 写入数据之前必须按页来擦除先擦除再写入 2. 场景要求 程序一共有15个字节的内容需要断电保存每改变其中一个字节就需要保存一次做到100万次的一个存储次数。 单片机的 Flash 一共是 128KB 从0x08000000----0x0801FFFF一共64页每页2KB。 3. 软件设计思路 以每个 page 2KB 的大小为一个节点假设数据要存储到【最后一个page】设计思路如下 从第一个 page 开始写入第一次写前16字节然后更新写入地址索引到第16个字节第二次从 17-31 字节写入然后更新写入地址索引到第32个字节依次循环 这样来算每个 page 可以存储 2048/16 128 次写满一页擦除一次理论上存储次数能达到128 × 1万次/页 128万次。 4. 代码展示 4.1 flash.h #ifndef FLASH__H #define FLASH__H#include stm32g0xx_hal.h #include string.h// FLASH配置 #define FLASH_BASE_ADDR 0x0801F800 // FLASH最后一页起始地址 (128KB - 2KB) #define PAGE_SIZE 2048 // STM32G071页面大小为2KB #define STATE_SIZE 16 // 结构体大小填充到24字节typedef struct {unsigned int color; // 颜色unsigned int seconds; // 秒数unsigned char mode; // 模式unsigned char number; // 序号unsigned char padinng[5]; // 预留5unsigned char checksum; // 1字节校验和 }dataState;extern dataState old_state; extern dataState current_state; void printState(dataState *state); HAL_StatusTypeDef flash_program(unsigned int addr, unsigned char* data, unsigned int len); void read_flash(unsigned int addr, unsigned char* data, unsigned int len); void init_flash_addr(void); void save_state(dataState* state); void get_state(dataState* state); void update_state(dataState* state);#endif4.2 flash.c // 初始化查找最新有效数据 void init_flash_addr(void) {dataState temp_state;uint32_t addr FLASH_BASE_ADDR;uint32_t last_valid_addr FLASH_BASE_ADDR;int found_valid_data 0;while (addr FLASH_BASE_ADDR PAGE_SIZE) {read_flash(addr, (uint8_t*)temp_state, STATE_SIZE);// 检查是否全0xFFuint8_t all_ff[STATE_SIZE];memset(all_ff, 0xFF, STATE_SIZE);int is_all_ff (memcmp(temp_state, all_ff, STATE_SIZE) 0);if (!is_all_ff temp_state.checksum calculate_checksum(temp_state)) {last_valid_addr addr;found_valid_data 1;memcpy(current_state, temp_state, STATE_SIZE); } else { break;}addr STATE_SIZE;}flash_addr last_valid_addr (found_valid_data ? STATE_SIZE : 0);if(found_valid_data)printf(init first,found valid data,last_valid_addr:%X\r\n,last_valid_addr);elseprintf(init first,it is all ff,it is the first data\r\n);if (flash_addr FLASH_BASE_ADDR PAGE_SIZE) {printf(init erase page 2KB\r\n);erase_page(FLASH_BASE_ADDR);flash_addr FLASH_BASE_ADDR;}if (!found_valid_data) {printf(not found valid data\r\n);current_state.color 100;current_state.seconds 200;current_state.mode 1;current_state.number 1;current_state.checksum calculate_checksum(current_state);__disable_irq(); flash_program(FLASH_BASE_ADDR, (uint8_t*)current_state, STATE_SIZE);__enable_irq(); flash_addr FLASH_BASE_ADDR STATE_SIZE; }printState(current_state); }第一步先从第一个地址读取第一个16字节然后判断是不是全部等于0xFF如果第一次是就证明是第一次下一步flash_addr就不需要增加STATE_SIZE写入地址索引就是FLASH_BASE_ADDR。第二步如果不全是0xFF并且校验字节通过证明这是一组有效数据我们先将此数据更新到current_state但是这里还不能证明是最后一组有效数据因为最后一组有效数据才是我们要找到的数据。继续检查下一组数据直到检查到一组数据是全0xFF证明上一组数据就是最后一组有效数据就跳出此时我们也就找到了最后一组有效数据的起始地址。此地址增加STATE_SIZE就是最新可以存储数据的地址索引了。如果没找到有效数据证明是第一次就写入默认数值并保存更新索引。 保存数据save_state函数 oid save_state(dataState* state) {dataState last_state;if (flash_addr FLASH_BASE_ADDR) {read_flash(flash_addr - STATE_SIZE, (uint8_t*)last_state, STATE_SIZE);if (memcmp(last_state, state, STATE_SIZE) 0) {printf(数据没有变化直接返回);return; }}__disable_irq(); if (flash_addr STATE_SIZE FLASH_BASE_ADDR PAGE_SIZE) {printf(erase page 2KB\r\n);erase_page(FLASH_BASE_ADDR);flash_addr FLASH_BASE_ADDR; }state-checksum calculate_checksum(state);flash_program(flash_addr, (uint8_t*)state, STATE_SIZE);flash_addr STATE_SIZE; __enable_irq(); }函数就比较简单了首先将要保存的数据与最新存储的数据做对比如果没变化就不操作如果地址超出范围了就先擦除整个页更新写索引到FLASH_BASE_ADDR接着保存数据到当下最新写地址索引即可。
http://www.pierceye.com/news/168093/

相关文章:

  • 网站视频插件代码如何创建自己的软件
  • 如何免费建造网站电商网站建设哪家好
  • ps做网站首页设计教程郑州seo优化外包热狗网
  • 给网站增加功能怎么做360搜索关键词优化软件
  • 如何做公司网站空间南昌做网站的公司哪个比较好的
  • 美容网站开发网络营销的功能有哪些
  • 推广自己的网站需要怎么做做政协网站的目的是什么
  • 综合性电子商务网站有哪些商城系统软件开发
  • 网站服务器解决方案企业门户网站管理要求
  • 南京网站开发南京乐识专注岳阳网站建设网站
  • 做一直播网站要多少钱淘宝客如何建设推广网站
  • 网站模板内容怎么添加图片不显示菏泽做网站
  • 个人网站备案条件盐城做网站哪家好
  • 小型网站开发教程wordpress自适应小说
  • 来宾网站制作公司网站提交至google
  • 唐山网站建设怎么样专业的个人网站建设哪家
  • 成品网站w灬源码在线看重庆网站制作设计
  • 有没有在家做的兼职网站网站模板如何删除
  • 建站公司用的开源框架家纺网站模板
  • 做情网站甘肃省城乡城乡建设厅网站
  • 开发一个网站做公司内部用一个网站能用asp c
  • 设计师服务平台鱼巴士有哪些网站阜宁网站设计
  • 企业网站开发所需要的模块郴州网警
  • 案例网站网页设计实训报告结束语
  • 重庆网上房地产网站龙岩属于哪里
  • 高水平的番禺网站建设在天猫开店需要什么条件与费用
  • 给网站加个地图的代码wordpress 视频预览
  • 邯郸去哪做网站改版短网址生成器在线
  • 广州手机模板建站互联网公司薪资待遇
  • 网站建设的作用有哪些方面wordpress 首页描述