- •I справочный материал ц
- •Подразумевается, что читатель знаком с показательной формой записи действи- етльных чисел.
- •Int a[5]; // массив a[] из 5-и элементов типа int
- •Int a1, a2, a3, a4, a5; // 5 отдельных переменных типа int
- •Void boot_program_page (uint32_t page, uint8_t *buf){
- •Int main(void){
- •Isr_noblock
- •Isr_naked
- •Isr_alias()
- •Isr_aliasof()
- •Isr_block
Isr_alias()
ISR_ALIAS(vector, target_vector) - макрос, связывающий два вектора в один обработчик. Не рекомендуется использование в новых разработках. В качестве параметра vector и target_vector используется любая из констант, как и для ISR(), причем параметр target_vector к моменту вызова макроса должен быть уже определен (см. врезку ISR_ALIAS):
Isr_aliasof()
ISR_ALIASOF(target_vector) - макрос, используемый в качестве опционального параметра ISR() для того, чтобы связать обработчик, определенный ISR(), еще и с вектором target_vector (см. врезку ISR_ALIASOF).
BADISR_vect
BADISR_vect - константа «псевдовектора», обозначающая любой явно не заданный вектор. По умолчанию соответствует переходу на начало программной памяти, вызывая переинициализацию всего кода при поступлении «необрабатываемого» прерывания.
Isr_block
ISR_BLOCK - опциональный атрибут, используемый в ISR(), и обозначающий, что прерывания будут запрещены в течение работы всего обработчика прерывания. Если этот атрибут не задан явно (т.е. используется ISR() без атрибутов вообще), прерывания все равно будут запрещены.
Isr_noblock
ISR_NOBLOCK - опциональный атрибут, используемый в ISR(), и обозначающий, что прерывания будут разрешены в течение работы всего обработчика прерывания. Это позволит быстрее отреагировать на ожидающие в очереди другие запросы прерываний, однако увеличивает требования к объему стека.
Isr_naked
ISR_NAKED - опциональный атрибут, используемый в ISR(), и обозначающий, что компилятор не должен добавлять пролог и эпилог к функции. В этом случае программист обязан сам выполнить все необходимые меры, включая выход из обработчика макросом reti().
avr/io.h - Специфичные
для AVR функции ввода-вывода
Этот заголовочный файл по существу реализует автоматическое подключение одного конкретного файла, соответствующего выбранному микроконтроллеру. Во всяком случае, для определения констант и макросов портов ввода-вывода и т.п. периферии программист более не должен применять никаких усилий, кроме подключения этого файла к проекту и задания типа микроконтроллера. Фактически происходит подключение целого ряда заголовочных файлов, в которых определены константы и макросы для обращения к различной периферии микроконтроллера (см. например avr/sfr_defs.h - Регистры специальных функций AVR).
Рассмотрение всех этих определений опущено, т.к. подразумевается, что программист, работающий с AVR, вполне информирован о его периферии. Из прочего стоит обратить внимание лишь на следующие константы:
RAMEND - соответствует адресу последней существующей ячейки ОЗУ, т.е. в сущности, определяет размер ОЗУ выбранного микроконтроллера.
XRAMEND - соответствует адресу последней существующей ячейки внешнего или дополнительно адресуемого ОЗУ (если его поддержка имеется в микроконтроллере).
E2END - соответствует адресу последней ячейки встроенного EEPROM
FLASHEND - соответствует адресу последней ячейки памяти программ, т.е. фактически определяет размер сегмента кода.
SPM_PAGESIZE - соответствует размеру страницы для операций самопрограммирования (т.е. записи из программы в сегмент кода).
avr/pgmspace.h - Поддержка
обращения к сегменту кода AVR
В этом модуле определяются ряд функций и макросов, позволяющих обращаться к данным, хранящимся в памяти программ, т.е. сегменте кода. Для этого необходимо, чтобы микроконтроллер поддерживал инструкции LPM или ELPM.
Функции этого модуля - попытка облегчить процесс адаптации программ для IAR, однако полной совместимости нет по принципиальным особенностям GCC.
Если вы работаете со строками, которые постоянно размещены в ОЗУ, вы можете использовать функции для работы с ними из модуля string.h - Строки, но для неизменных строк более удачным будет размещение их в сегменте кода. В этом случае вы можете работать с ними при помощи функций этого модуля, которые совпадают по имени с аналогичными из string.h, но имеют суффикс _Р - признак того, что строка находится в программной памяти (такой принцип так же использовался и в модуле stdio.h - Стандартный ввод-вывод).
Однако следует учитывать, что функции из настоящего модуля могут работать только со строками, размещенными в первых 64К адресного пространства микроконтроллера, т.к. не используют инструкцию ELPM. Это не страшно в обычных случаях. Но может вызвать проблемы, если имеется много текстовых констант или же используется самозагрузка кода. При написании программы вы не должны беспокоиться о месте размещения строк, т.к. компоновщик автоматически разместит все данные в программной памяти сразу после векторов прерывания.
Так же следует помнить о том, что все используемые для обращения к сегменту кода указатели представляют себя адреса байтов (хотя программная адресация у AVR - 16-битная).
Определения модуля
Модуль определяет ряд констант, атрибутов и макросов, облегчающих разработку программ, работающих с данными в сегменте кода.
PROGMEM
PROGMEM - макрос, устанавливающий атрибут, указывающий, что переменная на самом деле представляет собой константу в сегменте кода
PSTR()
PSTR(s) - макрос, используемый для определения указателя на строку s, размещенную в сегменте кода
PGM_P
PGM_P - макрос, определяющий указатель на символ в сегменте кода
PGM_VOID_P
PGM_VOID_P - макрос, определяющий указатель на объект в сегменте кода
pgm_read_byte_near()
pgm_read_byte_near(address_short) - макрос, возвращающий значение байта, считанного из программной памяти по адресу address_short (в первых 64К).
pgm_read_word_near()
pgm_read_word_near(address_short) - макрос, возвращающий значение 16-битного числа, считанного из программной памяти по адресу address_short (в первых 64К).
pgm_read_dword_near()
pgm_read_dword_near(address_short) - макрос, возвращающий значение 32-битного числа, считанного из программной памяти по адресу address_short (в первых 64К).
pgm_read_byte_far()
pgm_read_byte_far(address_long) - макрос, возвращающий значение байта, считанного из программной памяти по адресу address_long (32 бита, нет ограничения в 64К).
pgm_read_word_far()
pgm_read_word_far(address_long) - макрос, возвращающий значение 16-битного числа, считанного из программной памяти по адресу address_long (32 бита, нет ограничения в 64К).
pgm_read_dword_far()
pgm_read_dword_far(address_long) - макрос, возвращающий значение 32-битного числа, считанного из программной памяти по адресу address_long (32 бита, нет ограничения в 64К).
pgm_read_byte()
pgm_read_byte(address_short) - аналог pgm_read_byte_near()
pgm_read_word()
pgm_read_word(address_short) - аналог pgm_read_word_near()
pgm_read_dword()
pgm_read_dword(address_short) - аналог pgm_read_dword_near()
Типы, вводимые модулем
Модуль вводит ряд типов, которые просто облегчают определение констант в сегменте кода. По смыслу все эти типы аналогичны определенным в inttypes.h - Целочисленные преобразования, только содержат префикс prog_, означающий, что соответствующий объект размещается в памяти программ. В связи с этим расшифровка значения типов не приводится. prog_void prog_char prog_uchar prog_int8_t prog_uint8_t prog_int16_t
prog_uint16_t
prog_int32_t
prog_uint32_t
prog_int64_t
prog_uint64_t
Функции модуля
Так как все функции не более чем аналоги string.h - Строки, вместо подробного описания будут указаны ссылки на функции для работы со строками в ОЗУ. Единственное, на что должен обратить программист, это типы передаваемых в функции параметров и возвращаемых значений: как правило, все указатели в функциях этого модуля - это указатели на объекты в сегменте кода.
memchr_P()
PGM_VOID_P memchr_P (PGM_VOID_P s, int val, size_t len)
Функция ищет в области программной памяти s символ, возвращая указатель на него или NULL, если не найдено. Подробности см. в memrchr()
memcmp_P()
int memcmp_P (const void *s1, PGM_VOID_P s2, size_t len)
Функция сравнивает область ОЗУ s1 и памяти программ s2. Подробности см. в memcmp()
memcpy_P()
void * memcpy_P (void *dest, PGM_VOID_P src, size_t len)
Функция копирует в область ОЗу dest содержимое области памяти программ src. Подробности см. в memcpy()
memrchr_P()
PGM_VOID_P memrchr_P (PGM_VOID_P s, int val, size_t len)
Функция ищет в области программной памяти s символ. Подробности см. в memrchr() и memchr_P()
strcasecmp_P()
int strcasecmp_P (const char *s1, PGM_P
s2)
Функция сравнивает строку s1 в ОЗУ со строкой в памяти программ s2 без учета регистра символов. См. strcasecmp()
strcat_P()
char * strcat_P (char *dest, PGM_P src) Функция осуществляет конкатенацию строки src из памяти программ к строке dest в ОЗУ. См. strcat()
strchr_P()
PGM_P strchr_P (PGM_P s, int val) Функция ищет символ в строке s в программной памяти. См. strchr()
strchrnul_P()
PGM_P strchrnul_P (PGM_P s, int val) Функция, аналогичная strchr_P(), за исключением того, что всегда возвращает не- NULL указатель: если символ не найден, возвращается указатель на завершающий ноль строки s
strcmp_P()
int strcmp_P (const char *s1, PGM_P s2)
Функция аналогична strcmp(), за исключением того, что s2 находится в программной памяти.
strcpy_P()
char * strcpy_P (char *s1, PGM_P s2)
Функция аналогична strcpy(), за исключением того, что s2 находится в программной памяти.
strcspn_P()
size_t strcspn_P (const char *s, PGM_P reject)
Функция аналогична strcspn(), за исключением того, что reject находится в программной памяти.
strlcat_P()
size_t strlcat_P (char *dest, PGM_P src, size_t siz)
Функция аналогична strlcat(), за исключением того, что src находится в программной памяти
strlcpy_P()
size_t strlcpy_P (char *dest, PGM_P src, size_t siz)
Функция аналогична strlcpy(), за исключением того, что src находится в программной памяти
strlen_P()
size_t strlen_P (PGM_P s)
Функция аналогична strlen(), за исключением того, что s находится в программной памяти
strncasecmp_P()
int strncasecmp_P (const char *s1, PGM_P s2, size_t n)
Функция аналогична strncasecmp(), за исключением того, что s2 находится в программной памяти
strncat_P()
char * strncat_P (char *dest, PGM_P src, size_t len)
Функция аналогична strncat(), за исключением того, что src находится в программной памяти
strncmp_P()
int strncmp_P (const char *s1, PGM_P s2, size_t n)
Функция аналогична strncmp(), за исключением того, что s2 находится в программной памяти
strncpy_P()
char * strncpy_P (char *dest, PGM_P src, size_t n)
Функция аналогична strncpy(), за исключением того, что src находится в программной памяти
strnlen_P()
size_t strnlen_P (PGM_P src, size_t len)
Функция аналогична strnlen(), за исключением того, что src находится в программной памяти
strpbrk_P()
char * strpbrk_P (const char *s, PGM_P accept)
Функция аналогична strpbrk(), за исключением того, что accept находится в программной памяти
strrchr_P()
PGM_P strrchr_P (PGM_P s, int val)
Функция аналогична strrchr(), за исключением того, что s находится в программной памяти
strsep_P()
char * strsep_P (char **sp, PGM_P delim)
Функция аналогична strsep(), за исключением того, что delim находится в программной памяти
strspn_P()
size_t strspn_P (const char *s, PGM_P accept)
Функция аналогична strspn(), за исключением того, что accept находится в программной памяти
strstr_P()
char * strstr_P (const char *s1, PGM_P s2)
Функция аналогична strstr(), за исключением того, что s2 находится в программной памяти
memmem_P()
void * memmem_P (const void *s1, size_t len1, PGM_VOID_P s2, size_t len2)
Функция аналогична memmem(), за исключением того, что s2 находится в программной памяти
strcasestr_P()
char * strcasestr_P (const char *s1, PGM_P
s2)
Функция аналогична strcasestr(), за исключением того, что s2 находится в программной памяти
p^ Продолжение в N92/2011
1 Значение может отличаться в зависимости от стандарта, которому соответствует компилятор.
2 Разделителями считаются любые скобки - круглые, фигурные и квадратные, однако не всегда и не все из них могут использоваться произвольно - существует ряд ограничений, которые будут упомянуты по мере изложения основ языка.
3 Список служебных слов может несколько отличаться в зависимости от конкретного компилятора (как правило в сторону расширения).
4 Приведены типы, являющиеся стандартными в версии Си для микроконтроллеров
AVR
5 Ключевое слово short имеет важную роль в системах, для которых тип int не является 16-битным числом (например, для PC-компьютеров). В этом случае тип char соответственно может быть 16-битным, и тогда для получения однобайтного типа необходимо использование short char.
6 Двоичные константы определены для GNU-расширений Си.
7 Здесь и далее, если иное не оговорено, используется традиционный формат описания шаблонов выражений: в угловых скобках указываются обязательные элементы, в квадратных - опциональные, все прочие символы вне скобок являются обязательными.
8 Вспоминается шутка математиков: «представьте себе проекцию семимерного куба на пятимерную плоскость»...
Радиолюбитель
- 01/2010 U
