Объявление переменной с @ в C

11

Я читаю код на C и наткнулся на это объявление в программе:

unsigned char serv_ctr @0x0002;

Может кто-нибудь указать мне на документацию или объяснить, для чего "@ 0x0002" в компиляторе C Mplab XC8 v1.35?

быть-е-е
источник
14
Я предполагаю, что это расширение компилятора для размещения переменной по определенному адресу.
Евгений Ш.
2
тогда вопрос может принести пользу тегу #mplab, поскольку оказывается, что это зависит от Mplab.
sylvainulg
Просто чтобы получить это: это по теме на этом сайте? Я думаю, что это относится к SO. Или можно спросить о программировании микроконтроллера здесь. Это сделало бы немного неясным, где эти вопросы должны быть.
До свидания, SE
6
@KamiKaze Какие темы я могу задать здесь? перечисляет «написание встроенного программного обеспечения для приложений на« голое железо »или RTOS», как в теме, и «программное обеспечение для программирования на ПК», как не по теме. Поскольку речь идет о программировании встраиваемых систем, на первый взгляд кажется, что это тема. То, что это также может быть связано с темой переполнения стека , само по себе здесь не выходит.
CVn
@KamiKaze спасибо за вопрос, у меня были похожие вопросы (я не постоянный пользователь этого SE)
GPPK

Ответы:

20

Это указать абсолютный адрес для размещения переменной.
Со страницы руководства по компилятору XC8 , раздел 2.5.2 Абсолютная адресация :

Переменные и функции могут быть размещены по абсолютному адресу с помощью __at()конструкции
......
2.5.2.2 ОТЛИЧИЯ
8-битные компиляторы использовали символ @ для указания абсолютного адреса

Евгений Ш.
источник
6

@является распространенным нестандартным расширением языка Си, которое позволяет объявлять переменную по определенному адресу. Его можно использовать для аппаратных регистров с отображением в памяти и т. Д. В этом случае переменная также должна быть объявлена volatile, поэтому ваш пример неверен.

Другие компиляторы используют что-то вроде __attribute__(section...или #pragma ..., все это нестандартный C.

Единственная разумная причина (если таковая имеется), почему цепочки инструментов делают это, состоит в том, чтобы включить отладку регистров на дрянных отладчиках. Нестандартный синтаксис гарантирует, что регистр станет частью вывода компоновщика и отладочной информации. Что, в свою очередь, позволяет вам наблюдать регистр в дерьмовом отладчике так же, как вы можете наблюдать любую другую переменную.

Если у вас есть хороший отладчик, он будет иметь поддержку и осведомленность о вашем конкретном MCU. Тогда вам не нужно нестандартное дерьмо в коде C, но вместо этого вы можете написать чистый, переносимый стандарт C:

#define serv_ctr ( *(volatile uint8_t*)0x0002u )
Лундин
источник
1
Хотя компиляторы обязаны принимать последнюю форму, реализациям разрешается сопоставлять числа с адресами любым удобным для них способом. Кроме того, большинство компиляторов, которые я видел, используют @целевые платформы нотации с несколькими областями памяти или другими проблемами, так что большинство вещей, объявленных с использованием @нотации, будут вести себя иначе, чем все, что может быть сделано без расширений.
суперкат
1

Краткое расширение:

Это больше не работает, начиная с xc8 2.0 и выше. Теперь вам нужно было написать:

unsigned char serv_ctr __at(0x0002);

поместить переменную ( serv_ctr) в абсолютный адрес ( 0x0002).

С XC8 2.0 можно скомпилировать старый код, используя @синтаксис, если в настройках компилятора используется формат «C90». Настройка выглядит следующим образом: она находится в разделе «Глобальные параметры XC8» и называется «Стандарт C».

Майк
источник
Многие другие компиляторы встроенных систем также поддерживают @синтаксис, не только Mplab.
Лундин