Почему чтение-изменение-запись необходимо для регистров во встроенных системах? - PullRequest
12 голосов
/ 31 марта 2010

Я читал http://embeddedgurus.com/embedded-bridge/2010/03/different-bit-types-in-different-registers/,, который сказал:

С битами чтения / записи, прошивка устанавливает и очищает биты при необходимости. Обычно он сначала читает регистр, модифицирует нужный бит, затем записывает измененное значение обратно

и я столкнулся с этим принципом, сохраняя при этом некоторый производственный код, закодированный здесь старыми парнями, встроенными в соль. Я не понимаю, почему это необходимо.

Когда я хочу немного установить / очистить, я всегда просто или / nand с битовой маской. На мой взгляд, это решает любые проблемы с безопасностью потоков, так как я предполагаю, что установка (либо путем присваивания, либо путем маски) регистра занимает всего один цикл. С другой стороны, если вы сначала прочитали регистр, затем изменили, а затем записали, прерывание, происходящее между чтением и записью, может привести к записи старого значения в регистр.

Так зачем читать-модифицировать-писать? Это все еще необходимо?

Ответы [ 5 ]

15 голосов
/ 31 марта 2010

Это зависит от архитектуры вашего конкретного встроенного устройства.Я приведу три примера, которые охватывают общие случаи.Основная суть этого, однако, заключается в том, что в основном ядро ​​ЦП не может работать непосредственно с регистрами устройств ввода / вывода, кроме как для чтения и записи их в байтовом или даже пословом виде.

1) Серия 68HC08, 8-разрядный автономный микроконтроллер.

Сюда входит команда «установка битов» и «очистка битов».Они, если вы внимательно прочитаете руководство, на самом деле сами выполняют цикл чтения-изменения-записи.У них есть преимущество в том, что они являются атомарными операциями, поскольку как отдельные инструкции они не могут быть прерваны.

Вы также заметите, что они занимают больше времени, чем отдельные инструкции чтения или записи, но меньше времени, чем использование трех инструкций для задания.(см. ниже).

2) ARM или PowerPC, обычные 32-разрядные RISC-процессоры (также часто встречающиеся в высокопроизводительных микроконтроллерах).

Они не включают любой инструкции, которые могут одновременно обращаться к памяти и выполнять вычисления (и / или).Если вы напишите на C:

*register |= 0x40;

, он превратится в следующую сборку (для этого примера PowerPC r8 содержит адрес регистра):

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

, потому чтоэто несколько инструкций, это не атомарный, и он может быть прерван.Сделать его атомарным или даже SMP-безопасным выходит за рамки этого ответа - для него есть специальные инструкции и методики.

3) IA32 (x86) и AMD64.Почему вы используете их для «встроенных», мне не понятно, но они на полпути между двумя другими примерами.

Я забываю, есть ли в памяти битовый набор с одной инструкцией и битясно на x86.Если нет, то смотрите раздел RISC выше, он просто принимает только две инструкции вместо трех, потому что x86 может загружать и изменять в одной инструкции.

Предполагая, что такие инструкции есть, они также нужнывнутренне загрузить и сохранить регистр, а также изменить его.Современные версии явно разбивают инструкцию на три RISC-подобные операции внутри.

Странность заключается в том, что x86 (в отличие от HC08) может прерываться на шине памяти в середине транзакции мастером шины, а не толькообычным прерыванием процессора.Таким образом, вы можете вручную добавить префикс LOCK в инструкцию, для выполнения которой необходимо выполнить несколько циклов памяти, как в этом случае.Вы не получите это из простой C, хотя.

7 голосов
/ 31 марта 2010

Дело в том, что если вы не хотите изменять другие биты в регистре, вы должны знать, что это такое, прежде чем что-то записывать. Отсюда и чтение / модий / запись. Обратите внимание, что если вы используете оператор C, например:

*pRegister |= SOME_BIT;

Несмотря на то, что на первый взгляд это может выглядеть как простая операция записи, компилятор должен выполнить чтение в первую очередь, чтобы сохранить остальные биты в значении (это обычно так, даже если вы не говорите об аппаратных регистрах) , если компилятор не может использовать другие знания о значении для оптимизации считывания).

Обратите внимание, что отображаемые в памяти аппаратные регистры обычно помечены volatile специально, так что эти оптимизации не могут быть выполнены (в противном случае многие процедуры аппаратного регистра не будут работать должным образом).

Наконец, иногда существует аппаратная поддержка регистров, которые специально устанавливают или сбрасывают биты в аппаратном обеспечении, не требуя последовательности чтения / изменения / записи. Некоторые микроконтроллеры Atmel ARM, с которыми я работал, имеют определенные регистры, которые сбрасывают или устанавливают биты аппаратно только в тех битах, которые устанавливаются при записи в регистр (оставляя любой неустановленный бит в покое). Кроме того, ARM-процессор Cortex M3 поддерживает доступ к одному биту (для чтения или записи) в памяти или в аппаратных регистрах этого посредством доступа к определенному адресному пространству с помощью метода, который они называют 'bit-banding' . Алгоритм битовой полосы выглядит на первый взгляд сложным, но на самом деле это просто простая арифметика, чтобы отобразить смещение бита в одном адресе в другой «бит-специфический» адрес.

Как бы то ни было, суть в том, что есть некоторые процессоры, в которых вы можете обойтись без серий чтения / изменения / записи, но это ни в коем случае не всегда верно.

2 голосов
/ 30 августа 2011

Современные процессоры могут устанавливать или сбрасывать биты с помощью одной команды. Однако эти инструкции нельзя одновременно устанавливать и очищать. Есть случаи, когда некоторые биты порта ввода-вывода должны все вместе меняться и не влиять на другие биты. Пока последовательность чтения-изменения-записи не может быть нарушена, проблем не возникает.

Ситуация, когда r-m-w может стать проблемой, требует трех условий.

  1. Переменная должна быть доступна глобально, например, порт ввода-вывода, регистр специальных функций или глобально определенная переменная.

  2. Глобальная переменная может быть изменена в функции, которая может быть прервана.

  3. Эта же глобальная переменная изменяется при обслуживании вытеснения.

Единственный способ разрешить множественные битовые модификации с использованием неатомарной последовательности r-m-w - это защитить последовательность команд путем отключения прерывания для подпрограммы обработки прерывания, которая также может изменять переменную или регистр. Это похоже на эксклюзивный доступ к таким ресурсам, как LCD или последовательные порты.

2 голосов
/ 02 апреля 2010

Если вам нужно изменить подмножество битов в слове, и архитектура поддерживает только чтение / запись на уровне слов, вы должны прочитать биты, которые не должны изменяться, чтобы знать, что записывать обратно, чтобы они не были изменены .

Некоторые архитектуры поддерживают доступ к памяти на уровне битов либо глобально, либо для определенных областей памяти. Но даже тогда при изменении нескольких битов чтение-изменение-запись многих приводят к меньшему количеству инструкций. В многопоточных системах необходимо следить за тем, чтобы два потока не могли одновременно выполнить это неатомарное действие над одним и тем же словом.

0 голосов
/ 31 марта 2010

Когда я хочу установить / очистить немного, я всегда просто или / nand с битовой маской.

Для некоторых регистров это достаточно хорошо. В таком случае прошивка ЦП все еще будет выполнять чтение-изменение-запись.

На мой взгляд, это решает любой потокобезопасный проблемы, так как я предполагаю установку (либо по назначению, либо по маска) регистр занимает всего один цикл.

Если вы позволите встроенному программному обеспечению процессора выполнять чтение-изменение-запись для вас, очевидно, оно будет включать в себя, по крайней мере, цикл чтения и цикл записи. Теперь большинство процессоров не будут прерывать эту инструкцию посередине, поэтому ваш поток выполнит всю эту инструкцию до того, как процессор вашего потока проверит наличие прерываний, но если вы не заблокировали шину, другие процессоры могут изменить этот же регистр. Ваша нить и другие нити все еще могут проходить друг вокруг друга.

...