Подтвердить что ты не робот

8-битное перечисление, в C

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

Мне нужно сохранить прозрачность между именем команды и ее значением. Чтобы избежать необходимости переводить 8-разрядный номер, полученный в последовательном порядке в любой тип.

Я хотел бы использовать Enumerations, чтобы иметь дело с ними в моем коде. Только перечисление соответствует а на этой платформе 16-битным целым числом.

Платформа - это микроконтроллер AVR ATmega169V, на демо-панель Butterfly. Это 8-битная система с ограниченной поддержкой 16-разрядных операций. Это не быстрая система и имеет около 1 КБ ОЗУ. В нем нет предметов роскоши, таких как файловый ввод-вывод или операционные системы.

Итак, любые предложения относительно того, какой тип я должен использовать для хранения 8-битных команд?
Там должно быть что-то лучше, чем массивный заголовок #defines.

4b9b3361

Ответ 1

gcc -fshort-enums может быть полезно:

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

Фактически здесь страница с большим количеством релевантной информации. Надеюсь, вы столкнулись с множеством переключателей GCC, которых вы никогда не знали.;)

Ответ 2

Вы пытаетесь решить проблему, которая не существует.

Ваш вопрос помечен C. В языках перечисления типа C в контексте значения полностью совместимы с целыми типами и ведут себя точно так же, как и другие интегральные типы. При использовании в выражениях они подвергаются точно таким же интегральным акциям, как и другие интегральные типы. Если учесть это, вы должны понимать, что если вы хотите хранить значения, описанные константами перечисления в 8-битном интегральном типе, все, что вам нужно сделать, это выбрать подходящий общий 8-битный интегральный тип (скажем int8_t) и использовать его вместо типа перечисления. Вы ничего не потеряете, сохранив ваши постоянные значения enum в объекте типа int8_t (в отличие от объекта, явно объявленного с типом перечисления).

Описанная вами проблема будет существовать в С++, где типы перечислений разделяются намного дальше от других интегральных типов. В С++ использование интегрального типа вместо типа enum для сохранения памяти сложнее (хотя возможно). Но не в C, где это не требует никаких дополнительных усилий.

Ответ 3

Я не понимаю, почему перечисление не будет работать. Сравнение с и перечислением из перечисления должно отлично работать с расширением по умолчанию. Просто будьте осторожны, чтобы ваши 8-битные значения были правильно подписаны (я бы подумал, что вам понадобится беззнаковое расширение).

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

Ответ 4

Компилятор Microsoft C позволяет вам делать что-то подобное, но это расширение (стандартное в С++ 0x):

enum Foo : unsigned char {
    blah = 0,
    blargh = 1
};

Поскольку вы отметили GCC, я не совсем уверен, возможно ли то же самое, но GCC может иметь расширение в режиме gnu99 или что-то в этом роде. Дайте ему вихрь.

Ответ 5

Я бы порекомендовал остаться в enum в любом случае по следующим причинам:

  • Это решение позволяет сопоставлять значения команд непосредственно с тем, что ожидает ваш последовательный протокол.
  • Если вы действительно используете 16-битную архитектуру, не так много преимуществ для перехода на 8-битный тип. Подумайте о других аспектах, кроме 1 байт памяти.
  • В некоторых компиляторах я использовал фактический размер перечисления, используя минимальное количество бит (перечисления, которые могут быть помещены в байты, используются только байты, затем 16 бит, затем 32).

Сначала вам не нужно заботиться о ширине реального типа. Только если вам действительно нужен эффективный способ хранения, вы должны использовать флаги компилятора, такие как -fshort-enums в компиляторе GNU, но я не рекомендую их, если вы им действительно не нужны.

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

Ответ 6

Ответ, который подходит для компилятора ARC (Цитируется в DesignWare MetaWare C/С++ Programmers Guide для ARC, раздел 11.2.9.2)

Размер перечислений Размер типа перечисления зависит от статуса переключения * Long_enums *.

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

■ Если переключатель * Long_enums * включен, перечислимое перечисление четыре байта (соответствующие соглашению AT & T Portable C Compiler).