2009-11-09 3 views
21

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

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

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

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

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

+2

+1 - Хороший вопрос и разумная оптимизация. –

+0

Это 8-битная арка. –

ответ

34

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

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

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

+5

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

+4

Ха, я понял сегодня, что если я усложню через AVR studio 4 IDE, то он включен по умолчанию –

+0

Я бы хотел добавить, что при получении команды вы, вероятно, захотите убедиться, что входящее значение 8 бит действительно является действительным значением из вашего перечислить перед тем, как напечатать конвертировать и сохранить его в качестве перечисления. – ndim

3

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

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

+0

вещь, мой последовательный ввод наиболее деинити 8 бит. Я не уверен, работает ли ALU на 16 или 8 бит. Большинство сборочных консолей работают только на 8-битных байтах, менее 5, которые работают на 2 байтовых словах (ADDW, MOVW - это все, что я могу вспомнить). Только –

+0

Я проверил, это 8 бит –

+4

@oxinabox - Я все еще не уверен, что это связано с размером типа перечисления. Храните значения 8 бит в переменной 'uint8_t' (или что-то еще, что соответствует байту). Вы по-прежнему сможете сравнивать и присваивать им значения перечисления (при условии, что перечисления меньше 256). Просто не используйте тип перечисления в качестве типа переменной, если точный размер имеет важное значение для приложения. –

1

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

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

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

+0

Умм, я отметил AVR-GCC. Мне нужно найти, какие расширения он поддерживает –

+0

Меня интересует то, что вы найдете. Это был выстрел из кишки. –

+0

И кажется, что MS является единственным, поддерживающим такой синтаксис. –

0

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

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

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

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

+0

8-разрядная архитектура. Я проверил аппаратные доски, это 8 бит –

6

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

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

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

+2

@ oxinabox.ucc.asn.au: На первой странице появился поток. Я не знаю почему. О, я вижу. * Вы * отредактировали его (заменив «комментарий» на «commend», BTW :) и теперь вы обвиняете меня в некромантии? – AnT

+0

Кстати, это было неплохо, на что он ответил, поскольку это лучший ответ для всех. В C перечисление есть не что иное, как объявление констант, хранение значений не зависит от перечисления. Мои 2 цента. –

+0

В общем, вы должны ответить на вопрос в своем ответе, а не просто критиковать его. – whoKnows

0

Ответ, который имеет отношение к ARC компилятор (цитируется по DesignWare Metaware C/Руководство C++ программиста для АРК, раздел 11.2.9.2)

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

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

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

Смежные вопросы