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

 
 
> GNU Tools ARM Embedded неопределённые ссылки из файла startup_ARMCM3.S
vovo
сообщение Apr 7 2017, 12:46
Сообщение #1





Группа: Участник
Сообщений: 9
Регистрация: 25-02-09
Пользователь №: 45 366



Доброго времени дня!
Никак не могу найти решение проблемы.

linking...
./gnu/startup_armcm3.o: In function `Reset_Handler':
E:\ARM_F/SRC/startup_ARMCM3.S:172: undefined reference to `__copy_table_start__'
E:\ARM_F/SRC/startup_ARMCM3.S:173: undefined reference to `__copy_table_end__'
E:\ARM_F/SRC/startup_ARMCM3.S:204: undefined reference to `__data_start__'
E:\ARM_F/SRC/startup_ARMCM3.S:205: undefined reference to `__data_end__'
E:\ARM_F/SRC/startup_ARMCM3.S:233: undefined reference to `__zero_table_start__'
E:\ARM_F/SRC/startup_ARMCM3.S:234: undefined reference to `__zero_table_end__'
collect2.exe: error: ld returned 1 exit status

Toolchain GNU Tools ARM Embedded\5.4 2016q3

Файл startup_ARMCM3.S взят из папки c тулчейном. Включён взамен стартового файла рабочего проекта, собранного на ARM MDK.
Проект на GCC успешно компилится но не хочет собираться по указанным выше причинам. Вопрос - чего в супе не хватает?
Это ведь области RAM, которые при старте инициализируются или обнуляются, что не так?

Спасибо.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Aaron
сообщение Apr 7 2017, 13:49
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



заимствовали стартап файл и линкер-файл от разных проектов? нотация имён необычная.
ищите в ld-файле что-то вида:
Код
    _etext = .;
    .data :                        /* AT makes the LMA follow on in the binary image */
    {
        . = ALIGN(4);
        _sidata = _etext;        /* start of initialized data label */
        _sdata = .;                /* start of .data label */
        KEEP( *(.data) )
        KEEP( *(.data.*) )
        . = ALIGN(4);
        _edata = .;                /* end of .data label */
    } > RAM AT > FLASH

    /* .bss section - uninitialized data */
    .bss :
    {
        . = ALIGN(4);
        _sbss = .;                /* start of .bss label (for startup) */
         *(.bss)
         *(.bss.*)
         *(COMMON)
        . = ALIGN(4);
        _ebss = .;                /* end of .bss label (for startup) */
        _end = .;                /* end of used ram (start of free memory, for malloc) */
        __end = .;                /* the same */
        end = .;                /* the same */
    } > RAM
и приводите имена в ссылках на память (строчки вида _end = .wink.gif к вашим именам из ассемблерного файла

Сообщение отредактировал IgorKossak - Apr 7 2017, 14:02
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!
Go to the top of the page
 
+Quote Post
vovo
сообщение Apr 7 2017, 14:04
Сообщение #3





Группа: Участник
Сообщений: 9
Регистрация: 25-02-09
Пользователь №: 45 366



Линкер файл я даже не цеплял. Думал, по аналогии с MDK, что по умолчанию что то должно быть. Стартап взят отсюда C:\Program Files (x86)\GNU Tools ARM Embedded\5.4 2016q3\share\gcc-arm-none-eabi\samples\startup, тул скачан с ARMа. Я посмотрел *.ld файл, предлагаемый в тулчейне, там тоже нет этих символов, кроме __bss_start__, этот совпадает. Ok, спасибо за подсказки, пошёл изучать скрипты линкера.
Go to the top of the page
 
+Quote Post
vovo
сообщение Apr 11 2017, 07:50
Сообщение #4





Группа: Участник
Сообщений: 9
Регистрация: 25-02-09
Пользователь №: 45 366



Ещё раз благодарю за подсказки, с multi RAM разбрался. А вот как быть с multi ROM? Только когда секция FLASH едина, только тогда правильно выставляестя топ стека и стартовый переход. А вот стоит мне порезать FLASH на куски, то секция векторов прерываний и стартовый код ложатся таки куда надо, а вот топ стека адрес перехода на стартовый код нулевые выходят. И параллельно вопрос- а что в GCC нет возможности одной директивой все функции одного файла исходника отправить в свою секцию, только каждой функции __attribute__ прикручивать?
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Apr 11 2017, 09:50
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(vovo @ Apr 11 2017, 10:50) *
все функции одного файла исходника отправить в свою секцию, только каждой функции __attribute__ прикручивать?

В скрипте линкера. В нужную секцию добавить:
*<имя файла>.o(.text .text* .rodata .rodata.* .constdata .constdata.*)
потом в той секции откуда взят файл:
*(EXCLUDE_FILE(*<имя файла>.o ...) .text*)
Имена секций поправьте сами.
Go to the top of the page
 
+Quote Post
vovo
сообщение Apr 11 2017, 10:54
Сообщение #6





Группа: Участник
Сообщений: 9
Регистрация: 25-02-09
Пользователь №: 45 366



Да, по второму вопросу протупил, виноват, исправлюсь. Хотя..., а если это библиотека, я не знаю имён модулей, но хочу разместить её в определённом фрагменте памяти?
А вот по первому
CODE
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH1 (rx) : ORIGIN = 0x0, LENGTH = 0x1000

FLASH2 ® : ORIGIN = 0x1000, LENGTH = 0x1000
FLASH3 (rx) : ORIGIN = 0x2000, LENGTH = 0x80000 - 0x2000

RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 8K */
RAM2 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 8K */
}

/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)

SECTIONS
{

.text0 0x0:
{
KEEP(*(.isr_vector))
KEEP(*(.Reset_Handler_s))
KEEP(*(.init))
KEEP(*(.fini))
} > FLASH1
.dfdata 0x1000:
{
/*. = 0x1000;*/
*(.ARM.__AT_0x00001000)
} > FLASH2
.text 0x2000 :
{
/*. = 0x2000;*/
*(.text*)

/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)

/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)

*(.rodata*)

KEEP(*(.eh_frame*))
} > FLASH3

__exab_start = .;
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH3
__exab_end = .;

__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH3
__exidx_end = .;

/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH3
*/

/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH3
*/

__etext = .;

.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);

. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);


. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);

KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;

} > RAM

.bss_RAM2 : ALIGN(4)
{
PROVIDE(__start_bss_RAM2 = .) ;
*(LWIP_ram_heap*)
*(.bss.$RamAHB32*)
. = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
PROVIDE(__end_bss_RAM2 = .) ;
} > RAM2
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM2

/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM2

/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
/*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")*/
}

Вот так мне нужно, но не работает
А вот так работает
CODE

/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 128K */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 8K */
RAM2 (rwx) : ORIGIN = 0x200c7000, LENGTH = 0x8000 /* 8K */
}

/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)

SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)

KEEP(*(.init))
KEEP(*(.fini))

/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)

/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)

*(.rodata*)

KEEP(*(.eh_frame*))
} > FLASH

.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH

__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;

/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH

/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH

__etext = .;

.data : AT (__etext)
{
__data_start__ = .;
*(LWIP_ram_heap)
__data_end__ = .;

} > RAM

__etext2 = __etext + SIZEOF(.data);
.data2 : AT (__etext2)
{
__data2_start__ = .;
*(vtable)
*(.data*)

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);

. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);


. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);

KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data2_end__ = .;

} > RAM2

.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

.bss2 :
{
. = ALIGN(4);
__bss2_start__ = .;
*(COMMON)
. = ALIGN(4);
__bss2_end__ = .;
} > RAM2

.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM2

/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM2

/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}


Сообщение отредактировал vovo - Apr 11 2017, 11:15
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 11 2017, 11:20
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (vovo @ Apr 11 2017, 13:54) *
Вот так мне нужно, но не работает
Но вы так и не сказали, зачем вам это нужно.

Зачем вы дважды указываете адрес - при задании региона и при объявлении выходной секции?
Замените
CODE
    .text0 0x0:
    {
        ......
    } > FLASH1

на
CODE
    .text0:
    {
        ......
    } > FLASH1

и с остальными секциями аналогично.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
vovo
сообщение Apr 11 2017, 13:13
Сообщение #8





Группа: Участник
Сообщений: 9
Регистрация: 25-02-09
Пользователь №: 45 366



Цитата(Сергей Борщ @ Apr 11 2017, 14:20) *
Но вы так и не сказали, зачем вам это нужно.

Зачем вы дважды указываете адрес - при задании региона и при объявлении выходной секции?
Замените
Код
    .text0 0x0:
    {
        ......
    } > FLASH1

на
Код
    .text0:
    {
        ......
    } > FLASH1

и с остальными секциями аналогично.

Попробовал, в строке где скобка открывающая, линкер выдаёт ошибку синтаксиса.
Код
c:/program files (x86)/gnu tools arm embedded/5.4 2016q3/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld.exe:./SRC/gcc.ld:55: syntax error

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

Сообщение отредактировал vovo - Apr 11 2017, 13:22
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- vovo   GNU Tools ARM Embedded неопределённые ссылки из файла startup_ARMCM3.S   Apr 7 2017, 12:46
- - DmitryM   А в линкер-файле эти регионы определены и именуютс...   Apr 7 2017, 13:27
|- - Сергей Борщ   QUOTE (vovo @ Apr 11 2017, 10:50) А вот с...   Apr 11 2017, 09:09
||- - Сергей Борщ   QUOTE (vovo @ Apr 11 2017, 16:13) Попробо...   Apr 11 2017, 15:20
||- - vovo   Цитата(Сергей Борщ @ Apr 11 2017, 18:20) ...   Apr 11 2017, 17:04
||- - Сергей Борщ   QUOTE (vovo @ Apr 11 2017, 20:04) загрузч...   Apr 11 2017, 19:08
|- - Kabdim   Цитата(vovo @ Apr 11 2017, 13:54) Да, по ...   Apr 11 2017, 12:30
- - vovo   Хорошая ссылка, гораздо гораздее чем штатный pdf, ...   Apr 12 2017, 14:37


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

 


RSS Текстовая версия Сейчас: 31st July 2025 - 00:17
Рейтинг@Mail.ru


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