【问题标题】:How would I write to memory?我将如何写入内存?
【发布时间】:2025-11-26 02:00:02
【问题描述】:

我正在尝试为 RAM 编写一个简单的测试,以检查嵌入式设备上内存的基本完整性。这就是我希望能够做到的:

基本上写出某些模式:“10101010101010”到内存块,然后写入“01010101010”,然后重新写入第一个并测试模式是否写入正确。

我正在尝试用 C 编写这个程序。我想知道如何编写这个模式。我希望能够打开和关闭 RAM 存储单元中的某些位。

我会不会分配一块内存然后写一些类似的东西

uint32 pattern = 0xaaaaaaaa;
uint32 * mem_loc = malloc some memory;
int i = 0;
int offset = 1; 
uint32 * location = &mem_loc;

while ((&mem_loc)++ && (!i))  {
   &mem_loc = pattern;
   if (!(&(mem_loc+offet))) { 
      mem_loc = location;
      pattern = 0x55555555;
      i++;
   }
}

//Check to see if values written are consistent

上面的代码行得通吗?将十六进制模式写入内存会打开模式中的位吗?

我知道上面的代码被严重破坏了,但我只是想知道用正确的逻辑做类似的事情是否会达到预期的结果。

谢谢

【问题讨论】:

  • 谷歌“walking one”和“walking zeroes”内存测试算法
  • 您概述的总体思路应该可行。您拥有的代码甚至还没有接近。举个例子,我不确定!int 应该是什么意思,但我很确定没有正常运行的编译器会接受它。
  • 信息不足 - 你的处理器有缓存吗?你的操作系统怎么样——它有虚拟内存系统吗?你关心你写的地址吗?除此之外,您的代码示例没有意义。 !int 是什么?使用malloc() 似乎表明您的代码是从 RAM 运行的——这不是表明它的“基本完整性”没问题吗?
  • 你的代码看起来很奇怪......为什么使用 &mem_loc ?它是一个常量(mem_loc 地址),它永远不会改变,它不像 mem_lot VALUE。而当你想写入内存时,你必须使用 *mem_loc=pattern 来代替。 (!int) 也是错误的。
  • 抱歉,int 应该是 i。

标签: c testing memory embedded ram


【解决方案1】:

你有鸡和蛋的问题。为了让足够的代码运行来执行 malloc 甚至使用 C 代码,你已经有了工作内存。

您需要定义您的问题。例如,这是设计验证还是生产测试?您是在测试内存芯片本身还是电路板。通常,您会购买具有某些供应商定义质量的工作/测试芯片(内存)或内存芯片。您的测试通常是生产测试,即制造焊点。数据线、地址线、控制线。

先有鸡还是先有蛋的问题是您想在嵌入式处理器上运行软件,该软件需要在某处运行的代码,这意味着内存(可能只是闪存,不需要任何或最少)。理想的情况是要么完全用完 rom,只使用处理器资源,要么只使用内部芯片资源,没有外部 ram,这样外部 ram 就可以被完全测试。每个地址行等。否则,您需要提出一个方案或声明不测试的内存块。

或者采取多阶段的方法,rom引导代码可以快速检查一小部分ram而不用它来运行。然后将主测试程序复制到那一小块内存中并在其中运行。然后以更大的代码灵活性进行主内存测试。例如,可以使用 C 代替汇编程序。例如,您可以进行预测试、超级简单测试、25% 的内存,然后将测试复制到那里,测试其他 75%,然后将程序移动到内存空间中的另一个 25% 并在第一个上进行繁重的测试25% 未通过全面测试。

测试类型,您需要了解故障,您可能需要特别测试焊点和印刷电路板走线。所以你可以有开放的连接,所以你想让每个引脚成为一个和一个零,你也可以有短路,一和零覆盖,你可能有“友好的位”,相邻的引脚可能彼此短路所以你想让每对信号彼此不同。

人们通常会进行全 1、全 0、5 和 As 之类的测试。然后棋盘测试一个内存位置有 5s 而下一个有 As。对于地址线测试,您需要使用非 2 的幂,或者更好的是,内存中的每个内存位置都有不同的值,例如 32 位字,每个字都有自己的地址。

作为一个快速测试,我在几个测试中涵盖了大部分内容,如果您使用伪随机化器,像 lfsr 这样可重复的东西,使用随机化器填充所有内存,重新播种,返回并查看。然后再次通过并填充反转值,重新播种并验证反转值。你得到地址位,每条数据线但不是所有的邻居都被检查。重新播种并开始所有这些都可以通过移动随机模式来解决。有时只是使用随机测试作为地址测试,而传统的 0 5 As、3s、Cs、6s、9s 等。

就您指向被测内存的指针而言,您不只是 malloc,您需要知道物理地址并处理转换(如果有),以便如果/当您在物理地址中通信时出现问题。你也知道和控制有多少内存。通常我会用 C 编写基于处理器的测试,但不会使用任何 C 库调用(如 malloc 或 printf 或类似的东西)。

【讨论】:

  • 谢谢!然而,此时设备出现了足够多的错误,有时将模式写入“特定”位置并读取它会得到不一致的结果。
【解决方案2】:

呼应@Martin 的回答:您不想使用标准库调用来提供要测试的内存。

您的嵌入式工具链应该能够生成应用程序的内存映射。 您需要确定要测试的内存段,并从映射文件中提取它们的起始地址。

测试循环可能类似于:

 const int* AddressToTest = MEM_SEGMENT;
 const int* SegLength     = SEGMENT_LENGTH;
 volatile int* mem;
 for (mem = AddressToTest; mem < AddressToTest + SegLength; mem++)
 {
    *mem = PATTERN;
    if (*mem != PATTERN) {report("Read-Write Failure at %x",mem);}
 }
 //-or- you could separate the write and verify into 2 separate loops.

这里最大的问题是您无法测试您正在运行的细分市场,因此您需要仔细计划。嵌入式工具应该有某种链接器选项文件(和/或编译器#pragmas)来控制哪些代码使用哪些内存。因此,您需要将测试代码设置为在与被测内存不同的地方运行。

【讨论】:

【解决方案3】:

您要使用new 吗?
如果您正在尝试测试嵌入式系统内存的特定区域,您不想直接设置该地址而不是依赖new 给您的任何东西吗?

如果这个 嵌入式 系统真的是 linux 或 Windows 嵌入式或其他一些复杂的操作系统,那么它可能更复杂,您可能需要考虑不同进程、缓存、乐观分配的内存地址空间。

【讨论】: