为什么嵌入式系统上的寄存器需要 Read-Modify-Write?

本文介绍了为什么嵌入式系统上的寄存器需要 Read-Modify-Write?的处理方法,对大家解决问题具有一定的参考价值

问题描述

我正在阅读 http://Embeddedgurus.com/embedded-bridge/2010/03/different-bit-types-in-different-registers/,上面写着:

I was reading http://embeddedgurus.com/embedded-bridge/2010/03/different-bit-types-in-different-registers/, which said:

使用读/写位,固件在需要时设置和清除位.它通常首先读取寄存器,修改所需的位,然后将修改后的值写回

With read/write bits, firmware sets and clears bits when needed. It typically first reads the register, modifies the desired bit, then writes the modified value back out

我在维护一些由老盐嵌入人员在这里编写的生产代码时遇到了这个结构.我不明白为什么这是必要的.

and I have run into that consrtuct while maintaining some production code coded by old salt embedded guys here. I don't understand why this is necessary.

当我想设置/清除一点时,我总是使用位掩码或/nand.在我看来,这解决了任何线程安全问题,因为我假设设置(通过赋值或使用掩码进行 oring)寄存器只需要一个周期.另一方面,如果你先读取寄存器,然后修改,然后写入,读取和写入之间发生的中断可能会导致将旧值写入寄存器.

When I want to set/clear a bit, I always just or/nand with a bitmask. To my mind, this solves any threadsafe problems, since I assume setting (either by assignment or oring with a mask) a register only takes one cycle. On the other hand, if you first read the register, then modify, then write, an interrupt happening between the read and write may result in writing an old value to the register.

那么为什么要读-修改-写呢?还需要吗?

So why read-modify-write? Is it still necessary?

推荐答案

这在一定程度上取决于特定嵌入式设备的架构.我将给出三个涵盖常见情况的示例.然而,它的基本要点是,CPU 内核基本上不能直接对 I/O 设备的寄存器进行操作,只能以字节甚至字的方式读取和写入它们.

This depends somewhat on the architecture of your particular embedded device. I'll give three examples that cover the common cases. The basic gist of it, however, is that fundamentally the CPU core cannot operate directly on the I/O devices' registers, except to read and write them in a byte- or even word-wise fashion.

1) 68HC08 系列,8 位独立微控制器.

1) 68HC08 series, an 8-bit self-contained microcontroller.

这包括位设置"和位清除"指令.这些,如果您仔细阅读手册,实际上在内部会自行执行读取-修改-写入循环.它们确实具有原子操作的优势,因为作为单条指令它们不能被中断.

This includes a "bit set" and a "bit clear" instruction. These, if you read the manual carefully, actually internally perform a read-modify-write cycle by themselves. They do have the advantage of being atomic operations, since as single instructions they cannot be interrupted.

您还会注意到,它们比单独的读取或写入指令花费的时间更长,但比使用三个指令的时间要少(见下文).

You will also notice that they take longer than individual read or write instructions, but less time than using three instructions for the job (see below).

2) ARM 或 PowerPC,传统的 32 位 RISC CPU(也经常出现在高端微控制器中).

2) ARM or PowerPC, conventional 32-bit RISC CPUs (often found in high-end microcontrollers too).

这些不包括任何指令,这些指令既可以访问内存又可以一次执行计算(和/或).如果你用 C 写:

These do not include any instructions which can both access memory and perform a computation (the and/or) at once. If you write in C:

*register |= 0x40;

它变成以下程序集(对于这个 PowerPC 示例,r8 包含寄存器地址):

it turns into the folowing assembly (for this PowerPC example, r8 contains the register address):

LBZ r4,r8
ORI r4,r4,#0x40
STB r4,r8

因为这是多条指令,它不是原子的,它可以被中断.使其成为原子甚至 SMP 安全超出了此答案的范围 - 有特殊的说明和技术.

Because this is multiple instructions, it is NOT atomic, and it can be interrupted. Making it atomic or even SMP-safe is beyond the scope of this answer - there are special instructions and techniques for it.

3) IA32 (x86) 和 AMD64.为什么要将这些用于嵌入式",我无法理解,但它们是其他两个示例之间的中途之家.

3) IA32 (x86) and AMD64. Why you would use these for "embedded" is beyond me, but they are a half-way house between the other two examples.

我忘记了 x86 上是否有单指令内存位设置和位清除.如果没有,请参阅上面的 RISC 部分,它只需要两条指令而不是三条,因为 x86 可以在一条指令中加载和修改.

I forget whether there is a single-instruction in-memory bit-set and bit-clear on x86. If not, then see the RISC section above, it just takes only two instructions instead of three because x86 can load and modify in one instruction.

假设有这样的指令,它们需要在内部加载和存储寄存器以及修改它.现代版本会在内部明确地将指令分解为三个类似 RISC 的操作.

Assuming there are such instructions, they also need to internally load and store the register as well as modifying it. Modern versions will explcitly break the instruction into the three RISC-like operations internally.

奇怪的是,x86(与 HC08 不同)可以在内存总线上由总线主控中断,而不仅仅是传统的 CPU 中断.因此,您可以手动将 LOCK 前缀添加到需要执行多个内存周期才能完成的指令,如本例所示.不过,你不会从纯 C 中得到这个.

The oddity is that x86 (unlike the HC08) can be interrupted on the memory bus in mid-transaction by a bus master, not just by a conventional CPU interrupt. So you can manually add a LOCK prefix to an instruction that needs to do multiple memory cycles to complete, as in this case. You won't get this from plain C though.

这篇关于为什么嵌入式系统上的寄存器需要 Read-Modify-Write?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1127

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1032

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this->id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:775

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this->id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:866

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:903

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:848

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:834

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:809

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1620

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1264