Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
Fati_
2 / 2 / 1
Регистрация: 18.06.2015
Сообщений: 65
1

STM32 GCC размещение объектных файлов в RAM используя линкер

28.09.2016, 16:33. Просмотров 2737. Ответов 6

Переезжаю с Keil на System Workbench на базе Eclipse
В старом проекте на Keil в файле линкера спокойно указывала размещение файлов в RAM
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
 
LR_IROM1 0x08000000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00004000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
 
  ER_RAM_FUNC 0x20000000 0x00001000 {  ; load address = execution address
   flashprog.o (+RO)
   ram_funcs.o (+RO)
   stm32f30x_flash.o (+RO)
  }
  RW_IRAM1 0x20001000 UNINIT 0x00009000  {  ; RW data
   .ANY (+RW +ZI)
  }
}
Не понимаю и не могу найти как сделать примерно тоже самое в SW, т.е. разместить flashprog.o, ram_funcs.o и stm32f30x_flash.o в ОЗУ
Пыталась пока разместить только FlashProg.o
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
MEMORY
{
  RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 64K
  ROM (rx)      : ORIGIN = 0x8000000, LENGTH = 512K
}
 
/* Sections */
SECTIONS
{
  /* The startup code into ROM memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >ROM
 
  /* The program code and other data into ROM memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
 
    KEEP (*(.init))
    KEEP (*(.fini))
 
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >ROM
 
/*много кода не совсем понятного мне*/
 
 /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);
 
  /* Initialized data sections into RAM memory */
 
  .FlashProg :
  {
   . = ALIGN(4);
    *FlashProg.o (.text)
  } >RAM
  
  .data : 
  {   
    . = ALIGN(4);
    
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
 
   . = ALIGN(4);    
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> ROM
 
/*еще код*/
Единственная статья по теме на которую я ориентировалась http://www.opennet.ru/docs/RUS/gnu_ld/gnuld-3.html
Но ответа в ней не нашла
Может кто-нибудь знает как это реализовать или может поделиться ссылками?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.09.2016, 16:33
Ответы с готовыми решениями:

STM32 + RAM(no name)
Привет. У себя в "мусоре" нашел несколько плат с чипамя похожими на оперативку, хочу знать какие...

GCC, ar и stm32
Собираю прошивку для МК STM32 В МК в начале флеша должна идти таблица прерываний. Разработчики...

stm32 и внешняя RAM
Добрый день, уважаемые форумчане. Хочу использовать контроллер 32f429 с внешней памятью...

О форматах объектных файлов
Имеется задача сформировать объектный файл для линкера от мелокомягких. Пытался найти его описание,...

Связь объектных файлов!
Доброго времени суток! Подскажите пожалуйста, предположим имеется некий проект, над которым...

6
Voland_
1694 / 1038 / 98
Регистрация: 04.01.2010
Сообщений: 3,517
29.09.2016, 09:31 2
курите мануал GCC в применении к вашей платформе (STM32). Вообще, в GCC это делается указанием атрибута функции, в какую секцию ее нужно размещать. Если вы хотите выстроить список функций по секциям в linker-script'е (который вы привели цитатой) - то нужно компилятору указать, чтобы он компилил функции по отдельности (есть такая опция). Иначе, он не разобъет объектники по функциям, указанным в списке.
ЗЫ: я делал первый вариант, то есть размещал функции с указанием атрибута, типа такого:
Bash
1
__attribute__((section(".spec_region")))
PS: имейте ввиду, что возможно, GCC и будет ожидать функции по указанному адресу, но скопировать их туда перед вызовом скорее всего должны будете вы. В KEIL'е это делает сам загрузчик (библиотека), так что вам этого делать не нужно. А вот в GCC, возможно, придется нестандартные секции инитить самому.
0
Evg
Эксперт CАвтор FAQ
19789 / 7429 / 560
Регистрация: 30.03.2009
Сообщений: 20,705
Записей в блоге: 30
29.09.2016, 10:30 3
Voland_, у ТС'а проблема в том, как писать скрипт для gnu-линкера. Т.е. как для gnu-линкера сделать скрипт, эквивалентный скрипту (не знаю какого)-линкера с предыдущей системы

Людей, одновременно понимающих и то, и другое, скорее всего найти будет сложно. Людей, которые хоть как-то понимают, как писать скрипты под gnu-линкер, скорее всего есть. Для них было бы полезно объяснить, что делает скрипт со старой системы, чтобы стало ясно, что надо писать для gnu-линкера.

Правда по формулировке вопроса у меня есть подозрение, что ТС сам(а) толком не до конца понимает, как оно работало на старой системе. Вопрос, вероятно, звучит так: каким образом из файлов flashprog.o, ram_funcs.o и stm32f30x_flash.o секции RO (read-only) разместить по адресу 0x20000000 и размером блока 0x00001000. Во всяком случае я именно так понимаю первый линкерный скрипт (не факт, что верно). По поводу первого фрагмента более-менее внятных догадок нет, так же нет догадок насчёт того, что такое .ANY

Добавлено через 5 минут
Пример линкерного скрипта для "родной" системы можно посмотреть, запустив

Код
$ gcc ~/hello.c -Wl,--verbose
но он скорее всего окажется бесполезным, т.к. описывает исполняемый файл, а не образ памяти

Скрипты для образа памяти можно посмотреть при сборке ядра linux, но там их вроде бы нету в виде исходников, они генерируются в процессе сборки. В качестве образца должно помочь. При условии, что ТС чётко понимает, что должно быть в конечном итоге, а не так, чтобы "раньше работало, хочу чтобы сейчас тоже было всё хорошо"

Добавлено через 3 минуты
Собственно, вот скрипт от образа ядра linux, может быть на живом примере и методом тыка получится сделать желаемое

http://lxr.free-electrons.com/source/arch/x86/kernel/vmlinux.lds.S
2
Voland_
1694 / 1038 / 98
Регистрация: 04.01.2010
Сообщений: 3,517
29.09.2016, 16:15 4
Лучший ответ Сообщение было отмечено Fati_ как решение

Решение

Цитата Сообщение от Evg Посмотреть сообщение
Voland_, у ТС'а проблема в том, как писать скрипт для gnu-линкера.
та я понял . Потому что и сам раньше сталкивался лишь с расстановкой памяти в KEIL'е, но потом столкнулся с GNU, и теперь понимаю что, где и как происходит. Стратегия действительно разная. В KEIL вы можете раскидывать функции по секциям лишь на уровне объектных файлов. То есть можно сказать линкеру при линковке каждого объектного файла - куда его засовывать. И он (кейл) сам создает базовое хранилище данных, такое как для FLASH, например, и создает "бут-код", который копирует функции, например, из ФЛЕША в РАМ, при старте. Все это происходит автоматически, причем, даже так, что в дебаггере этого не видно.
В GCC система гибче (как вы и представили на примере, но он слишком сложный для проекта ТС), но требует локализации под конкретную платформу, т.к. в каждой системе чипов в общем случае они не совместимы. Соответственно, объяснить - какой именно подход маппирования подходит - значит знать общую структуру проекта, тз, и дальнейшее его развитие. Иначе никак ).

ТС, почитайте еще обсуждение вот здесь. При беглом просмотре в 5секунд я увидел в тексте правильные слова, так что думаю, что там есть то, что вы ищете.
3
Fati_
2 / 2 / 1
Регистрация: 18.06.2015
Сообщений: 65
30.09.2016, 16:58  [ТС] 5
Спасибо за помощь, начинаю разбираться)
Отдельное спасибо, за то что объяснили как все работает

p.s. и за ссылку спасибо, видимо гуглом мне тоже надо научиться пользоваться
0
Fati_
2 / 2 / 1
Регистрация: 18.06.2015
Сообщений: 65
25.07.2017, 12:15  [ТС] 6
долго вспоминала, как это сделала, пока не забыла снова напишу сюда, может кому-то поможет

с помощью аттрибутов разместила отдельные функции в RAM
для этого указала перед объявлением функции аттрибут с указанием имени секции, где какие секции располагаются глядела в файле линкера
C++
1
__attribute__ ((long_call, section (".data")))
то есть получилось примерно так
C++
1
2
__attribute__ ((long_call, section (".data"))) void platform_rewriteSelf(uint8_t *ptr,int size);
__attribute__ ((long_call, section (".data"))) void platform_EraseSector(unsigned int pageAddress);
две таблицы векторов в ROM разместила с помощью файла линкера так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
MEMORY
{
  RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 40K
  ROM (rx)      : ORIGIN = 0x00000000, LENGTH = 256K
  
}
 
/* Sections */
SECTIONS
{
  /* The startup code into ROM memory */
  .text :
  {
    
    . = ALIGN(4);
    KEEP(*(.isr_vector2))
    
    . = 0x3F4; 
     KEEP(*(.BootProc))
 
    . = ALIGN(4);
        
    . = 0x4000; 
    KEEP(*(.isr_vector));
    
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
 
    . = ALIGN(4);
    _etext = .;   
 
  } >  ROM
//................................и тд...........................................//
}
до этого в стартап файле создала вторую таблицу векторов над первой и назвала её - isr_vector2.
Получается в начале располагается новая таблица векторов, затем по фиксированным адресам располагается еще одна секция из startup и следом, также начиная с фиксированного адреса, основная таблица векторов все остальное, описывается это в данном кусочке:
C++
1
2
3
4
5
6
7
8
9
10
. = ALIGN(4);
    KEEP(*(.isr_vector2))
    
    . = 0x3F4; 
     KEEP(*(.BootProc))
 
    . = ALIGN(4);
        
    . = 0x4000; 
    KEEP(*(.isr_vector));
0
Evg
Эксперт CАвтор FAQ
19789 / 7429 / 560
Регистрация: 30.03.2009
Сообщений: 20,705
Записей в блоге: 30
25.07.2017, 12:33 7
Вообще, странно, что всё это работало. Секция .data - это название стандартной секции для размещения данных (а не кода). Т.е. компилятор сам будет помещать данные в секцию .data, что может привести к нежелательным сущностям в секции .data. А далее в линкерном скрипте про .data не было вообще никакого упоминания. Правда там написано "и т.д.", так что может .data там и есть и может быть даже так и должно быть, что функции попадают в неисполняемую секцию с данными. Но как-то это выглядит несколько сомнительно
0
25.07.2017, 12:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.07.2017, 12:33

Проблема в простой математике STM32 и gcc
При выполнении операций преобразования типов и умножения/деления например переменных ftoot на int,...

Декомпиляция объектных файлов и жестокая реальность
Появилось страшно неприодолимое желание подумать над этой темой. Появилось не одно, а вместе с...

STM32, GCC. А как вы боретесь с необъявленным assert_param?
Большинство файлов из библиотеки STM32 Peripheral Library использует макрос ossirt_param(). Но...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru