在 Atmel SAMD21J18A 微控制器中查找剩余的闪存大小?

Posted

技术标签:

【中文标题】在 Atmel SAMD21J18A 微控制器中查找剩余的闪存大小?【英文标题】:Find left over flash memory size in Atmel SAMD21J18A microcontroller? 【发布时间】:2017-05-01 16:39:31 【问题描述】:

我正在做一个 IOT 项目,我正在使用 Atmel SAMD21J18A 芯片将数据发送到远程服务器。我想包含一个功能,我可以在运行时发送使用过的闪存和剩余的闪存大小。有没有保存这些数据的寄存器?我查看了数据表,但找不到答案。

【问题讨论】:

不是寄存器可以保存的东西,通常闪存消耗由工具链定义,二进制文件有多大,因此您可以使用链接器脚本获取二进制文件的整体大小,四舍五入到该部分的闪存擦除块大小,并且应该能够检测到该部分或编译该部分以知道该部分有多少闪存,减去这就是空闲的。 或采取另一种方法,从顶部开始检查内存,直到找到数据,然后向上舍入到闪存擦除边界。 没有使用和空闲的闪存,它一直都在使用,数据可能是擦除值但它是一个值它是每个位两种状态(一个或零) 不是三个(一、零、免费)。 @old_timer 非常感谢。 RAM使用情况如何?有没有办法确定? 除了堆栈是的,假设你不使用 malloc,我真的希望你不要。如果您保持某种传统(仅使用静态分配的变量,而不要只是徘徊在 ram 中),那么您可以在编译时告诉您使用 .data 和 .bss 使用了多少 ram。但是堆栈是动态的,您需要进行分析,无论如何您都应该这样做以确保。如果没有别的,你会使用 valgrind 类型的方法,但这会添加使用资源并且不是 100% 的代码,因为它没有涵盖所有可能的路径。 【参考方案1】:

应该可以修改链接器脚本以创建一个符号,其值等于链接器分配的闪存的末尾(如果它还没有)。然后,您可以在代码中将该符号声明为 extern 并使用其值。例如:

extern uint32_t END_OF_LINK_ROM ; // Linker generated symbol

如何生成链接器符号本身将是特定于工具链的。如果您的链接器没有在 ROM 的开头定位代码,您可能还需要一个符号作为开头。您需要查阅您的链接器文档并考虑您的内存映射。

【讨论】:

如何计算剩余的 RAM?我的 Atmel 芯片上运行了一个客户端服务器 (IOT) 代码。服务器会定期请求剩余的 RAM,我需要编写一个逻辑来报告它。我没有使用任何堆(没有动态分配)。我的数据+bss 为 13160 字节(这是编译器给我的),RAM 为 32000 字节。 我想找到运行时使用的堆栈数量,以便将其添加到 13160 并报告给服务器。例如,如果我从函数 A 调用 freeMem,那么在该函数 + 13160 之前使用的堆栈数量就是答案。如果从函数 B 调用,答案是在该函数 + 13160 之前使用的堆栈数量。我希望在服务器端收到剩余内存值时看到它的变化。有没有办法找到大约使用的堆栈?像堆栈的开始 - 堆栈指针? 如果你发布一个新问题,你会得到一个更好的答案; SO 不是讨论论坛。堆栈是由链接器静态分配的,就像任何其他数据结构一样。瞬时堆栈级别可以由堆栈指针的值确定(记住堆栈通常从高内存地址向下增长到低内存地址)。如果您想估计峰值堆栈使用量(也许更有用),那么您需要使用水印值填充堆栈并从堆栈顶部向下扫描以找到高潮标记。 是的。我一发表这条评论就意识到了这一点。我也发布了一个新问题。无论如何,非常感谢你。

以上是关于在 Atmel SAMD21J18A 微控制器中查找剩余的闪存大小?的主要内容,如果未能解决你的问题,请参考以下文章

Atmel 微控制器:UBRR0H 和 UBRRnH 的区别

((Port *)0x41004400UL) 在这里是啥意思?

Linux / Windows Arduino IDE 上的 avr-gcc Atmel AVR 微控制器

Atmel SAMD21 DMA 中止问题

如何延迟 avr 微控制器的组装?

使用 AVRDUDE 通过 CAN 对 Atmel 芯片 (AT90CAN128) 进行编程