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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Cortex M4F проблема с памятью
Golikov A.
сообщение Apr 15 2015, 07:52
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

Но его можно потаскать по памяти
то есть сначала в конец задвинуть, потом протестить начала памяти, а потом передвинуть на начало и протестить конец
Go to the top of the page
 
+Quote Post
johnshadow
сообщение Apr 15 2015, 08:53
Сообщение #17


Участник
*

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



Цитата(vanek18 @ Apr 14 2015, 12:48) *
А вот про менеджер памяти можно поподробнее? Я всегда память распределял стандартными средствами keil.


Брал в этой теме.
Остаток памяти для первого банка берется из переменных в скрипте линковщика (пример для lpc1754):
CODE
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
/*INCLUDE "memory.ld"*/

MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00004000
ram1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x00004000
}

_eram = 0x10000000 + 0x00004000;

/* Section Definitions */
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
KEEP(*(.hware))
KEEP(*(.offset))
KEEP(*(.templ))
KEEP(*(.swvers1))
KEEP(*(.swvers2))
KEEP(*(.swvers3))

*(.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*))
} > rom

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

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

. = ALIGN(4);
_etext = .;
_sidata = .;

.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = .;
} > ram

/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
_sbss = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > ram

/* heap section */
.heap (COPY):
{
__Heap_Start = .;
_end = __Heap_Start;
end = __Heap_Start;
*(.heap*)
__Heap_End = .;

} > ram

/* .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 */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > ram

/* 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(.co_stack);
PROVIDE(__stack = __StackTop);

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

.data_dma (COPY): ALIGN(4)
{
__data_dma_start = .;
KEEP(*(.dma_vars))
} > ram1
. = ALIGN(4);

__data_dma_finish = .;
}

а дальше:

Код
#define SECOND_BANK_END (0x2007FFFFUL)

void init_system_heap(void) {
    extern unsigned long __Heap_Start;
    extern unsigned long __Heap_End;
    extern unsigned long __data_dma_finish;
    system_heap.start = (heap_mcb *) (&__Heap_Start);
    system_heap.freem = (heap_mcb *) (&__Heap_Start);
    system_heap.hsize = (unsigned long) (&__Heap_End) - (unsigned long) (&__Heap_Start) + (unsigned long) 1;

    heapinit(&system_heap);
    heapadd(&system_heap, (heap_mcb *) (&__data_dma_finish), (unsigned long) SECOND_BANK_END - (unsigned long) (&__data_dma_finish));
}

второй банк добавляю соответственно после памяти выделенной для DMA буферов (__data_dma_finish) и до конца второго банка. Для себя добавлял еще обертки для freeRTOS. Только сейчас понял что SECOND_BANK_END можно считать из ram1_ORIGIN+ram1_LENGTH.
Секция .co_stack соответственно используются для стека - т.к. я использую rtos то этот стек используется насколько я понимаю только функцией main до старта шедулера и в обработчиках прерываний).
Код из startup_LPC17xx.c:
Код
#define STACK_SIZE       0x00000100      /*!< The Stack size suggest using even number   */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];

......
__attribute__ ((used,section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
    /*----------Core Exceptions------------------------------------------------ */
    (void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer         */
    Reset_Handler, /*!< Reset Handler                               */
    NMI_Handler, /*!< NMI Handler                                 */
    HardFault_Handler, /*!< Hard Fault Handler                          */
    MemManage_Handler, /*!< MPU Fault Handler                           */
    BusFault_Handler, /*!< Bus Fault Handler                           */
    UsageFault_Handler, /*!< Usage Fault Handler                         */
    0,0,0,0, /*!< Reserved                                    */
    SVC_Handler, /*!< SVCall Handler                              */
    DebugMon_Handler, /*!< Debug Monitor Handler                       */
    0, /*!< Reserved                                    */
    PendSV_Handler, /*!< PendSV Handler                              */
    SysTick_Handler, /*!< SysTick Handler                             */
....


Сообщение отредактировал IgorKossak - Apr 15 2015, 14:14
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
vanek18
сообщение Apr 15 2015, 09:49
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 30-01-15
Пользователь №: 84 841



Цитата(Golikov A. @ Apr 15 2015, 07:52) *
на кучу нет, можно вообще без нее,
А стек какой-то минимум имеет, в нем локальные переменные живут и между вызовами функций регистры-данные сохраняются.

Но его можно потаскать по памяти
то есть сначала в конец задвинуть, потом протестить начала памяти, а потом передвинуть на начало и протестить конец

Я конечео имел в виду про максимальный размер...ну да ладно,расскажу что я щас сделал.
Итак, написал прогу которая просто печатает через UART "Hello world" biggrin.gif причем без использования retarget,напрямую через регистры.
Выявил максимальный размер стэка при котором прога работает
Он оказался равным 0х7BBF.
Затем прибавляю 1 байт(стэк = 0x7BC0) прога не работает.
Следущее, сдвигаю область памяти RAM на 64 КБайт, выставляю размер стека 0x7FBF(это как раз 0x7BBF + 0x400 байт урезанных вначале области памяти)-программа работает.
Увеличиваю стек на 1 байт - не работает.
Файл с картой памяти прилагается.
Что за беда?
Кстати как стэк по памяти можно потаскать?
Прикрепленный файл  Mem_test.txt ( 2.12 килобайт ) Кол-во скачиваний: 112


Сообщение отредактировал vanek18 - Apr 15 2015, 09:53
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 15 2015, 10:15
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(vanek18 @ Apr 15 2015, 12:49) *
Итак, написал прогу которая просто печатает через UART "Hello world" biggrin.gif причем без использования retarget,напрямую через регистры.
Выявил максимальный размер стэка при котором прога работает
Он оказался равным 0х7BBF.
Затем прибавляю 1 байт(стэк = 0x7BC0) прога не работает.

Какой ужас! Как можно так жить? К чему эти пляски с бубном?

Цитата(Golikov A. @ Apr 15 2015, 10:52) *
Но его можно потаскать по памяти
то есть сначала в конец задвинуть, потом протестить начала памяти, а потом передвинуть на начало и протестить конец

Есть гораздо более цивилизованный способ протестировать макс. использование стека: заполнять стек определённой последовательностью при старте (скажем, 0xDEADBEEF), а потом в любой момент можно посчитать, сколько затёрлось, а сколько - нет.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 15 2015, 10:54
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Какой ужас! Как можно так жить? К чему эти пляски с бубном?


к тому что

Цитата
Детище местного подразделения микроэлектроники.
Это опытный образец,поэтому косяки быть могут. Моя задача либо сделать рабочую прошивку,либо указать где косяк,и почему я не могу эту прошивку написать.
Может быть проблема в ОЗУ?


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


А что если стэк увеличить ни на 1 байт а в 2 раза? Может там что-то с выравниванием? Увеличить на 4 байта?

Ограничение по любой памяти сверху - это ограничение памяти не больше. То есть раздувая стэк на этапе сборки вы получите сообщение что стэк залез на данные и собрать нельзя, но так чтобы что-то не работало из-за большого стека, я еще не слышал... По идее весь РАМ должен быть адресуемым, и потому мало вероятно что какой-то указатель не до тянется...
Go to the top of the page
 
+Quote Post
vanek18
сообщение Apr 15 2015, 11:34
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 30-01-15
Пользователь №: 84 841



Цитата(Golikov A. @ Apr 15 2015, 10:54) *
А что если стэк увеличить ни на 1 байт а в 2 раза? Может там что-то с выравниванием? Увеличить на 4 байта?

На сколько ни увеличивай,ничего не происходит.
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 15 2015, 11:50
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Кстати, выстрел наугад: у меня когда стек не был выравнен по границе 8 байт, не работали операции с плавучкой. А вдруг это оно?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 15 2015, 11:56
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А стэк пишется с конца, тут ничего не изменилось? То есть на самом деле размер стэка определяет адрес первого сохраняемого значения.
Смещение на 64 К не привило к падению, а что если размер стека увеличить на 64 К? Взять тот размер что работает и 64К прибавить?
Go to the top of the page
 
+Quote Post
johnshadow
сообщение Apr 15 2015, 18:48
Сообщение #24


Участник
*

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



Цитата(scifi @ Apr 15 2015, 14:50) *
Кстати, выстрел наугад: у меня когда стек не был выравнен по границе 8 байт, не работали операции с плавучкой. А вдруг это оно?


Согласен, насколько я встречал стек располагают с выравниванием и размером кратным sizeof(unsigned long). Для cortex m3 размер unsigned int = 4 байта, думаю что и для m4f размер такой же. Т.е. увеличивать\уменьшать размер стека нужно с шагом 4.

Сообщение отредактировал johnshadow - Apr 15 2015, 18:49
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 15 2015, 18:56
Сообщение #25


Гуру
******

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



Для ARM выравнивание стека производится по границе двух слов (8 байт).

А топикстартеру лучше посмотреть map и проверить значение SP непосредственно перед вызовом printf().
Go to the top of the page
 
+Quote Post
vanek18
сообщение Apr 23 2015, 11:46
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 30-01-15
Пользователь №: 84 841



Цитата(aaarrr @ Apr 15 2015, 18:56) *
Для ARM выравнивание стека производится по границе двух слов (8 байт).

А топикстартеру лучше посмотреть map и проверить значение SP непосредственно перед вызовом printf().

Итак, выравнивание по границе не привело к успеху. Выравнивать кстати нужно по 8 байтам,там прям в starup.s это указано. Отладчик в моем проце отсутствует.


Цитата(Golikov A. @ Apr 15 2015, 11:56) *
А стэк пишется с конца, тут ничего не изменилось? То есть на самом деле размер стэка определяет адрес первого сохраняемого значения.
Смещение на 64 К не привило к падению, а что если размер стека увеличить на 64 К? Взять тот размер что работает и 64К прибавить?

Увеличение размера стека не помогло.
Я освоил scatter файл,и с его помощью разбил память,отдельно для стека,отдельно для кучи и все остальное пространство собственно для программы.
Вот так выглядит мой scatter
CODE
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************


LOAD_ROM 0x08000000 0x0005FFFF ; load region size_region
{
EXEC_ROM 0x08000000 0x0005FFFF ; load address = execution address
{
*.o (START, +First)
*(InRoot$$Sections)
.ANY (+RO )
}
HEAP_RAM 0x20000400 0x00007BFF ; Heap region Heap_size = 31K
{
*(HEAP)
}
SRAM 0x20008000 0x000FFFF ; RW region RW_size = 64K
{
.ANY (+RW +ZI)
}
STACK_RAM 0x20018000 0x00007FFF ; Stack region Stack_size = 32K
{
*(STACK)
}
}

Карта памяти в приложении.
И моя программа с приветствием миру заработала при любых комбинациях и размерах областей памяти и ее содержимого.
О чудо,подумал я!
И на всякий случай решил удостовериться что ничего не работало. Я снова скомпилировал проект,но уже со стандартными настройками...такой какой был раньше и не работал.
И он ЗАРАБОТАЛ laughing.gif
Что это? И что я сделал этим разбиение памяти?
Прикрепленный файл  Mem_map_SCATTER.txt ( 995 байт ) Кол-во скачиваний: 105
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 23 2015, 11:56
Сообщение #27


Гуру
******

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



Цитата(vanek18 @ Apr 23 2015, 14:46) *
И он ЗАРАБОТАЛ laughing.gif
Что это? И что я сделал этим разбиение памяти?

Можете привести map от неработающего варианта?
Go to the top of the page
 
+Quote Post
vanek18
сообщение Apr 23 2015, 12:06
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 30-01-15
Пользователь №: 84 841



Цитата(aaarrr @ Apr 23 2015, 11:56) *
Можете привести map от неработающего варианта?

Он чуть выше уже был
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 23 2015, 12:10
Сообщение #29


Гуру
******

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



Цитата(vanek18 @ Apr 23 2015, 15:06) *

Вот тут интересно было бы узнать значение SP при входе в main().
Go to the top of the page
 
+Quote Post
vanek18
сообщение Apr 23 2015, 12:18
Сообщение #30


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 30-01-15
Пользователь №: 84 841



Цитата(aaarrr @ Apr 23 2015, 13:10) *
Вот тут интересно было бы узнать значение SP при входе в main().

Это можно как-то без отладчика сделать?
И факт в том,что сейчас с этой картой памяти он работает! wacko.gif
И кстати тот проект,который вначале темы, работает всегда.
Но когда я все это ставлю на rtx, та же лажа,что и раньше((

Сообщение отредактировал vanek18 - Apr 23 2015, 12:21
Go to the top of the page
 
+Quote Post

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

 


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


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