реклама на сайте
подробности

 
 
> Hello World и GNU ARM Toolchain
menzoda
сообщение Apr 30 2014, 06:07
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 13-09-12
Пользователь №: 73 530



Собственно решил освоить 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. Есть ли у него аналог? То, что можно задать выравнивание в скрипте компоновщика я знаю.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th August 2025 - 23:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01937 секунд с 7
ELECTRONIX ©2004-2016