4.2.1. Расширения языка C

(Руководство разработчика по микроконтроллерам семейства HCS08)

Стандарт ANSI C предусмаривает резервирование некоторого количества ключевых слов, которые могут быть использованы по усмотрению разработчика компилятора. В компиляторе CodeWarrior для HCS08 используется 7 дополнительно определенных ключевых слов или операторов. Они перечислены в Табл.4.8, смысловое назначение каждого слова подробно описано ниже.

Таблица4.8. Дополнительные ключевые слова компилятора C HCS08

@farlinearnear
_va sizeof _alignofInterruptasm

@

этот оператор может быть использован для того, чтобы поместить переменную в желаемый сегмент памяти. Кроме того, с помощью данного оператора можно расположить глобальную переменную по адресу, заданному в абсолютном коде. Например:

/*Объявляемглобальнуюпеременнуювформатеunsignedint(16битбеззнака)иразмещаемеепоадресу0x0080*/
intmy_variable@0x0080;

far

указывает компилятору использовать режимы адресации с 16-битным форматом адреса для выбранного типа переменных. Таким образом, разрешается доступ к переменным, которые размещаются в любой области линейно адресуемого адресного пространства, вплоть до 0xFFFF или 65535. Когда это слово используется в выражении с объявлением указателя, оно работает как модификатор адреса. Примеры:

//Объявлениеуказателя(сформатомfar)науказатель(тожеформатаfar)дляпеременнойформатаchar//
char*far*farmy_far_pointer;
//Объявлениеуказателянауказатель(форматаfar)дляпеременнойформатаint//
int*far*my_far_pointer;

Также возможно использование данного ключевого клова в приложении к массивам. Это может быть представлено, например, так:

//Объявлениепараметрадляфункцииtest_functionкакэлементамассива«param»
voidtest_function{charparam[2]far);
//илипосредствомиспользованиявсегоодногоуказателя:
voidtest_function(char*farparam);

linear

указывает компилятору использовать режим глобальной адресации с форматом адреса, превышающим 16 бит. Таким образом, разрешается доступ к переменным, которые размещаются в области расширенного адресного пространства, т.е. к адресам, превышающим 0xFFFF.

//Объявлениеконстанты,котораяразмещаетсяпоадресу0x010000иравна10
constcharmy_var@LINEAR0x010000=10;

near

указывает компилятору использовать режим адресации 8-битным форматом адреса для выбранного типа переменных. Таким образом, разрешается быстрый доступ к переменным, которые размещаются в нулевой странице памяти 0x00...0xFF. Эта директива компилятора по своему действию противоположна директиве far.

_va_sizeof

возвращает размер в байтах выбранного типа данных, в том числе после автоматического преобразования типа данных в программе.

_alignof

возвращает размер определенного пользователем специального типа данных, например структуры.

interrupt

указывает компилятору на то, что следующая за ним функция вызывается автоматически по запросу на прерывание. За этим словом должен следовать номер вектора прерывания. Начиная с версии 6.0 интегрированной среды CodeWarrior в компилятор встроены предварительно определенные имена векторов прерывания (см. Табл.2.1...2.6). Примеры:

//ФункцияобработкипрограммногопрерыванияSWI
voidinterruptVectorNumber_Vswivoidswi_service(void);
//ФункцияобработкивнешнегопрерыванияповходуIRQ
voidinterruptVectorNumber_Virqtrata_irq(void);
//ФункцияобработкивнутреннегопрерыванияотмодуляADC
voidinterruptVectorNumber_Vadctrata_adc(void);

asm

позволяет вставлять команды ассемблера в текст прграммы на C. Более подробно синтаксис и некоторые смысловые действия программиста по этой теме будут обсуждаться в разделе 4.3. Пример:

//ВставитьвпрограммукомандуассемблераSTOP
asmstop;

Также в компиляторе для HCS08 существуют специальные указания компилятору, которые применяются со служебным словом #pragma. Рассмотрим наиболее важные с точки зрения автора указания/директивы.

CODE_SEG

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

//Функцияmy_funcбудетразмещенавсегментепамятиMY_SEG
#pragmaCODE_SEGMY_SEG
voidmy_func(void)
{
.......
}

Если после CODE_SEG использовано слово DEFAULT, то обычно это сегмент DEFAULT_ROM:

#pragmaCODE_SEGDEFAULT

В качестве дополнительной опции для CODE_SEG можно задать расположение функции в определенной области памяти и, как следствие, способ доступа к этой области памяти. Сушествует 6 выделенных сегментов памяти: DIRECT_SEG, NEAR_CODE, NEAR_SEG, FAR_CODE, FAR_SEG, _CODE_SEG. Пример:

#pragmaCODE_SEGFAR_SEGMY_SEG
//Функцияmy_funcбудетразмещенавсегментепамятиMY_SEG,вызовфункциибудетпроизводитьсясиспользованиемтолько15-битнойадресации
voidmy_func(void)
{
.......
}

Важно, что вы должны использовать только те имена сегментов памяти, которые обозначены в разделе PLACEMENT файла конфигурации программы компоновщика *.prm!

CONST_SEG

указывает сегмент памяти, в котором будут размещаться константные данные. Пример:

/*Переменнаяmyconst1,котораяследуетсразуза#pragma,будетразмещенавсегментеMY_CONST_SEG*/
#pragmaCONST_SEGMY_CONST_SEG
constcharmyconst1=50;
/*Всоответствиисоследующейзаписьюконстантныезначениябудутразмещенывсегменте,которыйотведенподконстантыпоумолчанию.ОбычноэтосегментROM_VAR*/
#pragmaCONST_SEGDEFAULT

Так же, как и для предыдущей директивы, можно указать способ доступа к константным значениям. Доступны следующие опции: _SHORT_SEG, _DIRECT_SEG, NEAR_SEG, _CODE_SEG, _FAR_SEG and _LINEAR_SEG. Пример:

//Константнаяпеременнаяmyconst2,котораяследуетсразуза#pragma,будетразмещенавсегментеMY_CONST_SEG,идляобращениякэтойпеременнойбудетиспользоватьсяпрямаяадресация(адреспредставляетсяоднимбайтом)*/
#pragmaCONST_SEGDIRECT_SEGMY_CONST_SEG
charmyconst2=50;

Важно, что вы должны использовать только те имена сегментов памяти, которые обозначены в разделе PLACEMENT файла конфигурации программы компоновщика *.prm!

DATA_SEG

указывает сегмент памяти, в котором будут размещаться переменные программы. Эта директива имеет те же опции, что и директива CONST_SEG.

INLINE

предписывает компилятору вставлять в исполняемый код программы непосредственно код функции вместо кода вызова этой функции. Такое решение сокрашает время исполнения программы, но увеличивает размер исполняемого кода. Пример:

#pragmaINLINE
voidswap(char*vl,char*v2)
{I
chartemp;
temp=*v2;
*v2=*vl;
*vl=temp;
}

Рассматриваемая директива эквивалентна опции –Oi компилятора. Но опция –Oi позволяет дополнительно назначить максимальный размер кода, который следует вставлять непосредственно. Например, использование –Oi=c50 укажет компилятору, что непосредственно следует вставлять только те функции, код которых занимает менее 50 байт.

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

  • функции с метками в теле функции;
  • функции с открытым списком параметров;
  • функции, которые содержат ассемблерные строки;
  • функции, которые используют локальные статические переменные.
INTO_ROM

предписывает компилятору запомнить переменную в области постоянной памяти, которая в МК HCS08 является флэш-памятью (сегмент ROM_VAR). Пример:

#pragmaINTO_ROM
char[]={"MyconstantstringplacedintoROM"};

Эта директива эквивалентна опции –Cc компилятора.

mark

добавляет маркер с именем, который соответствует тексту в строке после директивы #pragma mark. Этот маркер можно увидеть в списке marks list в окне редактора CodeWarrior. Установка маркеров упрощает навигацию по тексту исходного программного кода. Пример:

//ПервыймаркерVariabledefinition
#pragmamarkVariabledefinition
charva,vb,vc;
//Второймаркерtest
#pragmamarktest
voidtest(intsubject)

NO_ENTRY

запрещает генерировать входной код. Это полезно для функций, записанных на ассемблере. Тогда программист может полностью проверить код функции перед ее вызовом.

Пример:

#pragmaNO_ENTRY
voidmy_asm_func(void)
{
.......
}

NO_EXIT

запрещает генерировать код возврата из функции. Это полезно для функций, записанных на ассемблере. Тогда программист может полностью проверить программный код функции перед возвратом в функцию вызова.

NO_FRAME

запрещает генерировать код функции. Это полезно для функций, записанных на ассемблере. Тогда программист может полностью проверить программный код функции перед возвратом в функцию вызова. Пример:

#pragmaNO_ENTRY
#pragmaNO_EXIT
#pragmaNO_FRAME
voidmy_asm_func(void)
{
......
}

NO_RETURN

предписывает компилятору не генерировать команд возврата из функции (RTS, RTI или RTC), поскольку выход из функции не предполагается. Пример:

#pragmaNO_RETURN
voidspecial_func(void)
{
......
}

NO_STRING_CONSTR

запрещает специальную обработку символа # компилятором. Эта функция полезна, когда записывают макросы C с использованием команд ассемблера. Пример:

#pragmaNO_STRING_CONSTR
#definelda(x)asmlda#x

Здесь в команде ассемблера присутствует символ #, но он не имеет отношения к конструкциям языка C.

profile

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

//Включитьфункциюпрофилированиякомпилятора
#pragmaprofileon
//Выключитьфункциюпрофилированиякомпилятора
#pragmaprofileoff

Мы рассмотрели не все указания со служебным словом #pragma, которые доступны для компилятора HCS08. Для дополнительной информации смотрите документацию и раздел «help» в программе CodeWarrior.

Электронные компоненты Freescale >>>
Подробнее о компании Freescale >>>