4.2.1. Расширения языка C
(Руководство разработчика по микроконтроллерам семейства HCS08)Стандарт ANSI C предусмаривает резервирование некоторого количества ключевых слов, которые могут быть использованы по усмотрению разработчика компилятора. В компиляторе CodeWarrior для HCS08 используется 7 дополнительно определенных ключевых слов или операторов. Они перечислены в Табл.4.8, смысловое назначение каждого слова подробно описано ниже.
Таблица4.8. Дополнительные ключевые слова компилятора C HCS08
@ | far | linear | near |
_va sizeof | _alignof | Interrupt | asm |
@
этот оператор может быть использован для того, чтобы поместить переменную в желаемый сегмент памяти. Кроме того, с помощью данного оператора можно расположить глобальную переменную по адресу, заданному в абсолютном коде. Например:
intmy_variable@0x0080;
far
указывает компилятору использовать режимы адресации с 16-битным форматом адреса для выбранного типа переменных. Таким образом, разрешается доступ к переменным, которые размещаются в любой области линейно адресуемого адресного пространства, вплоть до 0xFFFF или 65535. Когда это слово используется в выражении с объявлением указателя, оно работает как модификатор адреса. Примеры:
char*far*farmy_far_pointer;
//Объявлениеуказателянауказатель(форматаfar)дляпеременнойформатаint//
int*far*my_far_pointer;
Также возможно использование данного ключевого клова в приложении к массивам. Это может быть представлено, например, так:
voidtest_function{charparam[2]far);
//илипосредствомиспользованиявсегоодногоуказателя:
voidtest_function(char*farparam);
linear
указывает компилятору использовать режим глобальной адресации с форматом адреса, превышающим 16 бит. Таким образом, разрешается доступ к переменным, которые размещаются в области расширенного адресного пространства, т.е. к адресам, превышающим 0xFFFF.
constcharmy_var@LINEAR0x010000=10;
near
указывает компилятору использовать режим адресации 8-битным форматом адреса для выбранного типа переменных. Таким образом, разрешается быстрый доступ к переменным, которые размещаются в нулевой странице памяти 0x00...0xFF. Эта директива компилятора по своему действию противоположна директиве far.
_va_sizeof
возвращает размер в байтах выбранного типа данных, в том числе после автоматического преобразования типа данных в программе.
_alignof
возвращает размер определенного пользователем специального типа данных, например структуры.
interrupt
указывает компилятору на то, что следующая за ним функция вызывается автоматически по запросу на прерывание. За этим словом должен следовать номер вектора прерывания. Начиная с версии 6.0 интегрированной среды CodeWarrior в компилятор встроены предварительно определенные имена векторов прерывания (см. Табл.2.1...2.6). Примеры:
voidinterruptVectorNumber_Vswivoidswi_service(void);
//ФункцияобработкивнешнегопрерыванияповходуIRQ
voidinterruptVectorNumber_Virqtrata_irq(void);
//ФункцияобработкивнутреннегопрерыванияотмодуляADC
voidinterruptVectorNumber_Vadctrata_adc(void);
asm
позволяет вставлять команды ассемблера в текст прграммы на C. Более подробно синтаксис и некоторые смысловые действия программиста по этой теме будут обсуждаться в разделе 4.3. Пример:
asmstop;
Также в компиляторе для HCS08 существуют специальные указания компилятору, которые применяются со служебным словом #pragma. Рассмотрим наиболее важные с точки зрения автора указания/директивы.
CODE_SEG
указывает компилятору сегмент памяти, в который необходимо поместить функцию.
#pragmaCODE_SEGMY_SEG
voidmy_func(void)
{
.......
}
Если после CODE_SEG использовано слово DEFAULT, то обычно это сегмент DEFAULT_ROM:
В качестве дополнительной опции для CODE_SEG можно задать расположение функции в определенной области памяти и, как следствие, способ доступа к этой области памяти. Сушествует 6 выделенных сегментов памяти: DIRECT_SEG, NEAR_CODE, NEAR_SEG, FAR_CODE, FAR_SEG, _CODE_SEG. Пример:
//Функцияmy_funcбудетразмещенавсегментепамятиMY_SEG,вызовфункциибудетпроизводитьсясиспользованиемтолько15-битнойадресации
voidmy_func(void)
{
.......
}
Важно, что вы должны использовать только те имена сегментов памяти, которые обозначены в разделе PLACEMENT файла конфигурации программы компоновщика *.prm!
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. Пример:
#pragmaCONST_SEGDIRECT_SEGMY_CONST_SEG
charmyconst2=50;
Важно, что вы должны использовать только те имена сегментов памяти, которые обозначены в разделе PLACEMENT файла конфигурации программы компоновщика *.prm!
DATA_SEG
указывает сегмент памяти, в котором будут размещаться переменные программы. Эта директива имеет те же опции, что и директива CONST_SEG.
INLINE
предписывает компилятору вставлять в исполняемый код программы непосредственно код функции вместо кода вызова этой функции. Такое решение сокрашает время исполнения программы, но увеличивает размер исполняемого кода. Пример:
voidswap(char*vl,char*v2)
{I
chartemp;
temp=*v2;
*v2=*vl;
*vl=temp;
}
Рассматриваемая директива эквивалентна опции –Oi компилятора. Но опция –Oi позволяет дополнительно назначить максимальный размер кода, который следует вставлять непосредственно. Например, использование –Oi=c50 укажет компилятору, что непосредственно следует вставлять только те функции, код которых занимает менее 50 байт.
Некоторые функции не могут быть непосредственно помещены в исполняемый код, поскольку используют такие конструкции программного кода, которые не позволяют несколько раз повторить в программе машинный код функции без каких-либо изменений. К таким функциям следует отнести:
- функции с метками в теле функции;
- функции с открытым списком параметров;
- функции, которые содержат ассемблерные строки;
- функции, которые используют локальные статические переменные.
INTO_ROM
предписывает компилятору запомнить переменную в области постоянной памяти, которая в МК HCS08 является флэш-памятью (сегмент ROM_VAR). Пример:
char[]={"MyconstantstringplacedintoROM"};
Эта директива эквивалентна опции –Cc компилятора.
mark
добавляет маркер с именем, который соответствует тексту в строке после директивы #pragma mark. Этот маркер можно увидеть в списке marks list в окне редактора CodeWarrior. Установка маркеров упрощает навигацию по тексту исходного программного кода. Пример:
#pragmamarkVariabledefinition
charva,vb,vc;
//Второймаркерtest
#pragmamarktest
voidtest(intsubject)
NO_ENTRY
запрещает генерировать входной код. Это полезно для функций, записанных на ассемблере. Тогда программист может полностью проверить код функции перед ее вызовом.
Пример:
voidmy_asm_func(void)
{
.......
}
NO_EXIT
запрещает генерировать код возврата из функции. Это полезно для функций, записанных на ассемблере. Тогда программист может полностью проверить программный код функции перед возвратом в функцию вызова.
NO_FRAME
запрещает генерировать код функции. Это полезно для функций, записанных на ассемблере. Тогда программист может полностью проверить программный код функции перед возвратом в функцию вызова. Пример:
#pragmaNO_EXIT
#pragmaNO_FRAME
voidmy_asm_func(void)
{
......
}
NO_RETURN
предписывает компилятору не генерировать команд возврата из функции (RTS, RTI или RTC), поскольку выход из функции не предполагается. Пример:
voidspecial_func(void)
{
......
}
NO_STRING_CONSTR
запрещает специальную обработку символа # компилятором. Эта функция полезна, когда записывают макросы C с использованием команд ассемблера. Пример:
#definelda(x)asmlda#x
Здесь в команде ассемблера присутствует символ #, но он не имеет отношения к конструкциям языка C.
profile
предписывает компилятору так организовать систему функций программы, чтобы оптимизировать профиль приложения. Пример:
#pragmaprofileon
//Выключитьфункциюпрофилированиякомпилятора
#pragmaprofileoff
Мы рассмотрели не все указания со служебным словом #pragma, которые доступны для компилятора HCS08. Для дополнительной информации смотрите документацию и раздел «help» в программе CodeWarrior.
Электронные компоненты Freescale >>>
Подробнее о компании Freescale >>>