Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Hello World и GNU ARM Toolchain
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
menzoda
Собственно решил освоить GNU инструментарий, раньше пользовался изделием от ARM (тот который в Keil MDK). Для начала, чтобы было от чего отталкиваться, создал простенький проект в Keil, состоящий из одного ассемблерного файла и скрипта компоновщика.

Startup.s:
CODE

AREA StackArea, NOINIT, READWRITE, ALIGN=3
StackBase SPACE 100
StackTop

THUMB
PRESERVE8

AREA VectorTable, DATA, READONLY
DCD StackTop
DCD HandleReset
DCD HandleNMI
DCD HandleHardFault
DCD HandleMemManage
DCD HandleBusFault
DCD HandleUsageFault
DCD 0
DCD 0
DCD 0
DCD 0
DCD HandleSVC
DCD 0
DCD 0
DCD HandlePendSV
DCD HandleSysTick

AREA IntHandlers, CODE
HandleReset
HandleNMI
HandleHardFault
HandleMemManage
HandleBusFault
HandleUsageFault
HandleSVC
HandlePendSV
HandleSysTick PROC
B .
ENDP
END


Scatter:
CODE

IROM 0x0 0x80000
{
IROM +0x0
{
* (VectorTable, +First)
* (+RO)
}

IRAM +0x0
{
* (+RW +ZI)
* (StackArea)
}
}


Собственно ничего сложного. Таблица векторов прерываний неполная, секции в памяти я расположил подряд, но мне главное было получить бинарный образ на выходе, запускать это я не собирался. В итоге с помощью команды fromelf.exe --bin , я получил такой вот образ:

CODE

00: AC 00 00 00
04: 41 00 00 00
08: 41 00 00 00
0C: 41 00 00 00
10: 41 00 00 00
14: 41 00 00 00
18: 41 00 00 00
1C: 00 00 00 00
20: 00 00 00 00
24: 00 00 00 00
28: 00 00 00 00
2C: 41 00 00 00
30: 00 00 00 00
34: 00 00 00 00
38: 41 00 00 00
3C: 41 00 00 00
40: FE E7 00 00


1. Сразу же первый вопрос. Стек требует выравнивания по границе в восемь байт. Раньше я как-то не задумывался об этом, но ведь мы работаем с вершиной стека, соответственно задав размер стека равным, например 77, я нарушу выравнивание указателя вершины стека. То есть нужно еще и следить за размером, чтобы он был кратным восьми? Или можно игнорировать это дело, но тогда зачем вообще выравнивать основания стека?

Едем дальше. Попытался воспроизвести то же самое, но с помощью гнусного набора инструментов.

Startup.s:
CODE

.syntax unified
.section ".stack", "w"
StackBase:
.space 100
StackTop:

.section ".reset"
.4byte StackTop
.4byte HandleReset
.4byte HandleNmi
.4byte HandleHardFault
.4byte HandleMemManage
.4byte HandleBusFault
.4byte HandleUsageFault
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte HandleSvc
.4byte HandleDebugMon
.4byte 0
.4byte HandlePendSV
.4byte HandleSysTick

.section ".text"
HandleReset:
HandleNmi:
HandleHardFault:
HandleMemManage:
HandleBusFault:
HandleUsageFault:
HandleSvc:
HandleDebugMon:
HandlePendSV:
HandleSysTick:
b .
.end


Linker.ld:
CODE

SECTIONS
{
.rom :
{
* (.reset)
* (.text)
}

.ram :
{
* (.data)
* (.bss)
* (.stack)
}
}


Бинарный образ:
CODE

00: 64 00 00 00
04: 40 00 00 00
08: 40 00 00 00
0C: 40 00 00 00
10: 40 00 00 00
14: 40 00 00 00
18: 40 00 00 00
1C: 00 00 00 00
20: 00 00 00 00
24: 00 00 00 00
28: 00 00 00 00
2C: 40 00 00 00
30: 40 00 00 00
34: 00 00 00 00
38: 40 00 00 00
3C: 40 00 00 00
40: FE E7 00 00
44: 00 00 00 00
...
A8: 00 00 00 00


На указатель стека не обращайте внимание, это я эксперементировал с его (стека) расположением, поэтому бинарник не соответствует скрипту компоновщика и ассемблерному файлу. Я бы пересобрал заново, но сейчас на работе и не имею такой возможности. В любом случае вопросы будут не про это. Да, собирал с вот такими опциями:
Код
arm-none-eabi-as.exe -mcpu=cortex-m3 -mthumb -Wall
arm-none-eabi-ld.exe -T Linker.ld
arm-none-eabi-objcopy.exe -O binary


Собственно вопросы:
2. Почему проект, собранный с помощью Keil ставит в таблице векторов прерываний адрес, указывающий на второй байт инструкции (0xE7), тогда как у GNU там находится адрес первого байта инструкции (0xFE)?

3. В случае ARM, именование execution region в скрипте компоновщика может быть произвольным (IROM, IRAM), это верно с выходными секциями GNU (".irom", ".iram")? А то во всех примерах, которые я видел, они указывались как стандартные ".text", ".bss", и ".data".

4. В случае ARM, для секции со стеком мы указываем атрибут NOINIT, чтобы компоновщик ее не инициализировал, а просто выделил под нее место. GNU же заполнил ее нулями, что ожидаемо, потому что я ничего похожего на NOINIT не указывал. Так вот есть ли у секции атрибут аналогичный NOINIT, или это указывается в скрипте компоновщика, если да, то как?

5. Тот же вопрос про атрибут ALIGN. Есть ли у него аналог? То, что можно задать выравнивание в скрипте компоновщика я знаю.
demiurg_spb
Цитата(menzoda @ Apr 30 2014, 10:07) *
Не мучайте себя так. Возьмите примеры посвежее из demo-проектов для ScmRtos.
Там вам и скрипты и стартапы и мейк-файлы...
menzoda
Я не мучаю себя, я разбираюсь. Не могу взять что-то чужое, не понимая что там написано.
RabidRabbit
2. Пишите руками
.4byte HandleReset + 1
Keil - он хитрый, а в GNU - что написал, то и будет sm.gif

По остальным вопросам - согласен с demiurg_spb - скачайте примеры и с ними разбирайтесь. Или читайте документацию - она для GNU доступна и обширна sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.