Jump to content

    

задание размера стеков

процессор перенес массив констант для инициализации из флэш-памяти в стек

 

void f(...)
{
static const unsigned char a [] = {0x01, 0x02, 0x03 };
}

 

Если кто-то забыл static написать, так и будет.

Edited by Genadi Zawidowski

Share this post


Link to post
Share on other sites

Неправильно сказал - не через стек переписывает, а через память, отведенную под стек. Переносит указатель на 0x040, и в свободной области создает буфер для этих констант. Потом обратно стек восстанавливает.

А за static - спасибо, попробую.

upd. Попробовал - помогло. И размер кода уменьшился (естественно :))

Share this post


Link to post
Share on other sites

Можно вопрос, не по теме, но непосредственно вытекающий из предыдущего.

Почему симулятор Keil останавливается на командах, которыми я инициализирую контроллер ЖКИ на внешней шине, и ходит только по шагам?

Share this post


Link to post
Share on other sites

А Вы окошечки сообщений посмотрите: он, наверное, ругается на запись/чтение левых адресов.

Share this post


Link to post
Share on other sites
А Вы окошечки сообщений посмотрите: он, наверное, ругается на запись/чтение левых адресов.

Точно, пишет! В окне command:

*** error 65: access violation at 0x6C000070 : no 'read' permission

а потом и на запись аналогично ругается.

 

Вообще, складывается впечатление, что в окне Options/Target Keil 4.10 имеется глюк. Привожу все варианты установок и результат их действия после запуска программы в симуляторе. Адрес 0x6C000070 - первый из используемых (регистр контроллера ЖКИ), адрес 0x6C020000 - память контроллера ЖКИ.

default--Start-------Size-------NoInit--access_violation--R13(SP)
---------0x6c000000--0x40000------------0x6C000070--------0x2000041C
---------0x6c000000--0x40000-----v------0x6C000070--------0x2000041C
-v-------0x6c000000--0x40000------------0x6C020000--------0x6C000414
-v-------0x6c000000--0x40000-----v------0x6C020000--------0x6C000414

Т.е., отмечаю default - там создается стек, NoInit - вообще никак не влияет.

А size там в каких единицах задавать, в байтах?

Придется изучать синтаксис scatter файла...

Пока отформатировал данное послание, упарился...

Share this post


Link to post
Share on other sites

А на такой вопрос подскажите, в чем дело (может, и предыдущий разрешится):

Отмечаю v default регион start 0x6c000000 size 0x40000, имею в scatter файле:

RW_RAM3 0x6C000000 UNINIT 0x00040000 { ; RW data

.ANY (+RW +ZI)

Стек, как и раньше, закидывается в 0x6c000414.

Запускаю симулятор, останавливается с ошибкой

*** error 65: access violation at 0x6C020000 : no 'read' permission

Это как? Разрешена же область! Или со стеком связано? Ведь перед этим обращался к адресам 0x6c000000... без ошибок.

А еще есть эта... куча...!?

Share this post


Link to post
Share on other sites
Отмечаю v default регион start 0x6c000000 size 0x40000, имею в scatter файле:

...

Запускаю симулятор, останавливается с ошибкой

*** error 65: access violation at 0x6C020000 : no 'read' permission

Это как? Разрешена же область!

Scatter-файл относится к линкеру, а ошибка к симулятору. Если хотите, чтобы последний не ругался на записи по левым адресам, создайте ini-файл со строкой:

map 0x6c000000, 0x6c0fffff READ WRITE

И подцепите его в качестве Initialization File для симулятора.

Share this post


Link to post
Share on other sites
Scatter-файл относится к линкеру, а ошибка к симулятору.

Я думаю, симулятор знает, что сделал линкер. Иначе он бы останавливался при первом же обращении в эту область, по адресу 0x6c000070.

Share this post


Link to post
Share on other sites
Я думаю, симулятор знает, что сделал линкер.

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

Просто объясните симулятору, что такая область есть. Как это делается я написал выше, только диапазон адресов расширьте.

Share this post


Link to post
Share on other sites
А вот линкеру как раз знать об этой области ничего не надо - вы же не хотите, чтобы по адресам регистров LCD он распихал данные программы.

Просто объясните симулятору, что такая область есть. Как это делается я написал выше, только диапазон адресов расширьте.

Спасибо, получилось! А я еще недоумевал, почему в симуляторе останавливается, а в железе работает.

А внешние ОЗУ и ПЗУ мне линкеру указывать?

Share this post


Link to post
Share on other sites
А внешние ОЗУ и ПЗУ мне линкеру указывать?

Если в них надо разместить код/данные - то указывать. Если они просто существуют, но не используются, то и указывать не за чем.

Share this post


Link to post
Share on other sites

В-общем, эта птичка default именно для этого и создана - подключать или отключать заданный регион памяти в проект. Если ее убрать в опциях Target, в scatter файле заданной цифрами области не будет.

Share this post


Link to post
Share on other sites

Возвращаюсь к теме.

Хочу для STM32F303 в Keil задать стек в конце CCM-RAM. Но что-то не выходит. Как это сделать, и можно ли? В startup.s или в *.sct?

Хочу понять строки в startup.s

Stack_Size      EQU     0x00000400

               AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
...
Heap_Size       EQU     0x00000000

               AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit
...
; Vector Table Mapped to Address 0 at Reset
               AREA    RESET, DATA, READONLY
               EXPORT  __Vectors
               EXPORT  __Vectors_End
               EXPORT  __Vectors_Size

__Vectors       DCD     __initial_sp               ; Top of Stack
               DCD     Reset_Handler              ; Reset Handler
...
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                IF      :DEF:__MICROLIB

                EXPORT  __initial_sp
                EXPORT  __heap_base
                EXPORT  __heap_limit

                ELSE

                IMPORT  __use_two_region_memory
                EXPORT  __user_initial_stackheap

__user_initial_stackheap

                LDR     R0, =  Heap_Mem
                LDR     R1, =(Stack_Mem + Stack_Size)
                LDR     R2, = (Heap_Mem +  Heap_Size)
                LDR     R3, = Stack_Mem
                BX      LR

                ALIGN

                ENDIF

Share this post


Link to post
Share on other sites

Ого, блин! В AN4296 "Overview and tips for using STM32F303/313xx CCM RAM..." Rev.2 в разделе KEIL ошибочно заменили Figure 11 на такую же из IAR (Figure 2). Без этой картинки нихрена не понять.

К счастью, нашел в корзине удаленный файл Rev.1.

Share this post


Link to post
Share on other sites

Добавляю в *.sct

ARM_LIB_STACK 0x10002000 EMPTY -0x0400 { }

не помогает.

Вау - работает, вижу в отладчике SP = 0x10002000

Но когда всю обычную RAM (не CCMRAM) пытаюсь забрать под массив, не складывается.

Т.е. теперь вопрос - как разместить остальные переменные в CCMRAM.

В неё же у меня и код перегружается, и из нее выполняется.

В-общем, что-то со стеком, сначала в основной памяти размещается, а потом в CCM. Приступаю штудировать доку по линкеру.

 

Кстати, в Keil для IRAM1 указан неправильный размер, надо A000 (40k) вместо C000 (48k).

Из-за этого компилируется без ошибок, а после запуска вываливается в HardFault.

А все потому, что стек размещается сразу после всех переменных (+ куча, если есть), а не в конце RAM. И когда память не была забита, хватало места и для стека.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this