Файл с полезностями.

Опубликовано в рубрике "Исходники", 04.10.2009.
Тэги: , , , , автор:

Во все свои контроллерные проекты я включаю файлик, в котором содержится куча разных дефайнов, полезных макросов и прочей лабуды. Предлагаю его и вам.

#define TRUE FALSE

 

Сразу перейду к главному. Скачать этот файлик можно тут:

 

Что там есть и зачем это нужно?

Там есть шапка с моим ником, которую никто обычно в своих проектах не сохраняет. Пусть это останется на их совести )).

Дальше идет секция с гордым названием настройки. В этой секции только одно определение с архитектурой. Я оставил AVR.

Разные инклуды”. Обычно каждый контроллер требует включать заголовочные файлы компилятора, название которых очень лениво вспоминать. В этой секции они всегда будут на виду. Опять-же там есть только пара AVR и IAR. У каждого разработчика есть куча заголовочных фалов с разными полезностями, эта секция – идеальное место включить их одним махом.

 

В секции “Разные полезные типы данных” описаны типы данных с фиксированным размером. Стандартные типы (“int”, к примеру) не имеют фиксированного стандартами размера, и с этим связанно большое количество глюков. К примеру, у связки IAR+AVR sizeof(int) = 2, а у IAR+ARM7 – sizeof(int) = 4. По этому поводу даже есть рекомендация MISRA-C:

The basic types of char, int, short, long, float, and double should not be used, but specific-length equivalents should be typedef’d for the specific compiler, and these type names used in the code.

Я назвал свои переменные “uint8” (8 — длинна в битах), “int16”, итп. Некоторые программисты предпочитают более короткие имена – u8, s16. Как и все остальное в этом файле, конкретное название – дело вкуса.

Конечно-же, производители компиляторов не могли обойти стороной проблему фиксированной длинны и сделали файлик stdint.h, который входит в стандартную библиотеку. Имена которые определенны там (uint8_t, uint_least8_t) я считаю слишком длинными и некрасивыми.

С фиксированной длинной связанна еще одна маленькая проблемка – многие 32-битные контроллеры с 8-битными переменными работают медленнее, чем с 32-битными. В stdint.h для решения этой проблемы определили переменные типа uint_fast8_t. Гарантируется, что такие переменные будут как минимум 8 бит длинной и как можно быстрее работать.

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

 

Дальше немного констант. Про значения MAXMAX и так все понятно, А вот коды возврата – это очень полезная штука. Часто в качестве кода возврата используют bool. Этот тип занимает целые 8 бит, а передает всего два значения. Я решил его немного исправить несправедливость и добавил несколько других значений, естественно их можно дополнять как хочется. Имена кодов возврата я взял из технологии COM, используемой в Windows. Все коды обозначающие ошибки начинаются с префикса E_ ( ERROR ), а коды обозначающие успешное выполнение – с S_ ( SUCCESS ). К примеру

S_OK – Все хорошо, уряяя!
E_ERR – Все плохо (
E_USER – Все плохо потому, что пользователь сделал какую-то глупость, к примеру прервал операцию.

итп.

 

Полезные функции. Тут несколько правильно написанных макросов которые часто используются. Разные общеизвестные MIN, MAX, ABS всем, надеюсь, ясны.

Макросы начиная с LOBYTE и до BYTE3 используются особо часто и возвращают соответствующий кусочек большего типа данных. К примеру, uint16 i = 0x1234; HIBYTE(i) = 0x12; LOBYTE(i) = 0x34. Надеюсь, вы поняли идею.

Ну, и самая большая полезность из этого всего — ARRAY_SIZE(a). К примеру у вас есть структура и массив экземпляров этой структуры. К примеру, очень часто нужно пробежаться по всем экземплярам структуры в поисках чего-то, это очень удобно сделать так:

struct People_t
{
	uint8 *Name;
	uint32 Birthday;
} ;

People_t people[100];

for ( uint8 i; i<ARRAY_SIZE(people); i++ )
{
	...
}

 

Биты – тоже очень полезны. К примеру, ножки контроллеров можно обозначать как

#define DF_MISO_PB   BIT4

Теперь можно писать

DDRB &= ~DF_MISO_PB;

Вместо

DDRB &= ~(1<<DF_MISO_PB);

Лично я часто забывал про “1<<” и меня начало это раздражать.

 

Дальше идут ассерты. Я предлагаю при переходе на новую архитектуру/процессор на раскомментировать их. Они проверят – являются ли длинны наших переменных с фиксированной длинной такими, какими они должны быть. Дальше этот блок можно закомментировать обратно.

Критика, комментарии и дополнения приветствуются.

Комментарии
  1. Deimos написал(а) 4th Июль, 2010 в 11:08

    #define BYTE0(a) (*((uint8*)&(a) + 0))
    #define BYTE1(a) (*((uint8*)&(a) + 1))
    #define BYTE2(a) (*((uint8*)&(a) + 2))
    #define BYTE3(a) (*((uint8*)&(a) + 3))

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *


Срок проверки reCAPTCHA истек. Перезагрузите страницу.