Jump to content

    
Sign in to follow this  
yanvasilij

Инициализация данных в SDRAM

Recommended Posts

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

 

Вопрос возможно дурацкий, но все же... Подключаю внешнюю 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)
  {
    ...
  }
}

 

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

 

 

Share this post


Link to post
Share on other sites

инициализацию памяти надо вынести в функцию, которая вызывается после старта (до вызова main и функций из стандартной библиотеки, которые занимаются инициализацией). Т.е. смотрите свой стартап

Share this post


Link to post
Share on other sites

По моему сделать так как Вы хотите невозможно.

На примере IAR:

Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main().

А SDRAM у вас становится доступной в main(), после инициализации.

Все остальные способы рукопашные.

Я бы после инициализации внешней памяти добавил функцию типа SDRAM_data_init(), в которой и произвёл это действие.

Для удобства можно объявить массив констант для инициализации во Flash.

Share this post


Link to post
Share on other sites
инициализацию памяти надо вынести в функцию, которая вызывается после старта (до вызова main и функций из стандартной библиотеки, которые занимаются инициализацией). Т.е. смотрите свой стартап

 

 

Спасибо за подсказку!

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

 

   .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)
  {
    ...
  }
}

 

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

 

Share this post


Link to post
Share on other sites
По моему сделать так как Вы хотите невозможно.

На примере IAR:

Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main().

А SDRAM у вас становится доступной в main(), после инициализации.

 

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

 

 

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

 

extern int *data;

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

  while (1)
  {
    ...
  }
}

 

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

 

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

Share this post


Link to post
Share on other sites
А в чем проблема инициализировать SDRAM до инициализации переменных в System_init?

Можно. Просто я такой способ отнёс к "рукопашным" вариантам.

Наверное это будет даже проще, чем пытаться перенести инициализацию переменных на момент после инициализации SDRAM.

Хотя лично я бы отключил System_init и написал свою функцию копирования переменных, используя адреса, которые формирует линкер.

Просто не люблю присутствия стороннего кода, а System_init - как раз такой.

Share this post


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

 

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

 

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

 

Все прекрасно работает, спасибо!

Share this post


Link to post
Share on other sites

Спрошу тут, чтобы не плодить веток. Подскажите как разместит в 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 ?

Share this post


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

Что нужно дописать в скрипт, чтобы, например, bss файла heap_1.c распологалось в области SDRAM ?

 

Наверное что-то типа

.bss.sdram : {
  heap_1.o(.bss)
} >SDRAM

 

Share this post


Link to post
Share on other sites
Добавил в скрипт эти строчки, при сборке выдает ошибку:

Не понял, зачем Вы это здесь написали...

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

Share this post


Link to post
Share on other sites
Не понял, зачем Вы это здесь написали...

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

 

Такой файл в проекте есть. Мне не понятно, как это линкеру объяснить.

Share this post


Link to post
Share on other sites
А в чем проблема инициализировать SDRAM до инициализации переменных в System_init?

 

 

 

 

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

 

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

 

Я для 6816 в стартап коде чипселекты для памяти настраивал. Оно ведь еще до копирования переменных сегмента .data должно быть сделано.

Share this post


Link to post
Share on other sites
Такой файл в проекте есть.

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

 

Мне не понятно, как это линкеру объяснить.

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

Можете показать команду, которой линкуете проект?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this