8 -битный enum, в c
-
18-09-2019 - |
Вопрос
Я должен хранить инструкции, команды, которые я буду получать через сериал. Команды будут длиной 8 бит.
Мне нужно сохранить прозрачность между именем команды и ее значением. Чтобы избежать перевода 8-битного числа, полученного в сериале в любой тип.
Я хотел бы использовать перечисления, чтобы справиться с ними в моем коде. Только перечисление соответствует A на этой платформе 16 -битное целое число.
Платформа - микроконтроллер AVR ATMEGA169V, на Демонстрационная доска бабочек. Анкет Это 8 -битная система с некоторой ограниченной поддержкой 16 -битных операций. Это не быстрая система и имеет около 1 КБ ОЗУ. У него нет роскоши, таких как файл ввод/вывод или операционные системы.
Итак, какие-нибудь предложения относительно того, какой тип я должен использовать для хранения 8-битных команд?
Должно быть что -то лучше, чем огромный заголовок #Defines.
Решение
gcc
S. -fshort-enums
может быть полезно:
Выделите тип «перечисления» всего столько байтов, сколько необходимо для объявленного диапазона возможных значений. В частности, тип «enum» будет эквивалентен самым маленьким целочисленным типам, у которого достаточно места.
Фактически, здесьСтраница SA с большим количеством соответствующей информации. Я надеюсь, что вы столкнетесь со многими выключателями GCC, которых вы никогда не знали. ;)
Другие советы
Вы пытаетесь решить проблему, которой не существует.
Ваш вопрос помечен C. В C -языковых типах перечисления в контексте значения полностью совместим с интегральными типами и ведут себя так же, как и другие интегральные типы. При использовании в выражениях они подвергаются точно таким же интегральным акциям, что и другие интегральные типы. Как только вы примите это во внимание, вы должны понять, что если вы хотите сохранить значения, описанные константами перечисления в 8-битном интегральном типе, все, что вам нужно сделать, это выбрать подходящий общий 8-битный интегральный тип (скажем int8_t
) и используйте его вместо типа перечисления. Вы абсолютно ничего не потеряете, сохраняя свои постоянные значения перечисления в объекте типа int8_t
(в отличие от объекта, явно объявленного с типом перечисления).
Проблема, которую вы описываете, будет существовать в C ++, где типы перечисления отделены намного дальше от других интегральных типов. В C ++ использование интегрального типа вместо энчевого типа с целью сохранения памяти сложнее (хотя это возможно). Но не в C, где это не требует никаких дополнительных усилий.
Я не понимаю, почему перечисление не сработает. Сравнения и назначения от перечисления должны работать нормально с расширением по умолчанию. Просто будьте осторожны, чтобы ваши 8 -битные значения были правильно подписаны (я думаю, вы хотите Unsigned расширение).
Таким образом, вы получите 16-битные сравнения, я надеюсь, что это не будет проблемой производительности (это не должно быть, особенно если ваш процессор 16-битный, как это кажется).
Компилятор Microsoft C позволяет вам делать что -то подобное, но это расширение (это стандарт в C ++ 0x):
enum Foo : unsigned char {
blah = 0,
blargh = 1
};
Поскольку вы пометили GCC, я не совсем уверен, возможно ли то же самое, но у GCC может быть расширение в gnu99
режим или что -то в этом роде. Дайте ему вихрь.
Я бы порекомендовал остаться на Enum в любом случае по следующим причинам:
- Это решение позволяет вам отобразить значения команд непосредственно с тем, что ожидает ваш серийный протокол.
- Если вы действительно используете 16-битную архитектуру, не существует столь большого количества преимуществ, чтобы перейти к 8 битам. Подумайте об аспектах, кроме 1 сохраненного байта памяти.
- В некоторых компиляторах я использовал фактический размер перечисления использовался минимальное количество бит (перечисления, которые можно было бы поместиться в байт, используемый только байт, затем 16 -битный, затем 32).
Сначала вы не должны заботиться о реальной ширине типа. Только если вам действительно нужен эффективный способ хранения, вы должны использовать флаги компилятора, такие как -fshort -enums на компиляторе GNU, но я не рекомендую их, если они вам не нужны.
В качестве последнего варианта вы можете определить «enum» как данные презентации для команд и использовать преобразование в байт с 2 простыми операциями для хранения / восстановления значения команды в / из памяти (и инкапсулировать это в одном месте). Что насчет этого? Это очень простые операции, поэтому вы можете даже внедрить их (но это позволяет вам действительно использовать только 1 байт для хранения и с другой стороны, чтобы выполнять операции, используя наиболее полезное перечисление, определенное как вам нравится.
Ответ, который имеет отношение к Дуговой компилятор (Цитируется из Designware Metaware C/C ++ Руководство программиста для ARC; Раздел 11.2.9.2)
Размер перечислений Размер типа перечисления зависит от статуса переключения *long_enums *.
■ Если перевернуть * long_enums * выключен, тип перечисления отображается на самый маленький из одного, двух или четырех байтов, так что все значения могут быть представлены.
■ Если перевернуть * long_enums * включен, перечисление карты до четырех байтов (соответствует конвенции AT & T Portable C Compiler).