Вы могли бы использовать битовые поля, несмотря на то, что говорили здесь все противники страха. Вам просто нужно знать, как компилятор (ы) и системные ABI (ы), с которыми вы собираетесь работать в своем коде, определяют аспекты «определенных реализацией» битовых полей. Не пугайтесь педантов, которые выделяют такие слова, как «реализация определена» жирным шрифтом.
Однако то, что другие пока упускают из виду, - это различные аспекты того, как аппаратные устройства с отображением памяти могут вести себя, которые могут быть нелогичными при работе с языком более высокого уровня, таким как C, и функциями оптимизации, которые предлагают такие языки. , Например, каждое чтение или запись аппаратного регистра может иногда иметь побочные эффекты, даже если биты не изменяются при записи. Между тем оптимизатор может затруднить определение того, когда сгенерированный код фактически читает или записывает по адресу регистра, и даже когда объект C, описывающий регистр, тщательно квалифицирован как volatile
, требуется большая осторожность, чтобы контролировать, когда я / O происходит.
Возможно, вам потребуется использовать определенный метод, определенный вашим компилятором и системой, чтобы правильно манипулировать отображаемыми в памяти аппаратными устройствами. Это касается многих встраиваемых систем. В некоторых случаях поставщики компиляторов и систем действительно будут использовать битовые поля, как в некоторых случаях использует Linux. Я бы предложил сначала прочитать руководство по вашему компилятору.
Таблица описания битов, которую вы цитируете, по-видимому, предназначена для управляющего регистра ядра контроллера Intel Avalon DMA. Столбец «чтение / запись / очистка» дает подсказку о том, как ведет себя конкретный бит, когда он читается или записывается. Регистр состояния для этого устройства имеет пример бита, в котором запись нуля приведет к сбросу значения бита, но он может не считывать то же значение, которое было записано - т.е. запись в регистр может иметь побочный эффект в устройстве, в зависимости от значения бита DONE. Интересно, что они документируют бит SOFTWARERESET как «RW», но затем описывают процедуру как запись 1 в него дважды для запуска сброса, а затем они также предупреждают Выполнение сброса программного обеспечения DMA, когда активна передача DMA, может привести к постоянная блокировка шины (до следующего сброса системы). Поэтому бит SOFTWARERESET не следует записывать, кроме как в крайнем случае. Управление сбросом в C потребует некоторого тщательного кодирования независимо от того, как вы описываете регистр.
Что касается стандартов, то в ИСО / МЭК был подготовлен «технический отчет», известный как «ISO / IEC TR 18037» , с подзаголовком «Расширения для поддержки встроенных процессоров», В нем обсуждается ряд вопросов, связанных с использованием C для управления аппаратной адресацией и вводом-выводом устройства, и, в частности, для типов битовых регистров, которые вы упоминаете в своем вопросе, он документирует ряд макросов и методов, доступных через включаемый файл, который они Звоните <iohw.h>
. Если ваш компилятор предоставляет такой заголовочный файл, вы можете использовать эти макросы.
Доступны черновые копии TR 18037, последняя из которых TR 18037 (2007) , хотя и обеспечивает довольно сухое чтение. Однако он содержит пример реализации <iohw.h>
.
Возможно, хорошим примером реальной реализации <iohw.h>
является QNX. Документация по QNX предлагает хороший обзор (и пример, хотя я бы настоятельно рекомендовал использовать enum
s для целочисленных значений, а не макросов): QNX <iohw.h>