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

 
 
> Инициализация стека STM32
igorle
сообщение Sep 29 2013, 19:08
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



STM32F103 Keil StdPeriph.

Есть два аналогичных проекта. Сравнивая потабово свойства проектов, различий не вижу.

Насколько я понимаю, размер стека задается в файле startup_stm32f10x_md.s таким образом:
Код
Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

...

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
При этом в одном проекте SP инициализируется значением 0x200004D0, в другом 0x200008F0

Вопросы:
- Как образуются эти числа? Я ожидал видеть там 0x20000400
- Что находится под стеком?

Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 20)
A. Fig Lee
сообщение Sep 29 2013, 20:27
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Смотрите линкер файл. В IAR это .icf файл


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
igorle
сообщение Sep 29 2013, 20:30
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



А если Кейл - куда смотреть?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 29 2013, 21:05
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Стек растет вниз, в сторону уменьшения адресов. А навстречу ему движется "куча", из которой выделяется память. И все это находится выше переменных.
А посмотреть можно в файле *.map.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 29 2013, 21:13
Сообщение #5


Гуру
******

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



Цитата(igorle @ Sep 30 2013, 00:30) *
А если Кейл - куда смотреть?

.scat

Вам нужно найти начало секции STACK. __initial_sp будет равен <начало STACK> + Stack_Size.
Go to the top of the page
 
+Quote Post
_NB
сообщение Sep 30 2013, 10:41
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 92
Регистрация: 22-06-05
Из: Украина, г.Боярка
Пользователь №: 6 238



Цитата(igorle @ Sep 29 2013, 22:08) *
Вопросы:
- Как образуются эти числа? Я ожидал видеть там 0x20000400

В 'startup_stm32f10x_md.s' вы задаёте размер стека, а не адрес его начала.

Цитата
- Что находится под стеком?

Для Keil-a посмотрите map-файл
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Sep 30 2013, 11:27
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(_NB @ Sep 30 2013, 06:41) *
В 'startup_stm32f10x_md.s' вы задаёте размер стека, а не адрес его начала.


Для Keil-a посмотрите map-файл

1. Именно что начало.
2. Мап это не тот файл, это результат.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 30 2013, 13:51
Сообщение #8


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Вот такие наблюдения. В проекте в стартапе задано размер стека 0x400, размер кучи 0x200. В map файле вижу:
Код
    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   0x00000008   Data   RW            4    .data               telt_test.o
    0x20000008   0x00000060   Zero   RW          139    .bss                c_w.l(libspace.o)
    0x20000068   0x00000200   Zero   RW           55    HEAP                startup_stm32f10x_hd.o
    0x20000268   0x00000400   Zero   RW           54    STACK               startup_stm32f10x_hd.o

В отладчике вижу, что стек инициализируется значением 0x20000668.
Go to the top of the page
 
+Quote Post
igorle
сообщение Sep 30 2013, 18:33
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



MAP файл нашел. Стало понятно, что за цифры я получал и почему они разные. Стек объявляется НАД всеми данными.

Мне это не нравится. Ведь это означает, что если я выйду за пределы стека - то я потру свои переменные. И ловить такую ошибку очень трудно. Я бы хотел разместить стек ПОД всеми данными. Начиная с 0х20000000. Тогда при выходе за стек я получу hard fault.

Вопрос - могу ли я в Кейле сказать, где должен начинаться стек?

Цитата(aaarrr @ Sep 30 2013, 00:13) *
.scat

Вам нужно найти начало секции STACK. __initial_sp будет равен <начало STACK> + Stack_Size.

Я не нашел такого файла. Есть <target>.sct. Но он тоже автогенерится. Там есть такая секция
Код
  RW_IRAM1 0x20000000 0x00005000  { ; RW data
   .ANY (+RW +ZI)
  }

Возможно, если бы я мог повлиять на этот файл, я мог бы переместить стек туда, куда мне надо.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 30 2013, 18:57
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(igorle @ Sep 30 2013, 22:33) *
Возможно, если бы я мог повлиять на этот файл, я мог бы переместить стек туда, куда мне надо.

конечно возможно)
нужно снять галку - Use Memory Layout from Target Dialog - и правим скаттер руками
обзываем область стека как нужно и в скаттере даем указание где расположить
скорее всего, там обозначен один регион для .ANY (+RW +ZI), так вот нужно просто создать свой регион и обозначить его точку вхождения и размер
LOAD REGION определяет то, как будет располагаться образ, записываемый программатором (ну или бутлоадером)
А вот уже в нем расписываются все секции - где код, где данные, где оставить окно и т.д.
Go to the top of the page
 
+Quote Post
igorle
сообщение Sep 30 2013, 19:01
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



<Спустя полчаса>
Все, спасибо всем. Дошло. Я могу отменить "Use Memory Layout..." на закладке Linker в свойствах проекта, и задать свой скаттер файл. Уже видно, что это не тривиальная задача - написать скаттер файл, но понятно куда грести.
Еще раз всем спасибо.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 30 2013, 19:49
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



http://infocenter.arm.com/help/topic/com.a...51a/DUI0151.pdf

в помощь
Go to the top of the page
 
+Quote Post
igorle
сообщение Oct 1 2013, 08:06
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



2toweroff - Спасибо. Жаль что вы написали предыдущее сообщение одновременно со мною sm.gif Теперь никто не поверит, что я сам сообразил, и написал одновремнно с вами sad.gif

И за линк спасибо. Документу уже 12 лет, а не потерял актуальности. Я сам не нашел такого хорошего руководства по линковщику.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 1 2013, 10:50
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(igorle @ Oct 1 2013, 12:06) *
Жаль что вы написали предыдущее сообщение одновременно со мною sm.gif Теперь никто не поверит, что я сам сообразил, и написал одновремнно с вами sad.gif

а оно кому-нибудь надо? sm.gif
Цитата(igorle @ Oct 1 2013, 12:06) *
И за линк спасибо. Документу уже 12 лет, а не потерял актуальности. Я сам не нашел такого хорошего руководства по линковщику.



да, мне этот документ тоже мозг вправил, когда бутлодырем занимался. Кстати, тоже много полезного у самого кейла есть тут

Go to the top of the page
 
+Quote Post
редактор
сообщение Oct 2 2013, 08:02
Сообщение #15


Местный
***

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



Раз уж речь пошла об инициализации, спрошу здесь (хоть и не совсем в тему, да простят меня автор топика и Модераторы).
Можно ли в KEIL узнать остаток кучи (HEAP) штатными средствами?
Или только через контроль указателя, который вернулся при запросе (через new) и несложную математику?


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
igorle
сообщение Oct 2 2013, 14:35
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



А что такое "остаток"? Память ведь может быть фрагментирована. Сумма всех кусочков?

Единственный путь, известный мне, это в нужной точке устроить крэш тест: аллоцировать память, пока не вернет ошибку. Но и это мало информации дает, так как фрагментация памяти и размер запрашиваемых блоков играют важную роль.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Oct 2 2013, 15:11
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(igorle @ Oct 2 2013, 18:35) *
А что такое "остаток"? Память ведь может быть фрагментирована. Сумма всех кусочков?

Единственный путь, известный мне, это в нужной точке устроить крэш тест: аллоцировать память, пока не вернет ошибку. Но и это мало информации дает, так как фрагментация памяти и размер запрашиваемых блоков играют важную роль.
да, я тоже видел подобные примеры в тырнете. While для malloc с инкрементом размера и освобождением, пока не вернет NULL

тут ведь какая штука... черт ее знает, как там менеджер кучи работает. Может он умеет "собирать крупу" sm.gif


Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Oct 2 2013, 15:25
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(редактор @ Oct 2 2013, 04:02) *
Раз уж речь пошла об инициализации, спрошу здесь (хоть и не совсем в тему, да простят меня автор топика и Модераторы).
Можно ли в KEIL узнать остаток кучи (HEAP) штатными средствами?
Или только через контроль указателя, который вернулся при запросе (через new) и несложную математику?

Keil это компилятор. Вы хотите узнать сколько осталось после компиляции?
мап файл.
Если в процессе работы программы, то Keil тут никаким боком.
Зависит от операционки, если она есть.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
редактор
сообщение Oct 3 2013, 08:55
Сообщение #19


Местный
***

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



Спасибо всем за ответы.
Цитата
А что такое "остаток"? Память ведь может быть фрагментирована. Сумма всех кусочков?

Ну примерно так. Если подробнее, то до вызова main() происходит инициализация статических переменных и классов. При инициализации классов часть памяти "захватыватся" через new. Вот и хотелось бы узнать хоть приблизительный остаток кучи (к этому моменту она еще не будет дефрагментирована, надеюсь) или размер максимального блока, который может быть выделен.
Использовать статическое выделение памяти можно, но это уже другая тема (мое наследство), поэтому не обсуждаю.

Цитата
Keil это компилятор. Вы хотите узнать сколько осталось после компиляции? мап файл.

Тогда уж после линковки (но это я к словам докапываюсь, извините). Это я в курсе.
Но тем неменее KEIL предоставляет несколько функций для работы с кучей, не относящихся к стандартным. Например __heapstats(); ее недостатком является то, что информацию выдает через printf в текстовом виде, да и информация по каждому блоку отдельно - не совсем то, что надо.
Думал, может кто с другими функциями контроля знаком.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
igorle
сообщение Oct 3 2013, 19:26
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



Вызовите в начале функции main маллок одного байта, поставьте там брекпоинт. Посмотрите, что вернул маллок и насколько это далеко от границы кучи. Освободите этот байт.

Хочется автоматизации - аллоцируйте и осбобождайте блок памяти в цикле, добавляя по одному байту. Когда будет достигнут предел - напечатайте, или зайдите в брекпоинт. Я так понимаю, речь идет не о рабочем коде, а об отладочном - чтобы оценить достаточность кучи?
Go to the top of the page
 
+Quote Post
редактор
сообщение Oct 4 2013, 07:39
Сообщение #21


Местный
***

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



Спасибо за совет. В данный момент речь идет именно об отладочном коде.
Но использование в реалтайме тоже могло бы пригодиться.
Есть мысль, что в начале main достаточно запросить один байт и по указателю рассчитать остаток.
HEAP_MEM + HEAP_SIZE - PTR
точность составит наверное 8-16 байт (округление запрошенной памяти до 8 байт + параметры под атрибуты блока) но для первоначальной оценки вполне достаточно.
Еще раз всем спасибо.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post

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

 


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


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