Замечания:
Необходимо перечислить все разделы, которые являются доступными для avr.
Weak (слабые) связи
FIXME: потребность обсуждать директиву .weak.
Следующее описывает различные доступные разделы.
Раздел .text содержит машинные команды – составляющие вашеу программу. Этот раздел разделён на подразделы .initN и .finiN описанные ниже.
Примечание:
Программа
avr
-
size
(часть
binutils),
так же, как в Unix, не
объясняет
инициализацию
пространства
.data,
которое
добавляется
к разделу .text, и не
знает,
сколько
конечная
программа
будет
потреблять flash-памяти.
Одна
потребность
добавить
значения для
обоих, .text и .data
(но не .bss),
в то время
как
количество
распределенного
SRAM является
суммой .data и .bss.
Этот
раздел содержит
статические
данные,
которые были
определены в
вашем коде.
Код, подобный следующему будет помещён в раздел .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 находятся неинициализированные глобальные или статические переменные.
Это раздел, в котором сохранены переменные eeprom.
Это разделы - часть раздела .bss. Что делает раздел .noinit special является этим переменные, которые определены также:
int foo __attribute__ ((section (".noinit")));
не будет инициализирован, чтобы обнулить в течение запуска, как был бы нормальные данные .bss.
Только неинициализированные переменные могут быть помещены в раздел .noinit. Таким образом, следующий код приведёт avr-gcc к ошибке:
int bar __attribute__ ((section (".noinit"))) = 0xaa;
Возможно
сказать
компоновщику,
явно где разместить
раздел .noinit, добавляя -
Wl
,--
section
-
start
=.
noinit
=0
x
802000
к avr-gcc командная
строка в
связывающейся
стадии. Например,
предположите,
что Вы
желаете разместить
раздел .noinit по адресу SRAM 0x2000:
$ avr-gcc ... -Wl,--section-start=.noinit=0x802000 ...
Из-за архитектуры Гарварда устройств AVR, вы должны вручную добавить 0x800000 к адресу, который Вы передаете компоновщику как начало раздела. Иначе, компоновщик думает, что Вы хотите поместить раздел .noinit в раздел .text вместо .data/.bss и будет ругаться.
Альтернативно, Вы можете записать ваш собственный сценарий компоновщика, чтобы автоматизировать это. [FIXME: нуждайтесь в примере или касательно к dox для того, чтобы писать сценарии компоновщика.]
Эти разделы используются, чтобы определить код запуска от сброса через начало 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().
Эти разделы используются, чтобы определить код завершения, выполненный после возвращения от 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.
Пример:
#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.