Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Микропроцессорная техника Сторожок / MPLAB_C30_Руководство пользователя.pdf
Скачиваний:
161
Добавлен:
20.02.2016
Размер:
1.26 Mб
Скачать

Глава 4. Среда периода исполнения

больше. Если известно, что все функции в приложении — ближние, то для компиляции каждого модуля может быть использована опция командной строки по умолчанию -msmall-code, чтобы заставить компилятор генерировать более эффективную форму вызова функции.

Если эта опция по умолчанию неприемлема, доступны следующие альтернативы.

1. Возможно компилировать отдельные модули приложения с опцией командной строки -msmall-code. В этом случае вызовы функций только в таких модулях будут использовать более эффективную форму.

2. Если использована опция -msmall-code, компилятор можно заставить

 

.

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

их атрибутом far.

A

 

3. Вместо применения опций командной строки, воздействующих на модуль

Опция командной строки -msmall-c de отличается от опции -msmall-data тем, что в первом случае компилятор не делает ничего особенного, чтобы проверить, расположены ли функции близко или далеко, тогда как в последнем случае компилятор разместит переменные в заданных секциях.

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

целиком, можно заставить компилятор использовать более эффективную форму вызова, снабдив их объявленияWilsonи определения атрибутом near.

4.7.Расположение кода и данных

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

Как описано в п. 4.3. «Адресноеby пространство», компилятор помещает код в секцию

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

Отклонения могут появиться, когда некоторая функция или переменная должны располагаться по определенному адресу либо внутри заданного диапазона адресов. Наиболее простой путь достичь этого состоит в использовании атрибута address, описанного в п.2.3. «Отличия ключевых слов». Например, чтобы поместить функцию PrintString в адрес 0x8000 программной памяти:

int attribute ((address(0x8000))) PrintString(const char *s);

Аналогично, чтобы поместить переменную Mabonga в адрес 0x1000 памяти данных: int attribute ((address(0x1000))) Mabonga = 1;

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

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

2.Чтобы определить начальный адрес пользовательской секции, вносятся соответствующие добавления в пользовательский сценарий компоновки.

Например, чтобы поместить функцию PrintString в адрес 0x8000 программной памяти сначала объявим ее соответствующим образом в исходном Си коде:

int __attribute__ ((__section__(“.myTextSection“))) PrintString(const char *s);

Атрибут секции определяет, что функция должна быть помещена в секцию с именем

.myTextSection, а не в секцию по умолчанию .text. Он не задает, где определенная пользователем секция будет располагаться. Это надо сделать в

© 2008 Microchip Technology Inc.

DS51284H(ru) стр. 4-5

16-битовый компилятор Си. Руководство

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

.myTextSection 0x8000 :

{

 

*(.myTextSection);

 

 

 

} >program

 

 

 

 

 

Этим задается, что выходной файл должен содержать секцию с именем

 

.myTextSection, со стартовым адресом 0x8000 и содержащую все входные

 

секции с именем .myTextSection. Поскольку в данном примере есть только одна

 

функция PrintString в такой секции, она и расположится по адресу 0x8000

 

программной памяти.

 

 

A

.

 

 

 

 

 

Точно также, для размещения переменной

 

 

Mabonda в адресе 0x1000 памяти

 

данных, первым делом объявим переменную в исходном коде Си как:

 

int __attribute__((__section(“.myDataSection”))) Mabonda = 1;

 

Атрибут секции определяет, что переменная должна быть помещена в секцию с

 

именем .myDataSection, а не в секцию по умолчанию .data. Он не задает, где

 

определенная пользователем секция будет располагаться. Снова это надо сделать

 

в пользовательском сценарии компоновки, как описано ниже. Беря за основу

 

специфический для данного устройства сценарий компоновки, добавляем

 

следующее определение секции:

 

 

 

.myDataSection 0x1000 :

Wilson

 

 

 

{

 

 

 

 

 

 

 

 

 

*(.myDataSection);

 

 

 

} >data

by

 

 

 

 

 

 

 

 

 

Этим задается, что выходной файл должен содержать секцию с именем

 

.myDataSection, со стартовым адресом 0x1000 и содержащую все входные

 

секции с именем .myDataSection. Поскольку в данном примере есть только одна

 

переменная Mabonda в такой секции, она и расположится по адресу 0x1000 памяти

 

данных.

 

 

 

 

4.8.

Программный стек

 

 

 

 

 

В устройствах dsPIC регистр W15 выделяется для использования в качестве

 

программного указателя стека. Все операции процессора со стеком, включая вызов

 

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

 

вверх, в сторону увеличения адресов памяти.

 

 

 

Translated

 

 

 

 

Устройства dsPIC также поддерживают определение переполнения стека. Если регистр предельного значения указателя стека, SPLIM, инициализирован, устройство будет определять переполнение при любой операции со стеком. Если происходит переполнение, процессор инициирует исключение по ошибке стека. По умолчанию это вызывает сброс процессора. Приложение может установить свой обработчик исключительных ситуаций, определив функцию обработки прерывания с именем _StackError. Подробнее см. главу 8 «Прерывания».

Стартовый модуль периода исполнения Си инициализирует указатель стека (W15) и регистр предельного значения указателя стека во время последовательности запуска и инициализации. Начальные значения обычно задаются компоновщиком, который выделяет максимально возможный объем от неиспользованной памяти данных. Расположение стека сообщается в выходном файле карты компоновки. Приложения могут гарантировать, что по крайней мере минимальный стек будет доступен, с помощью опции командной строки компоновщика --stack. Подробнее см. «MPLAB® Assembler, Linker and Utilities for PIC24 MCUs and dsPIC® DSCs User’s Guide» (DS51317).

DS51284H(ru) стр. 4-6

© 2008 Microchip Technology Inc.

Глава 4. Среда периода исполнения

С другой стороны, стек заданного размера может быть выделен с помощью определенной пользователем секции в нестандартном сценарии компоновки. Для использования стартовым модулем периода исполнения определяются два символа: __SP_init и __SPLIM_init:

.stack :

 

{

 

__SP_init = .;

 

. += 0x100;

 

__SPLIM_init = .;

.

. += 8;

} >data

__SP_init определяет начальную величинуA

для указателя стека (W15), а

Wilson

 

__SPLIM_init определяет начальную величину для регистра предельного значения указателя стека (SPLIM). Величина SPLIM_init должна быть по крайней мере на 8 байтов ниже, чем физический предел стека, чтобы оставить место обработчику исключения по переполнению стека. Эта величина должна быть еще уменьшена, чтобы учитывать использование стека собственно обработчиком прерываний, если обработчик исключительной ситуации по ошибке стека установлен. Обработчик прерываний по умолчанию не требует дополнительного объема стека.

4.9.Использование стека в Си

Компилятор Си использует стек для:

by

Размещения автоматических переменных

Передачи аргументов функциям

W15Translated— это указатель стека (SP). Он указывает на вершину стека, которая определяется как первый свободный адрес в стеке.

W14 — это указатель фрейма (FP). Он указывает на текущий фрейм функции. Каждая функция, если требуется, создает новый фрейм на вершине стека, в котором располагаются автоматические и временные переменные. Опция

командной строки компилятора -fomit-frame-pointer может быть использована для ограничения использования FP.Сохранения состояния процессора в функциях обработки прерываний управленияРИС. 4-1. УКАЗАТЕЛИ СТЕКА И ФРЕЙМА

Стек растет

 

 

 

SP (W15)

 

 

 

в сторону

 

 

 

 

 

 

 

увеличения

Фрейм

 

 

FP (W14)

адреса

 

 

функции

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Стартовые модули Си периода исполнения (crt0.o и crt1.o из libpic30.a) инициализируют указатель стека W15, устанавливая его на дно стека, и регистр указатель границы стека, устанавливая его на вершину стека. Стек растет вверх, и,

© 2008 Microchip Technology Inc.

DS51284H(ru) стр. 4-7

16-битовый компилятор Си. Руководство

если он превышает значение указателя границы стека, происходит прерывание по ошибке стека.

Следующий рисунок иллюстрирует последовательность событий при вызове функции. Выполнение команд CALL или RCALL заносит адрес возврата в программный стек. См. рис. 4-2.

РИС. 4-2. КОМАНДЫ CALL ИЛИ RCALL

 

 

 

A

.

 

 

SP (W15)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Адр.возвр.[23:16]

 

 

 

 

 

 

Адр.возвр.[15:0]

 

 

 

 

 

 

 

Wilson

 

 

 

 

 

Стек растет

 

Параметр 1

 

 

 

 

 

в сторону

 

...

 

 

 

 

 

увеличения

 

Параметр n-1

 

 

 

 

 

адреса

 

Параметр n

 

 

 

 

 

 

 

Фрейм

 

 

 

 

FP (W14)

 

 

вызывающей

 

 

 

 

 

 

 

 

 

 

 

 

 

функции

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Теперь вызываемая функция может выделить пространство для своего локального

контекста (рис. 4-3)

by

 

 

 

 

 

 

 

 

 

 

 

 

РИС. 4-3. РАСПРЕДЕЛЕНИЕ СТЕКА ВЫЗЫВАЕМОЙ ФУНКЦИЕЙ

 

 

 

 

 

 

 

 

Translated

 

 

 

 

 

SP (W15)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Локальные и

 

 

 

FP (W14)

 

 

 

временные

 

 

 

 

 

 

 

 

 

 

 

 

 

переменные

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Предыдущий FP

 

 

 

 

 

 

 

Адр.возвр.[23:16]

 

 

 

 

 

 

 

Адр.возвр.[15:0]

 

 

 

 

 

Стек растет

 

Параметр 1

 

 

 

 

 

...

 

 

 

 

 

в сторону

 

 

 

 

 

увеличения

 

Параметр n-1

 

 

 

 

 

адреса

 

Параметр n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Фрейм

 

 

 

 

 

 

 

вызывающей

 

 

 

 

 

 

 

функции

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DS51284H(ru) стр. 4-8

© 2008 Microchip Technology Inc.

Глава 4. Среда периода исполнения

Наконец, в стек убираются используемые вызываемой функцией регистры (рис. 4-4)

РИС. 4-4. СОХРАНЕНИЕ РЕГИСТРОВ ВЫЗЫВАЕМОЙ ФУНКЦИЕЙ

 

 

 

 

Сохр. вызыва-

 

 

 

 

 

SP (W15)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[W14+n] доступ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

емой функцией

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

к локальному

 

 

 

 

 

регистры

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

контексту

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Локальные и

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

A

 

 

 

FP (W14)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

временные

 

 

 

 

 

 

 

 

 

 

 

 

 

[W14–n] доступ

 

 

Стек растет

 

 

переменные

 

 

 

 

 

 

 

 

 

 

 

 

 

 

в сторону

 

 

 

 

 

 

 

к параметрам

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Предыдущий FP

 

 

 

 

 

 

 

увеличения

 

 

Wilson

 

 

 

 

 

функции в стеке

 

 

 

 

Адр.возвр.[23:16]

 

 

 

 

 

 

адреса

 

 

 

 

 

 

 

 

 

 

 

Адр.возвр.[15:0]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Параметр 1

 

 

 

 

 

 

 

 

 

 

...

 

 

 

 

 

 

 

 

 

 

 

Параметр n-1

 

 

 

 

 

 

 

 

 

 

 

Параметр n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Фрейм

 

 

 

 

 

 

 

 

 

 

 

вызывающей

 

 

 

 

 

 

 

 

 

Сиby

 

функции

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4.10. Использование хипа в

 

 

 

 

 

 

 

 

 

долженTranslatedбыть создан. Если единственным используемым файлом является stdout,

Хип периода исполнения в Си — это неинициализированная область памяти данных,

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

управления память из стандартных библиотек Си: calloc, malloc и realloc. Если

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

не создается.

 

 

 

 

 

 

 

 

 

Если Вы хотите использовать динамическое выделение памяти непосредственно, вызывая одну из функций распределения памяти, или косвенно, используя функции ввода/вывода из стандартных библиотек Си, то хип должен быть создан. Чтобы создать хип, надо определить его размера в командной строке компоновщика с помощью опции --heap. Ниже приведен пример выделения 512 байтов для хипа с помощью командной строки:

pic30-gcc foo.c -Wl,--heap=512

Компоновщик располагает хип непосредственно под стеком.

Если вы используете функции ввода/вывода из стандартных библиотек Си, то хип то размер хипа может быть нулевым, т. е. используйте опцию командной строки:

-Wl,--heap=0

Если вы открываете файлы, тогда размер хипа должен включать 40 байтов для каждого одновременно открытого файла. При нехватке памяти хипа функция open будет возвращать признак ошибки. Для каждого файла, использующего буфер, требуется 514 байтов в пространстве хипа. При нехватке памяти хипа для буфера, файл будет открыт в небуферизованном режиме.

© 2008 Microchip Technology Inc.

DS51284H(ru) стр. 4-9

Соседние файлы в папке Микропроцессорная техника Сторожок