我将在双核ARM Cortex-A9 CPU上运行一个操作系统(一个核心运行Linux,另一个核心没有操作系统)。
在无操作系统方面,我们向DDR内存写入64位double
,然后Linux端读取它。
由于CPU具有到DDR的32位总线,因此该值在两个总线周期内传输,这意味着如果写入和读取在总线上混合,则该值可能会被破坏。
我能做些什么才能让它以安全的方式运作?
答案 0 :(得分:5)
您没有准确说明您的订购要求是什么或者您打算如何发出变更信号 - 所以我只是按照说明回答问题:
如果在64位对齐位置执行LDREXD / STREXD指令,则保证它们是单拷贝原子(如果位置不是,则它们会中止)。如果你正在做一些无锁的事情,这可能对你有益。如果没有,只需使用互斥锁实现它。
当然,只要满足以下任一条件,LDREXD / STREXD才能正常工作:
Linux和您的其他软件都启用了缓存,两个cpus都设置了“SMP”位,并且都将共享区域映射为可写回写的。
Linux和您的其他软件都将共享区域视为未缓存,并且您的SoC为内存设备实现全局监视器。
答案 1 :(得分:2)
你的问题不够明确,但让我们试一试。
如果对于您来说非常重要的是,无任何部分在读取数据时始终会看到一致的值,您只需要执行原子操作。如果你正在使用gcc或类似的,那么有内置函数(例如__sync_val_compare_and_swap
)来实现这种操作。如果没有,这可以用几行汇编程序来实现,你很容易找到它的参考。 (但要注意这个特定的处理器,这不仅仅是一条指令。)
如果你想要某种信号表明Linux方已经编写了这个值,那么最简单的方法就是实现你自己的锁结构。由于您没有一侧的操作系统,因此您必须实施繁忙的等待。这可以通过原子操作再次完成,gcc builtin __sync_lock_test_and_set
将是学习如何实现这一目标的良好起点。