Spec-Zone.ru › GCC 5

6.16 Пространства именованных адресов

В качестве расширения, GNU C поддерживает пространства именованных адресов, как определено в черновике N1275 стандарта ISO/IEC DTR 18037. Поддержка пространств именованных адресов в GCC будет развиваться по мере изменения черновика технического отчета. Конвенции вызова для любого целевого процессора также могут изменяться. В настоящее время только целевые процессоры AVR, SPU, M32C и RL78 поддерживают пространства адресов, отличные от универсального пространства адресов.

Идентификаторы пространств адресов могут быть использованы точно так же, как и любой другой квалификатор типа C (например, const или volatile). Более подробная информация содержится в документе N1275.

6.16.1 Пространства именованных адресов AVR

На целевом процессоре AVR существует несколько пространств адресов, которые могут быть использованы для размещения данных только для чтения в памяти флэш-памяти и доступа к этим данным с помощью специальных инструкций LPM или ELPM, необходимых для чтения из флэш-памяти.

По умолчанию любые данные, включая данные только для чтения, находятся в ОЗУ (универсальное пространство адресов), поэтому для размещения данных только для чтения в памяти флэш-памяти и для генерации правильных инструкций для доступа к этим данным без использования (встраиваемого) ассемблерного кода необходимы пространства адресов, отличные от универсального.

__flash

Квалификатор __flash размещает данные в секции .progmem.data. Данные считываются с помощью инструкции LPM. Указатели на это пространство адресов имеют ширину 16 бит.

__flash1
__flash2
__flash3
__flash4
__flash5

Это 16-битные пространства адресов, размещающие данные в секции .progmemN.data, где N относится к пространству адресов __flashN. Компилятор устанавливает сегментный регистр RAMPZ соответствующим образом перед чтением данных с помощью инструкции ELPM.

__memx

Это 24-битное пространство адресов, которое линеаризует флэш-память и ОЗУ: Если старший бит адреса установлен, данные считываются из ОЗУ, используя два младших байта в качестве адреса ОЗУ. Если старший бит адреса сброшен, данные считываются из флэш-памяти с установленным RAMPZ в соответствии со старшим байтом адреса. См. __builtin_avr_flash_segment.

Объекты в этом пространстве адресов находятся в .progmemx.data.

Пример

char my_read (const __flash char ** p)
{
    /* p is a pointer to RAM that points to a pointer to flash.
       The first indirection of p reads that flash pointer
       from RAM and the second indirection reads a char from this
       flash address.  */

    return **p;
}

/* Locate array[] in flash memory */
const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };

int i = 1;

int main (void)
{
   /* Return 17 by reading from flash memory */
   return array[array[i]];
}

Для каждого пространства именованных адресов, поддерживаемого avr-gcc, определена одноименная, но заглавная встроенная макрокоманда. Цель состоит в том, чтобы упростить проверку доступности поддержки соответствующего пространства адресов:

#ifdef __FLASH
const __flash int var = 1;

int read_var (void)
{
    return var;
}
#else
#include <avr/pgmspace.h> /* From AVR-LibC */

const int var PROGMEM = 1;

int read_var (void)
{
    return (int) pgm_read_word (&var);
}
#endif /* __FLASH */

Обратите внимание, что атрибут progmem размещает данные во флэш-памяти, но доступ к этим данным читается из универсального пространства адресов, т.е. из ОЗУ, поэтому вам нужны специальные средства доступа, такие как pgm_read_byte из AVR-LibC вместе с атрибутом progmem.

Ограничения и замечания

  • Чтение через границу раздела 64 Кбайт пространств адресов __flash или __flashN демонстрирует неопределенное поведение. Единственное пространство адресов, поддерживающее чтение через границы сегментов флэш-памяти 64 Кбайт, — это __memx.
  • Если вы используете одно из пространств адресов __flashN, вы должны организовать свою линкерную скрипт для размещения секций .progmemN.data в соответствии с вашими потребностями.
  • Любые данные или указатели на пространства адресов, отличные от универсальных, должны быть квалифицированы как const, т. е. как данные только для чтения. Это все еще относится, если данные в одном из этих пространств адресов, например, номер версии программного обеспечения или справочная таблица калибровки, предназначены для изменения после загрузки, например, загрузочным программным обеспечением. В этом случае правильной квалификацией является const volatile, чтобы компилятор не оптимизировал известные значения или не вставлял их в качестве непосредственных операндов инструкций.
  • Следующий код инициализирует переменную pfoo, расположенную в статической памяти, с 24-битным адресом:
    extern const __memx char foo;
    const __memx void *pfoo = &foo;

    Для такого кода требуется как минимум binutils 2.23, см. PR13503.

6.16.2 Пространства именованных адресов M32C

На целевом процессоре M32C, с вариантами процессоров R8C и M16C, переменные, квалифицированные с помощью __far, обращаются к адресам с 32-битным адресом для доступа к памяти за пределами первых 64 Кбайт. Если __far используется с вариантами процессоров M32CM или M32C, он не оказывает никакого влияния.

6.16.3 Пространства именованных адресов RL78

На целевом процессоре RL78 переменные, квалифицированные с помощью __far, обращаются к 32-битным указателям (20-битным адресам) вместо стандартных 16-битных адресов. Переменные, не являющиеся дальними, предполагаются находящимися в самом верхнем 64 Кбайт пространства адресов.

6.16.4 Пространства именованных адресов SPU

На целевом процессоре SPU переменные могут быть объявлены как принадлежащие другому пространству адресов путём квалификации типа с идентификатором пространства адресов __ea:

extern int __ea i;

Компилятор генерирует специальный код для доступа к переменной i. Он может использовать поддержку библиотеки времени выполнения или генерировать специальные машинные инструкции для доступа к этому пространству адресов.

Далее: Длина ноль, Предыдущий: Фиксированная точка, Вверх: Расширения C [Оглавление][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/Named-Address-Spaces.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API