Домашняя страница библиотеки_c AVR

Синтаксис языка C

Библиотека языка C GNU glibc

Страницы развития библиотеки_с AVR

Главная страница

Инструкция пользователя

Содержание библиотеки_c

Часто задаваемые вопросы

Содержание по алфавиту

Демонстрационные проекты


 

Секции памяти

Замечания:

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

Weak (слабые) связи

FIXME: потребность обсуждать директиву .weak.

Следующее описывает различные доступные разделы.

Раздел .text

Раздел .text содержит машинные команды – составляющие вашеу программу. Этот раздел разделён на подразделы .initN и .finiN описанные ниже.

Примечание:

Программа avr-size (часть binutils), так же, как в Unix, не объясняет инициализацию пространства .data, которое добавляется к разделу .text, и не знает, сколько конечная программа будет потреблять flash-памяти. Одна потребность добавить значения для обоих, .text и .data (но не .bss), в то время как количество распределенного SRAM является суммой .data и .bss.

Раздел .data

Этот раздел содержит статические данные, которые были определены в вашем коде. Код, подобный следующему будет помещён в раздел .data:

char err_str[] = "Your program has died a horrible death!";
 
struct point pt = { 1, 1 };

Можно указать компоновщику адрес SRAM начала раздела .data. Это можно сделать добавив -Wl,-Tdata,addr к команде avr-gcc. Не этот адрес должен быть смещен, добавлением 0x800000 к реальному адресу SRAM так, чтобы компоновщик знал, что адрес находится в пространстве памяти SRAM. Если Вы хотите, чтобы раздел .data начинался с 0x1100, укажите 0x801100 в адресе компоновщику. [Смещение explained]

Примечание:

При использовании malloc() в приложении (которое может произойти при вызовах из библиотек), требуются.additional adjustments

Раздел .bss

В разделе .bss находятся неинициализированные глобальные или статические переменные.

Раздел .eeprom

Это раздел, в котором сохранены переменные eeprom.

Раздел .noinit

Это разделы - часть раздела .bss. Что делает раздел .noinit special является этим переменные, которые определены также:

int foo __attribute__ ((section (".noinit")));

не будет инициализирован, чтобы обнулить в течение запуска, как был бы нормальные данные .bss.

Только неинициализированные переменные могут быть помещены в раздел .noinit. Таким образом, следующий код приведёт avr-gcc к ошибке:

int bar __attribute__ ((section (".noinit"))) = 0xaa;

Возможно сказать компоновщику, явно где разместить раздел .noinit, добавляя -Wl,--section-start=.noinit=0x802000 к avr-gcc командная строка в связывающейся стадии. Например, предположите, что Вы желаете разместить раздел .noinit по адресу SRAM 0x2000:

 
 $ avr-gcc ... -Wl,--section-start=.noinit=0x802000 ...

Примечание:

Из-за архитектуры Гарварда устройств AVR, вы должны вручную добавить 0x800000 к адресу, который Вы передаете компоновщику как начало раздела. Иначе, компоновщик думает, что Вы хотите поместить раздел .noinit в раздел .text вместо .data/.bss и будет ругаться.

Альтернативно, Вы можете записать ваш собственный сценарий компоновщика, чтобы автоматизировать это. [FIXME: нуждайтесь в примере или касательно к dox для того, чтобы писать сценарии компоновщика.]

Разделы .initN

Эти разделы используются, чтобы определить код запуска от сброса через начало main(). Все они - части раздела .text .

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

Примечание:

Иногда, удобно думать о разделах .initN и .finiN как функциях, но в действительности они - только символьные имена, которые говорят компоновщику, где придержаться кусок кода, который нет функция. Обратите внимание, что примеры для asm и C нельзя назвать(вызвать) как функции и нельзя вскочить.

The .initN sections are executed in order from 0 to 9.

.init0:

Слабо связанный с __init(). Если пользователь определяет __init(), в это будут вскакивать немедленно после сброса.

.init1:

Не используется. Определяется пользователем.

.init2:

В программах на C, слабо связанный инициализировать стек, и очищать __zero_reg__ (r1).

.init3:

Не используется. Определяется пользователем.

.init4:

Для устройств с > 64 KB of ROM, .init4 определяет код, который заботится о копировании содержания .data из flash в SRAM. Для всех других устройств, этот код так же как код, чтобы обнулить .bss раздел загружен от libgcc.a.

.init5:

Не используется. Определяется пользователем.

.init6:

Не используется в программах на C, но используется в конструкциях программ на C++.

.init7:

Не используется. Определяется пользователем.

.init8:

Не используется. Определяется пользователем.

.init9:

Вскакивает main().

Разделы .finiN

Эти разделы используются, чтобы определить код завершения, выполненный после возвращения от main() или запроса к exit(). Все они - подразделы раздела .text .

.finiN Разделы выполнены в порядке по убыванию от 9 до 0.

.finit9:

Не используется. Определяется пользователем. Это – эффективно где запуски _exit().

.fini8:

Не используется. Определяется пользователем.

.fini7:

Не используется. Определяется пользователем.

.fini6:

Unused for C programs, but used for destructors in C++ programs.

.fini5:

Не используется. Определяется пользователем.

.fini4:

Не используется. Определяется пользователем.

.fini3:

Не используется. Определяется пользователем.

.fini2:

Не используется. Определяется пользователем.

.fini1:

Не используется. Определяется пользователем.

.fini0:

Входит в бесконечный цикл после завершения программы и завершения любого _exit () код (выполнение кода в .fini9-> .fini1 разделы).

Использование разделов в коде ассемблера

Пример:

#include <avr/io.h>
 
 .section .init1,"ax",@progbits
 ldi r0, 0xff
 out _SFR_IO_ADDR(PORTB), r0
 out _SFR_IO_ADDR(DDRB), r0

Примечание:

"ax",@progbits говорит ассемблеру, что секция является allocatable ("a"), выполнимая ("x") и содержит данные ("@progbits"). Для более детальной информации относительно директивы .section, см. пользовательское руководство gas.

Использование разделов в коде C

Пример:

#include <avr/io.h>
 
void my_init_portb (void) __attribute__ ((naked)) \
 __attribute__ ((section (".init3")));
 
void
my_init_portb (void)
{
 PORTB = 0xff;
 DDRB = 0xff;
}

Примечание:

Секция .init3 используется в этом примере, поскольку это гарантирует inernal __zero_reg__ был уже настроен. Код, произведенный компилятором мог бы вслепую положиться __zero_reg__ быть действительно 0.

 

Hosted by uCoz