3

我将在双核 ARM Cortex-A9 CPU 上运行一个操作系统(一个内核运行 Linux,另一个没有操作系统)。

在无操作系统端,我们将 64 位写入doubleDDR 内存,然后 Linux 端读取它。

因为 CPU 有一条到 DDR 的 32 位总线,所以该值在两个总线周期内传输,这意味着如果在总线上混合写入和读取,则该值可能会被破坏。

我该怎么做才能使其以安全的方式工作?

4

2 回答 2

5

您没有具体说明您的订购要求是什么或您打算如何表示更改 - 所以我将简单地回答所述问题:

如果在 64 位对齐的位置上执行 LDREXD/STREXD 指令,则保证是单副本原子的(如果该位置不是,它们会中止)。如果您正在做一些无锁的事情,那可能对您有好处。如果没有,只需使用互斥锁实现它。

当然,LDREXD/STREXD 仅在以下任一情况为真时才能正常工作:

  • Linux 和您的其他软件都启用了缓存,两个 cpu 都设置了“SMP”位,并且都将共享区域映射为可回写缓存。

  • Linux 和您的其他软件都将共享区域视为未缓存,并且您的 SoC 实现了内存设备的全局监视器

于 2013-05-23T10:35:45.727 回答
2

你的问题不够清楚,但让我们试一试。

如果no-Os 部分在读取数据时始终看到一致的值对您来说很重要,那么您只需要执行原子操作即可。如果您将使用 gcc 或类似的工具,那么有内置函数(例如__sync_val_compare_and_swap)可以实现这种操作。如果没有,这可以通过几行汇编程序来实现,您很容易找到相关的参考资料。(但在这个特定的处理器上要小心,这不仅仅是一条指令。)

如果你想有某种信号表明 Linux 端已经写入了值,最简单的方法是实现你自己的锁结构。由于您在一侧没有操作系统,因此您将不得不实施繁忙的等待。这同样可以通过原子操作来完成,gcc 内置函数 __sync_lock_test_and_set将是学习如何实现这一点的一个很好的起点。

于 2013-05-23T09:19:50.320 回答