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

 
 
> Инициализация данных в SDRAM
yanvasiij
сообщение May 6 2016, 11:04
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Доброго времени суток!

Вопрос возможно дурацкий, но все же... Подключаю внешнюю SRAM к STM32 через FMC, компилятор arm-none-eabi. Параметры расположения данных в памяти настраиваю через файлa линковки. Расположить объявленный, например, массив во внешней SRAM труда не составит, но как сделать так, чтобы этот массив можно было инициализировать объявлением?

Пусть есть файл someFile.c, переменные внутри которого расположены во внешней SRAM c помощью файл линковки.

Код
int data[20] = {1,2,3...20};


Инициализация к массиву data[] осуществляется после инициализации SDRAM в файле main.c

Код
extern int *data;

int main (void)
{
    SDRAM_init(); /*< Вот тут память инициализаруется */

   printf ("data: %d\r", data[5]);

  while (1)
  {
    ...
  }
}


Есть ли способ переиницилизировать все массивы данными, которыми они были инициализированы при объявлении, не прибегая к рукопашному присваиванию?

Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
Непомнящий Евген...
сообщение May 6 2016, 11:11
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



инициализацию памяти надо вынести в функцию, которая вызывается после старта (до вызова main и функций из стандартной библиотеки, которые занимаются инициализацией). Т.е. смотрите свой стартап
Go to the top of the page
 
+Quote Post
amiller
сообщение May 6 2016, 11:20
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



По моему сделать так как Вы хотите невозможно.
На примере IAR:
Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main().
А SDRAM у вас становится доступной в main(), после инициализации.
Все остальные способы рукопашные.
Я бы после инициализации внешней памяти добавил функцию типа SDRAM_data_init(), в которой и произвёл это действие.
Для удобства можно объявить массив констант для инициализации во Flash.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение May 6 2016, 11:31
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(Непомнящий Евгений @ May 6 2016, 16:11) *
инициализацию памяти надо вынести в функцию, которая вызывается после старта (до вызова main и функций из стандартной библиотеки, которые занимаются инициализацией). Т.е. смотрите свой стартап



Спасибо за подсказку!
Я заглянул в startup и обнаружил там такую штуку:

CODE

.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:

/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit

CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4

LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4

LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss

/* Call the clock system intitialization function.*/
bl SystemInit
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler


Если я правильно все понял, то мне нужно позвать после SDRAM_init() LoopCopyDataInit():

Код
extern int *data;

int main (void)
{
    SDRAM_init(); /*< Вот тут память инициализаруется */
     LoopCopyDataInit();
   printf ("data: %d\r", data[5]);

  while (1)
  {
    ...
  }
}


В ближайшее время проверю.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение May 6 2016, 12:02
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(amiller @ May 6 2016, 14:20) *
По моему сделать так как Вы хотите невозможно.
На примере IAR:
Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main().
А SDRAM у вас становится доступной в main(), после инициализации.


А в чем проблема инициализировать SDRAM до инициализации переменных в System_init?


Цитата(yanvasiij @ May 6 2016, 14:31) *
Если я правильно все понял, то мне нужно позвать после SDRAM_init() LoopCopyDataInit():

Код
extern int *data;

int main (void)
{
    SDRAM_init(); /*< Вот тут память инициализаруется */
     LoopCopyDataInit();
   printf ("data: %d\r", data[5]);

  while (1)
  {
    ...
  }
}


В ближайшее время проверю.


Это, имхо, может быть чревато. Хотя в чистом Си без наворотов может и прокатит. Более правильно было бы перенести SDRAM_init() в стартап
Go to the top of the page
 
+Quote Post
amiller
сообщение May 6 2016, 12:09
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Непомнящий Евгений @ May 6 2016, 14:32) *
А в чем проблема инициализировать SDRAM до инициализации переменных в System_init?

Можно. Просто я такой способ отнёс к "рукопашным" вариантам.
Наверное это будет даже проще, чем пытаться перенести инициализацию переменных на момент после инициализации SDRAM.
Хотя лично я бы отключил System_init и написал свою функцию копирования переменных, используя адреса, которые формирует линкер.
Просто не люблю присутствия стороннего кода, а System_init - как раз такой.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение May 18 2016, 05:19
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(Непомнящий Евгений @ May 6 2016, 17:02) *
Это, имхо, может быть чревато. Хотя в чистом Си без наворотов может и прокатит. Более правильно было бы перенести SDRAM_init() в стартап


Последовал Вашему совету, и сделал так:

CODE

Reset_Handler:

/* Call the clock system intitialization function.*/
bl SystemInit
bl SDRAM_init /*< Инициализация SDRAM в стартапе до main */

/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit

CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4

LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4

LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss

/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler



Все прекрасно работает, спасибо!
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Sep 13 2016, 10:42
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Спрошу тут, чтобы не плодить веток. Подскажите как разместит в bss опредленного файла в сраме, с помощь линкерскрпита?

Напирмер, в моем ликер файле определены секции памяти:

Код
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
  SDRAM (xrw)      : ORIGIN = 0xD0000000, LENGTH = 31250K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
  CCMRAM (rw)     : ORIGIN = 0x10000000, LENGTH = 64K
}


Что нужно дописать в скрипт, чтобы, например, bss файла heap_1.c распологалось в области SDRAM ?
Go to the top of the page
 
+Quote Post
alx2
сообщение Sep 15 2016, 05:01
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(yanvasiij @ Sep 13 2016, 16:42) *
Спрошу тут, чтобы не плодить веток. Подскажите как разместит в bss опредленного файла в сраме, с помощь линкерскрпита?
Что нужно дописать в скрипт, чтобы, например, bss файла heap_1.c распологалось в области SDRAM ?


Наверное что-то типа
Код
.bss.sdram : {
  heap_1.o(.bss)
} >SDRAM



--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Sep 15 2016, 09:18
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Добавил в скрипт эти строчки, при сборке выдает ошибку:

Код
arm-none-eabi/bin/ld.exe: cannot find heap_1.o
Go to the top of the page
 
+Quote Post
skripach
сообщение Sep 15 2016, 14:29
Сообщение #11


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Нужно определить функцию __low_level_init, или файл, плохо помню, подробнее найдёте в доке на яр.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
alx2
сообщение Sep 16 2016, 06:54
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(yanvasiij @ Sep 15 2016, 15:18) *
Добавил в скрипт эти строчки, при сборке выдает ошибку:

Не понял, зачем Вы это здесь написали...
Вам непонятна суть ошибки? Линкер не нашел указанный в скрипте объектный файл. Такой файл вообще в вашем проекте есть?


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Sep 16 2016, 13:24
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(alx2 @ Sep 16 2016, 11:54) *
Не понял, зачем Вы это здесь написали...
Вам непонятна суть ошибки? Линкер не нашел указанный в скрипте объектный файл. Такой файл вообще в вашем проекте есть?


Такой файл в проекте есть. Мне не понятно, как это линкеру объяснить.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Sep 18 2016, 23:12
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(Непомнящий Евгений @ May 6 2016, 16:02) *
А в чем проблема инициализировать SDRAM до инициализации переменных в System_init?




Это, имхо, может быть чревато. Хотя в чистом Си без наворотов может и прокатит. Более правильно было бы перенести SDRAM_init() в стартап


Да чем чревато?

Я для 6816 в стартап коде чипселекты для памяти настраивал. Оно ведь еще до копирования переменных сегмента .data должно быть сделано.
Go to the top of the page
 
+Quote Post
alx2
сообщение Sep 19 2016, 13:45
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(yanvasiij @ Sep 16 2016, 19:24) *
Такой файл в проекте есть.

Можете показать фрагмент map-файла, где говорится о загрузке этого файла (когда Вы собираете проект без вынесения его .bss в SDRAM)?

Цитата(yanvasiij @ Sep 16 2016, 19:24) *
Мне не понятно, как это линкеру объяснить.

В зависимости от того, отдельный ли это файл, или часть библиотели, либо указанием этого файла в командной строке линкера, либо указанием библиотеки через -l...
Можете показать команду, которой линкуете проект?


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Sep 20 2016, 09:58
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



В map-файле этот файл упоминается в нескольких местах:

Код
....
.text          0x00000000        0x0 ..\obj\heap_1.o
.data          0x00000000        0x0 ..\obj\heap_1.o
.text.vPortInitialiseBlocks
                0x00000000       0x18 ..\obj\heap_1.o
.text.vPortInitialiseBlocks
                0x00000000       0x18 ..\obj\heap_1.o
....
.text.pvPortMalloc
                0x08024048       0x8c ..\obj\heap_1.o
                0x08024048                pvPortMalloc
.text.vPortFree
                0x080240d4       0x14 ..\obj\heap_1.o
                0x080240d4                vPortFree
...
.bss           0x2000eb4c     0xc808 ..\obj\heap_1.o
...
.ARM.attributes
                0x000010dd       0x33 ..\obj\heap_1.o
...
LOAD ..\obj\heap_1.o
...


Команда ликнковки:

Код
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -g -nostartfiles -Wl,-Map=beremizStm32Port.map -O0 -Wl,--gc-sections -Wl, -LD:/_projects/beremizStm32Port/linkscript -Wl,-TD:/_projects/beremizStm32Port/linkscript/stm32f407zg_flash.ld -g -o output.elf ..\obj\vlStm32f4xI2C.o ...много файлов... ..\obj\heap_1.o ...еще много файлов... -lm -lgcc -lc -lnosys -lstdc++
Go to the top of the page
 
+Quote Post
alx2
сообщение Sep 22 2016, 07:17
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(yanvasiij @ Sep 20 2016, 15:58) *
Команда ликнковки:

Код
... ..\obj\heap_1.o ...

Ну вот. Оказывается, файл-то не heap_1.o, а ..\obj\heap_1.o! То есть он не в текущем каталоге, а в ../obj. А в скрипте линкера Вы как этот файл указали?


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Oct 7 2016, 05:58
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(alx2 @ Sep 22 2016, 12:17) *
Ну вот. Оказывается, файл-то не heap_1.o, а ..\obj\heap_1.o! То есть он не в текущем каталоге, а в ../obj. А в скрипте линкера Вы как этот файл указали?


Наконец-то дошли руки проверить. Сделал, с учетом каталога, после Вашего замечания:

Код
  .bss.sdram : {
      ..\obj\heap_4.o(.bss)
  } >SDRAM


Все работает как надо! Спасибо большое!

Правда теперь возникла другая трудность: этот файл используется при компиляции статической библиотеки. При компиляции уже конечного приложения с использованием этой библиотеки, в map-файле этот heap_4 (без переноса его в SDRAM) появляется следующим образом:

Код

.data          0x00000000        0x0 librunTime.a(heap_4.c.obj)
.rodata        0x00000000        0x4 librunTime.a(heap_4.c.obj)

...
.bss           0x200084bc    0x19018 librunTime.a(heap_4.c.obj)


Подскажите, как теперь переместить фрагмент либы в sdram? Пробовал вот так:

Код
  .bss.sdram : {
      librunTime.a(heap_4.c.obj)(.bss)
  } >SDRAM


Выдает ошибку синтаксиса.
Go to the top of the page
 
+Quote Post
alx2
сообщение Oct 10 2016, 10:14
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(yanvasiij @ Oct 7 2016, 11:58) *
Выдает ошибку синтаксиса.

И правильно делает, что выдает. Смотрите в руководстве, как надо указывать ссылки на файлы в архивах:
Код
You can also specify files within archives by writing a pattern matching the archive, a colon, then the pattern matching the file, with no whitespace around the colon.

`archive:file'
    matches file within archive
`archive:'
    matches the whole archive
`:file'
    matches file but not one in an archive


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 25th June 2025 - 02:41
Рейтинг@Mail.ru


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