Перейти к содержанию

    

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

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

 

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

 

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

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


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

Точно, пишет! В окне 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 файла...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Отмечаю 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... без ошибок.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Отмечаю 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 для симулятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Scatter-файл относится к линкеру, а ошибка к симулятору.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Я думаю, симулятор знает, что сделал линкер.

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

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

Поделиться сообщением


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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
А внешние ОЗУ и ПЗУ мне линкеру указывать?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Хочу для 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

ARM_LIB_STACK 0x10002000 EMPTY -0x0400 { }

не помогает.

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

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

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

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

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

 

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация