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

 
 
 
Reply to this topicStart new topic
> KEIL и размещение функции в RAM.
Real_Bastard
сообщение Nov 9 2012, 11:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Добрый день.
Необходимо:
1. Разместить функцию write_flash() в ОЗУ.
2. В конец FLASH по заданному адресу вставить массив.

Делаю два файла flash_write.c и flash_data.c пихаю в один функцию записи, в другой данные

Пишу скаттер.
LR_IROM1 0x08000000 0x00020000 { ; load region size_region
ER_IROM1 0x08000000 0x00020000-0x1000 { ; load address = execution address
*.o (RESET, +First)
* (+RO)
.ANY (*)
}
FLASH_DATA 0x0801F000 FIXED 0x1000 {
flash_data.o (*)
}

RW_IRAM1 0x20000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
flash_write.o (+RO)
}
}


Все отлично. Данные в нужном месте. Функция записи-в ОЗУ.

НО!!!! Копия write_flash() кладется в конец FLASH и в начале программы копируется из нее в ОЗУ.
И естественно занимает память моих данных, которые я тоже хочу класть в конец FLASH

Как заставить компилятор класть копию функции в другое место???
Go to the top of the page
 
+Quote Post
Lotor
сообщение Nov 9 2012, 11:39
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Что представляет из себя flash_data.c? Если он пустой, то попробуйте добавить ключ в опция линкера --keep=flash_data.o


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 9 2012, 11:40
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Real_Bastard @ Nov 9 2012, 13:17) *
Как заставить компилятор класть копию функции в другое место???

Можно попробовать разместить свои данные по нужному адресу:

Код
int FlashArray[100] __attribute__((at(0x5000)));

Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 9 2012, 11:42
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Real_Bastard @ Nov 9 2012, 15:17) *
НО!!!! Копия write_flash() кладется в конец FLASH и в начале программы копируется из нее в ОЗУ.
И естественно занимает память моих данных, которые я тоже хочу класть в конец FLASH

Секции накладываются? Покажите map-файл этого безобразия.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Nov 9 2012, 22:31
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Real_Bastard @ Nov 9 2012, 13:17) *
Необходимо:
1. Разместить функцию write_flash() в ОЗУ.
2. В конец FLASH по заданному адресу вставить массив.
...

Мне, как и aaarrr, хотелось бы увидеть map безобразия. Правда, прежде, чем понимать ее и исправлять Ваш скаттер, я бы предложил свое безобразие wink.gif: мной было замечено, что KEIL странно размещает, если куски находятся в рамках одного LOAD REGIONS. Поэтому я взял за правило создавать свой регион под каждый кусок. Думаю, именно это поможет.

Для иллюстрации же приведу скаттер для проекта на EFM32G210F128. EFM32 имеют таковую особенность, что функции записи во Flash ОБЯЗАНЫ быть размещены в RAM (в STM32 подобные функции работают и из Flash, если, конечно, пишут в другие страницы). Похоже на Вашу задачу. Так вот, в библиотеке к EFM32 по работе с Flash ОЗУ-шные функции предварены #pragma:
Код
#pragma arm section code="ram_code"
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes)
{
...
}

А в помощи написано:
Цитата
This function MUST be executed from RAM. For Keil uVision 4 you must define a section called "ram_code" and place this manually in your project's scatter file.

В проекте у меня также есть область данных, помещенная в конец Flash. Правда, в эту область сведены различные константы из разных файлов проекта применением именованной секции. Думаю, такой метод подойдет и Вам:

Код
// где-то в file1.c
volatile const unsigned long
    the_address __attribute__((section ("SETTINGS"), used)) = NODE_ADDRESS;

// а еще в file2.c
volatile const unsigned char
    the_flags __attribute__((section ("SETTINGS"), used)) = 0x10;

А теперь собственно скаттер:

Код
LR_IROM1 0x00000000 0x00000800  {; load region size_region
  ER_IROM1 0x00000000 0x00000800  {; load address = execution address
   *.o (BOOT, +First)
  }
}

LR_IROM2 0x00000800 (0x00020000-0x800)  {; load region size_region
  ER_IROM2 0x00000800 (0x00020000-0x800)  {; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00004000  {; RW data
   *(ram_code)                ; flash erase/write functions
   .ANY (+RW +ZI)
  }
}

LR_IROM3 (0x00020000-512) 512  {    
  ER_IROM3 (0x00020000-512) 512  {  
   *(SETTINGS)
  }
}

На LR_IROM1 внимание не обращайте (заморочки с bootloader в EFM32G).
В LR_IROM2 раздел ER_IROM2 собирает весь код и RO, а в раздел RW_IRAM1 помещена та самая секция ram_code. Установочные константы собраны в LR_IROM3/ER_IROM3, которая "отгрызает" 512 байт сверху Flash.

Проверено, работает (функции, копируемые в ОЗУ, реально находятся где-то внутри основного кода в ER_IROM2).

Надеюсь, мое безобразие поможет.

Сообщение отредактировал KnightIgor - Nov 9 2012, 22:36
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Nov 11 2012, 07:56
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Мар завтра выложу, но в нем flash_write.o находится тока в RAM. О том, что он появляется в конце FLASH я узнал, когда попытался запихать большой массив в секцию flash_data.o . Посмотрел hex. Действительно последние байты заняты копией flash_write.o.
У меня тоже процессор требует код для записи класть только в ОЗУ(Миландр).
Вариант с двумя регионами проверю... Просто привык к GCC, а под Миландр в нем получается плохо. Пришлось осваивать кейл. Теперь мечтаю, как бы поставить эклипс поверх кейла. Привык к удобной IDE(((....
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Nov 11 2012, 14:27
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Real_Bastard @ Nov 11 2012, 09:56) *
Мар завтра выложу, но в нем flash_write.o находится тока в RAM. О том, что он появляется в конце FLASH я узнал, когда попытался запихать большой массив в секцию flash_data.o .

Очевидно же, что код функции не может быть "тока в RAM", т.к. появиться там после сброса он может лишь из flash в результате копирования на этапе инициализации библиотеки. Почему же копия сунулась на секцию flash_data.o, было бы интересно выяснить, но как я уже писал, это, видимо, связано с какой-то особенностью интерпретации скаттера в KEIL. Когда я в свое время наткнулся на похожие непонятки, я, не докапываясь до причин и по совету из какого-то форума, начал под каждый изолированный кусок кода делать свой LR. Это работает уже в нескольких проектах. "Так почему бы Вам туда не съездить?" (с) М.Жванецкий.

Сообщение отредактировал KnightIgor - Nov 11 2012, 14:30
Go to the top of the page
 
+Quote Post
редактор
сообщение Nov 12 2012, 06:37
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Тоже пишу под Миландр в Keil. Правкой scatter-файла не занимался ни разу. Функции, которые надо разместить в ОЗУ, собираю в отдельный файл и в свойствах файла (вызывается по правой кнопке мыши) указываю разместить в IRAM1. Остальное Keil сам делает, и весьма корректно.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Nov 12 2012, 09:30
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



CODE
=======================================================================
===

Memory Map of the image

Image Entry point : 0x080000c1

Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00020038, Max: 0x00020000, ABSOLUTE)

Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00001498, Max: 0x0001f000, ABSOLUTE)

Base Addr Size Type Attr Idx E Section Name Object

0x08000000 0x000000c0 Data RO 3 RESET startup_mdr32fx.o
0x080000c0 0x00000008 Code RO 251 * !!!main c_w.l(__main.o)
0x080000c8 0x00000034 Code RO 408 !!!scatter c_w.l(__scatter.o)
0x080000fc 0x0000001a Code RO 410 !!handler_copy c_w.l(__scatter_copy.o)
0x08000116 0x00000002 PAD
0x08000118 0x0000001c Code RO 412 !!handler_zi c_w.l(__scatter_zi.o)
0x08000134 0x00000006 Code RO 278 .ARM.Collect$$libinit$$00000000 c_w.l(libinit.o)
......
0x08000158 0x00000006 Code RO 330 .ARM.Collect$$rtexit$$00000004 c_w.l(rtexit2.o)
0x0800015e 0x00000002 PAD
0x08000160 0x00000040 Code RO 4 .text startup_mdr32fx.o
0x080001a0 0x00000160 Code RO 10 .text main.o
0x08000300 0x000002a0 Code RO 63 .text mdr32f9qx_port.o
0x080005a0 0x000006e8 Code RO 127 .text mdr32f9qx_rst_clk.o
0x08000c88 0x000000dc Code RO 181 .text system_mdr32f9qx.o
0x08000d64 0x00000006 Code RO 249 .text c_w.l(heapauxi.o)
0x08000d6a 0x0000004a Code RO 269 .text c_w.l(sys_stackheap_outer.o)
0x08000db4 0x0000000c Code RO 271 .text c_w.l(exit.o)
0x08000dc0 0x00000008 Code RO 279 .text c_w.l(libspace.o)
0x08000dc8 0x00000008 Code RO 337 .text c_w.l(rt_fp_status_addr_intlibspace.o)
0x08000dd0 0x0000000c Code RO 341 .text c_w.l(sys_exit.o)
0x08000ddc 0x00000002 Code RO 352 .text c_w.l(use_no_semi.o)
0x08000dde 0x00000000 Code RO 354 .text c_w.l(indicate_semi.o)
0x08000dde 0x0000000a Ven RO 414 Veneer$$Code anon$$obj.o
0x08000de8 0x0000000e Code RO 325 x$fpl$fpinit fz_ws.l(fpinit.o)
0x08000df6 0x00000002 PAD
0x08000df8 0x00000020 Data RO 406 Region$$Table anon$$obj.o
0x08000e18 0x00000017 Data RW 12 .data main.o
0x08000e2f 0x00000001 PAD
0x08000e30 0x00000004 Data RW 182 .data system_mdr32f9qx.o
0x08000e34 0x00000060 Zero RW 280 .bss c_w.l(libspace.o)
0x08000e94 0x00000004 PAD
0x08000e98 0x00000200 Zero RW 2 HEAP startup_mdr32fx.o
0x08001098 0x00000400 Zero RW 1 STACK startup_mdr32fx.o


Execution Region FLASH_DATA (Base: 0x0801f000, Size: 0x00001000, Max: 0x00001000, ABSOLUTE, FIXED)

Base Addr Size Type Attr Idx E Section Name Object

0x0801f000 0x00001000 Data RO 224 .constdata flash_data.o

Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00000038, Max: 0x00008000, ABSOLUTE)

Base Addr Size Type Attr Idx E Section Name Object

0x20000000 0x00000038 Code RO 232 .text flash_write.o




и ругань компилятора на попытку разместить 0х1000 байт в flash_dataю
Mem_test.axf: Error: L6220E: Load region LR_IROM1 size (131128 bytes) exceeds limit (131072 bytes). Region contains 11 bytes of padding and 10 bytes of veneers (total 21 bytes of linker generated content).
собственно нехватает 0х38-размер flash_data.o

CODE
LR_IROM1 0x08000000 0x00020000-0x100 { ; load region size_region
ER_IROM1 0x08000000 0x00020000-0x1000 { ; load address = execution address
*.o (RESET, +First)
* (+RO)
.ANY (*)

}

RW_IRAM1 0x20000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
flash_write.o (+RO)
}
}

LR_IROM2 (0x0801F000) 0x1000 {
ER_IROM3 0x0801F000 0x1000 {
flash_data.o (*)
}
}


Работает идеально. СПАСИБО!!!

Сообщение отредактировал Real_Bastard - Nov 12 2012, 09:23
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Nov 13 2012, 10:09
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Точнее так, а то он стек во флеш пихает)))))
CODE
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00020000-0x100 { ; load region size_region
ER_IROM1 0x08000000 0x00020000-0x1000 { ; load address = execution address
*.o (RESET, +First)
* (+RO)
.ANY (+RO)

}

RW_IRAM1 0x20000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
mdr32f9qx_eeprom.o (+RO)
}
}

LR_IROM2 (0x0801F000) 0x1000 {
ER_IROM3 0x0801F000 0x1000 {
flash_data.o (*)
}
}
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 07:43
Рейтинг@Mail.ru


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