ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RIOT 内部 Flash 读写实战:使用 periph/flashpage 驱动测试应用验证片内存储

RIOT 内部 Flash 读写实战:使用 periph/flashpage 驱动测试应用验证片内存储 物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载本篇技术指南以 RIOT 仓库中的 tests/periph/flashpage/README.md 为核心系统讲解如何通过该测试应用验证 MCU 内部 Flash 的flashpage外设驱动接口。读完本文你将掌握read/edit/write/dump等 shell 命令的完整操作流程理解flashpageAPI 的底层实现原理并学会如何安全地在片内 Flash 中进行读-改-写-验证操作以及断电持久性测试。测试应用是什么flashpageFlash Page是 RIOT 提供的一套低层 Flash 页接口位于 drivers/include/periph/flashpage.h其设计目标是提供一种非常简单直接的方式读写 MCU 内部 Flash该接口只支持读取、验证和写入完整的 Flash 页不支持部分partialFlash 访问因此可以实现非常精简高效的驱动实现。更细粒度的内存访问模块可以轻松地构建在该接口之上。测试应用 tests/periph/flashpage 正是用于验证这套接口在各种 MCU 上的实现是否正确。它不是一个普通功能示例而是一个手动测试应用manual test application通过 main.c 注册一组 shell 命令让用户在交互式 shell 中直接对 Flash 页执行读写操作以验证驱动的正确性。启动后程序会打印如下提示源码见 main.cROM flash read write test Please refer to the README.md for further information Flash start addr: 0x08000000 Page size: 2048 Number of pages: 256其中info命令会在启动时自动执行一次输出 Flash 起始地址、页大小和页数量等关键参数。构建与烧录测试应用通过 Makefile 定义构建规则BOARD ? iotlab-m3 include ../Makefile.periph_common FEATURES_REQUIRED periph_flashpage FEATURES_OPTIONAL periph_flashpage_in_address_space FEATURES_OPTIONAL periph_flashpage_pagewise FEATURES_OPTIONAL periph_flashpage_rwee USEMODULE od USEMODULE od_string USEMODULE shell要点说明FEATURES_REQUIRED periph_flashpage目标板必须支持flashpage外设否则构建失败periph_flashpage_in_address_space、periph_flashpage_pagewise、periph_flashpage_rwee均为可选特性根据板子能力决定是否启用对应功能如按页读写、RWWEE 支持默认目标板为iotlab-m3也可通过BOARD指定其他开发板例如make BOARDnrf52840dk flash少数 RAM 极小的板子因内存不足无法运行见 Makefile.ci 中的BOARD_INSUFFICIENT_MEMORY黑名单如nucleo-l011k4、stm32f030f4-demo。构建并烧录到开发板后通过串口连接即可进入 RIOT shell输入help查看全部命令。核心 shell 命令一览main.c 中注册的 shell 命令如下命令功能适用条件info显示 Flash 起始地址、页大小、页数量等始终可用dump page将指定页的内容以十六进制 dump 到 STDOUTpagewisedump_localdump 本地页缓冲区RAM 中的镜像pagewiseread page将指定页读入本地页缓冲区并 dumppagewisewrite page将本地页缓冲区写入指定页带验证pagewiseedit offset data向本地页缓冲区指定偏移写入数据pagewisewrite_raw addr hexdata向任意 Flash 地址写入原始字节最多 64B始终可用erase page擦除指定页始终可用test page写入 a–z 循环测试图案并验证pagewisetest_last_pagewise在最后一页上写入并验证测试图案pagewisetest_reserved_pagewise在构建期保留的 Flash 页上写入并验证in_address_spacetest_last_raw在最后一页上执行原始短写入并验证始终可用read_rwwee/write_rwwee/test_rwwee/test_last_rwwee/test_last_rwwee_rawRWWEE Flash 区域的读写与测试板支持 RWWEEdump_config_page/test_config_page查看/测试 MCU 配置页仅 sam0 系列危险操作NVMCTRL_USER标准操作流程读-改-写-验证README 给出了操作内部 Flash 的推荐流程这也是最典型的持久化数据使用方式。以下命令序列在 shell 中逐一执行第一步读取一个页到本地缓冲区read 100该命令调用flashpage_read(page, page_mem)把第 100 页完整复制到 RAM 中的本地页缓冲区page_mem然后立即dump缓冲区内容。从源码看page_mem的大小恰为一页FLASHPAGE_SIZE并带有FLASHPAGE_WRITE_BLOCK_ALIGNMENT对齐属性——某些架构如 stm32l4要求 64 位对齐见 main.c。第二步编辑本地缓冲区edit 100 Hello_RIOT在本地缓冲区偏移 100 处写入字符串Hello_RIOT。实现上就是一次memcpy(page_mem[offset], argv[2], data_len)见 main.c若offset data_len超出页大小则自动截断。编辑后再次 dump 缓冲区以确认内容。第三步写回 Flashwrite 100将本地页缓冲区写入第 100 页。注意这里使用的是flashpage_write_and_verify(page, page_mem)见 main.c即写入后立即与缓冲区逐字节比对返回FLASHPAGE_OK或FLASHPAGE_NOMATCH失败会打印error: verification for page 100 failed。第四步验证写入结果dump 100直接读取 Flash 中第 100 页的原始内容并十六进制输出。dump使用flashpage_addr(page)得到页首地址后直接按内存读取绕过了本地缓冲区因此能确认数据确实写入了 Flash。第五步断电持久性验证完成上述步骤后关闭节点电源等待片刻再重新上电再次执行dump 100此时之前写入的内容应当仍然存在。这一步骤验证了数据真正持久化到了非易失性存储中而非仅停留在 RAM。深入底层flashpage API 与页/地址换算理解上述命令背后需要掌握 drivers/include/periph/flashpage.h 中定义的 API 核心API作用flashpage_read(page, data)将指定页读入data缓冲区大小须为FLASHPAGE_SIZEflashpage_write_page(page, data)整页写入data为 NULL 时仅擦除flashpage_write(target_addr, data, len)向任意 Flash 地址写入任意字节数flashpage_erase(page)擦除指定页flashpage_verify(page, data)将页内容与data比对返回FLASHPAGE_OK/FLASHPAGE_NOMATCHflashpage_write_and_verify(page, data)writeverify的便捷封装flashpage_addr(page)页号 → 页首地址CPU_FLASH_BASE page * FLASHPAGE_SIZEflashpage_page(addr)地址 → 所属页号flashpage_size(page)返回页大小驱动还定义了几个关键宏CPU_FLASH_BASE内部 Flash 起始地址默认 0多数 MCU 在cpu_conf.h中覆盖如 STM32 为0x08000000FLASHPAGE_SIZE与FLASHPAGE_NUMOF页大小与页数量未定义会触发编译错误FLASHPAGE_WRITE_BLOCK_SIZEMCU 允许的最小写入长度FLASHPAGE_WRITE_BLOCK_ALIGNMENT写入缓冲区和目标地址必须满足的对齐要求FLASHPAGE_ERASE_STATE擦除后字节的值默认0xFF。对于页大小均匀的 MCUflashpage_addr/flashpage_page/flashpage_size由头文件中的static inline函数直接计算见 flashpage.h只有声明了PERIPH_FLASHPAGE_CUSTOM_PAGESIZES的非均匀页大小 MCU 才需要驱动提供自定义实现。一个重要的底层事实是Flash 只能从 1 写到 0要恢复为 1 必须先擦除。因此flashpage_write的原型注释明确警告调用前必须确保目标区域已被擦除见 flashpage.h。这也解释了为什么测试命令中会有独立的erase。边界检查与页号合法性所有接受页号参数的命令都经由getpage()校验见 main.cstatic int getpage(const char *str) { int page atoi(str); if ((page (int)FLASHPAGE_NUMOF) || (page 0)) { printf(error: page %i is invalid\n, page); return -1; } return page; }超出[0, FLASHPAGE_NUMOF)范围的页号会被拒绝并报错避免对非法地址的误操作。另外测试应用对某些 CPU 做了特殊处理MSP430 系CPU_CC430、CPU_MSP430FXYZ的最后一页保存着中断向量表因此TEST_LAST_AVAILABLE_PAGE被定义为FLASHPAGE_NUMOF - 2见 main.c相关测试命令会避开这一页。原始写入与擦除验证除整页操作外测试应用还提供了面向底层驱动的精细测试命令write_raw addr hexdata向任意 Flash 地址写入原始十六进制数据。该命令要求数据长度必须为偶数且不超过 64 字节缓冲区大小由FLASHPAGE_WRITE_BLOCK_SIZE决定最小为 64见 main.c数据必须为合法十六进制字符缓冲区raw_buf带有FLASHPAGE_WRITE_BLOCK_ALIGNMENT对齐属性调用的是flashpage_write((void*)addr, raw_buf, len)因此目标区域必须已擦除。erase page调用flashpage_erase(page)擦除指定页。README 特别提醒了两个附加检查项擦除验证对一个内容已知的页执行擦除随后dump确认所有字节恢复为擦除态通常为0xFF以验证擦除功能本身正确页边界验证擦除目标页的同时检查前后相邻页的内容是否保持不变——这能确认页大小定义正确且擦除操作没有殃及相邻页的数据。一键自测命令与自动化测试为方便批量验证测试应用内置了多个写入-验证一体命令test page用循环字符a到z填充整个本地缓冲区后写入并验证test_last_pagewise对最后一页MSP430 为倒数第二页执行同样的写入验证。选择最后一页是为了与具体硬件布局解耦——无论板子的 Flash 布局如何最后一页都是可用的测试目标见 main.ctest_last_raw先擦除最后一页再写入 16 字节字符串test12344321tset然后用memcmp直接比对 Flash 中的内容见 main.ctest_reserved_pagewise仅在启用periph_flashpage_in_address_space特性时可用。它通过FLASH_WRITABLE_INIT宏在构建期从.flash_writable段保留一整页 Flash见 flashpage.h写入一个运行计数器与RIOT签名每次重启计数加一可用于验证保留页在固件更新后的持久性。与之对应的还有自动化测试脚本 tests/01-run.py它会按顺序执行test_last_raw验证原始短写入通过help输出探测能力若存在test_last_pagewise则执行之若存在test_reserved_pagewise则执行之若存在test_last_rwwee则执行之。该脚本巧妙地通过help命令的输出来判断板子支持哪些可选特性从而在不同硬件上自适应地执行对应测试。RWWEE 额外 Flash 区域部分 MCU如 SAML21、SAML11具备一块独立的 RWWEERead While Write EEPROM EmulationFlash 区RIOT 通过以_rwwee结尾的一组函数提供类似访问能力其支持与否由FLASHPAGE_RWWEE_NUMOF宏决定见 flashpage.h。当板子启用该特性时测试应用会额外注册read_rwwee、write_rwwee、test_rwwee、test_last_rwwee、test_last_rwwee_raw等命令见 main.c操作方式与普通 Flash 页一致只是作用于CPU_FLASH_RWWEE_BASE起始的独立地址空间。必须牢记的安全注意事项擦除周期有限Flash 的擦除次数有限多数在 1 万次左右README 与驱动头文件均警告在循环中使用本接口可能会损坏 MCU见 flashpage.h。频繁写入会消耗 Flash 寿命测试时应避免无限循环写入。切勿覆盖程序代码若写入的页包含程序代码甚至中断向量大概率会触发 hard fault 或系统崩溃且只能通过重新烧录固件修复README 原文明确警告。测试时务必使用数据页或最后一页等安全区域。写入前必须擦除flashpage_write不会自动擦除直接对未擦除区域写入会导致数据异常。对齐要求原始写入时目标地址、数据缓冲区必须按FLASHPAGE_WRITE_BLOCK_ALIGNMENT对齐长度必须是FLASHPAGE_WRITE_BLOCK_SIZE的整数倍。低功耗注意驱动实现应确保在读写函数返回前禁用相关外设不额外消耗能量若实现会令调用线程睡眠还需注意对电源模式的阻塞见 flashpage.h。在真实项目中的应用flashpage接口并非仅存在于测试中它被 RIOT 的多个真实子系统依赖。最典型的例子是 sys/riotboot/flashwrite.c 中的固件升级流程它通过flashpage_page()将目标 slot 的起始地址换算成页号用flashpage_erase()逐页擦除再借助flashpage_write()分批写入新固件数据。这印证了 README 所述更细粒度的访问模块可以轻松构建在该接口之上——riotboot 就是在其上构建的固件更新框架。此外sys/net/gnrc/link_layer/lorawan/gnrc_lorawan.c也使用 flashpage 保存 LoRaWAN 会话上下文。这意味着掌握本测试应用的操作流程本质上就掌握了 RIOT 生态中所有 Flash 持久化能力从数据存储到 OTA 固件升级的底层基础。赞分享物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载相关推荐RIOT 中 cryptoauthlib 驱动内部测试pkg_cryptoauthlib_internal_tests实战指南RIOT 中 cryptoauthlib 驱动内部测试pkg_cryptoauthlib_internal_tests实战指南 导读 tests/pkg/c物联网嵌入式操作系统实时系统Poppins字体家族高性能几何无衬线字体的技术架构与应用实践Poppins字体家族高性能几何无衬线字体的技术架构与应用实践 Poppins是一款支持Devanagari和拉丁文字体的开源几何无衬线字体家族专为Goog物联网嵌入式操作系统实时系统RIOT 驱动实战使用 BH1750FVI 环境光传感器测试应用RIOT 驱动实战使用 BH1750FVI 环境光传感器测试应用 导读 本文围绕 RIOT 操作系统中的 tests/drivers/bh1750 测试应用物联网嵌入式操作系统实时系统上一篇【亲测免费】 Decord 全面指南视频处理利器下一篇Simple Icons 使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表