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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как определить максимальную реальную глубину CSTACK моей программы?, в отладчике
Разработчики
сообщение Oct 14 2015, 08:35
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 13-03-14
Из: Санкт-Петербург
Пользователь №: 80 903



Есть ли какая-нибудь встроенная особенность отладчика IAR, которая автоматически показывает максимальную глубину CSTACK, которая произошла в моей программе за время отладки встроенным отладчиком?

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

Думаю, вопрос подойдет про разные платформы. Конкретно - AVR.

Сообщение отредактировал Разработчики - Oct 14 2015, 08:36
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Oct 14 2015, 08:44
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Заполняете область стека неким шаблоном (0xff, 0xDEAD, etc) и смотрите, где шаблон нарушен - туда опускался стек
Go to the top of the page
 
+Quote Post
Разработчики
сообщение Oct 14 2015, 08:48
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 13-03-14
Из: Санкт-Петербург
Пользователь №: 80 903



Цитата(Непомнящий Евгений @ Oct 14 2015, 11:44) *
Заполняете область стека неким шаблоном (0xff, 0xDEAD, etc) и смотрите, где шаблон нарушен - туда опускался стек


Да, сейчас так и делаю. Даже можно ничем не заполнять, потому что само заполняется ненулями.
Но может есть что-то встроенное.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 14 2015, 09:43
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Можно попросить линкер построить дерево вызовов и сложить глубину основного цикла с максимальной глубиной обработчиков прерываний. Вообще без отладчика.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Разработчики
сообщение Oct 14 2015, 11:21
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 13-03-14
Из: Санкт-Петербург
Пользователь №: 80 903



Спасибо. Я посмотрел, он довольно сильно завышает.

А можно как-то из программы определить границы (начало и конец) SCTACK - где расположено?

Сообщение отредактировал Разработчики - Oct 14 2015, 11:22
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 14 2015, 12:49
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Oct 14 2015, 15:43) *
Можно попросить линкер построить дерево вызовов и сложить глубину основного цикла с максимальной глубиной обработчиков прерываний. Вообще без отладчика.

Не канает если есть косвенные вызовы.

Цитата(Разработчики @ Oct 14 2015, 17:21) *
А можно как-то из программы определить границы (начало и конец) SCTACK - где расположено?

Стек в программе не определяют, а задают. Если что. Так же как любой другой массив.
Go to the top of the page
 
+Quote Post
den_po
сообщение Oct 14 2015, 12:53
Сообщение #7


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(Разработчики @ Oct 14 2015, 14:21) *
А можно как-то из программы определить границы (начало и конец) SCTACK - где расположено?

__segment_begin("CSTACK")
__segment_end("CSTACK")

и нужно не забыть заранее сделать так:
#pragma segment = "CSTACK"
Go to the top of the page
 
+Quote Post
Разработчики
сообщение Oct 14 2015, 13:55
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 13-03-14
Из: Санкт-Петербург
Пользователь №: 80 903



Цитата(den_po @ Oct 14 2015, 15:53) *
и нужно не забыть заранее сделать так:
#pragma segment = "CSTACK"


Я имел в виду системный сегмент CSTACK, а не мой.

Цитата(jcxz @ Oct 14 2015, 15:49) *
Стек в программе не определяют, а задают. Если что. Так же как любой другой массив.


Для массива можно из программы узнать, куда его запихал компилятор. А CSTACK?
Go to the top of the page
 
+Quote Post
den_po
сообщение Oct 14 2015, 14:01
Сообщение #9


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(Разработчики @ Oct 14 2015, 16:55) *
Я имел в виду системный сегмент CSTACK, а не мой.

Они оба - один и тот же сегмент. Просто сишный компилятор не знает о нём, если ему не подсказать.
Go to the top of the page
 
+Quote Post
Разработчики
сообщение Oct 14 2015, 14:11
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 13-03-14
Из: Санкт-Петербург
Пользователь №: 80 903



Цитата(den_po @ Oct 14 2015, 17:01) *
Они оба - один и тот же сегмент. Просто сишный компилятор не знает о нём, если ему не подсказать.


Понял. Спасибо!
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 15 2015, 05:23
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Разработчики @ Oct 14 2015, 19:55) *
Для массива можно из программы узнать, куда его запихал компилятор. А CSTACK?

Я не знаю, что в Вашей программе означает символьное имя CSTACK. Это только Вы можете знать. В моих проектах это имя не используется.
У меня есть массив
static __root __no_init OS_STK stkTaskMain[NNN + STK_SIZE_ISR_NFP] @ ".bssStkMain";
задающий стек используемый стартапом и функцией main() (и, впоследствии, после старта ОС, другой задачей), есть сегмент .bssStkMain, в который линкуется этот массив и указатель на конец которого записывается в вектор сброса.
Есть множество других стеков задач ОС, каждый задан массивом типа
__no_init static OS_STK stkXXX[NNN + STK_SIZE_ISR_NFP] @ ".bssStk";
И место под любой стек задаётся статическим массивом в исходниках либо в файле конфигурации компоновщика (*.icf в IAR).
Go to the top of the page
 
+Quote Post
den_po
сообщение Oct 15 2015, 06:38
Сообщение #12


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(jcxz @ Oct 15 2015, 08:23) *
Я не знаю, что в Вашей программе означает символьное имя CSTACK. Это только Вы можете знать. В моих проектах это имя не используется.

То есть вы НИКОГДА не использовали иаровский стартап и его же конфиги линкера по умолчанию?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 15 2015, 06:50
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(den_po @ Oct 15 2015, 12:38) *
То есть вы НИКОГДА не использовали иаровский стартап и его же конфиги линкера по умолчанию?

Когда-то давно использовал. Но это было давно. Последние годы использую везде (в ARM) только свои стартапы.
Go to the top of the page
 
+Quote Post
Target
сообщение Nov 25 2015, 11:33
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 21-05-08
Пользователь №: 37 691



А подскажите, как получить трехбайтовую величину? Хочу получить длину программы по окончанию сегмента NEAR_ID.
Пытаюсь получить адрес сегмента NEAR_ID.

Делаю так:

#pragma segment = "NEAR_ID"
unsigned long * pNEAR_ID_end = (unsigned long *)__segment_end("NEAR_ID");


Компилятор ругается так:

Linking
Warning[w47]: Range error,
Number out of range. Valid range is -128 (-0x80) to 255 (0xFF).
File: main.cpp, Line: 247
Source: LDI R17, (SFE(NEAR_ID)) >> 8

Если вместо unsigned long ставить void или word, то выдает только 2 байта, а третий - ноль.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Nov 25 2015, 12:51
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(Target @ Nov 25 2015, 18:33) *
А подскажите, как получить трехбайтовую величину? Хочу получить длину программы по окончанию сегмента NEAR_ID.
Пытаюсь получить адрес сегмента NEAR_ID.

Очень похоже на то, что сказывается гарвардская архитектура AVR. Указатели на память данных и память кода это две совершенно разные сущности и просто так не смешиваются.
А у Вас как раз написано unsigned long * pNEAR_ID_end = ..., что подразумевает указатель на память данных, в то время как сегмент NEAR_ID располагается во флеше.
В EWAVR_CompilerReference.pdf есть подсказка:
Цитата
If the segment was declared with a memory attribute
memattr, the type of the __segment_begin operator is a pointer to memattr void.
Otherwise, the type is a default pointer to void.

Попробуйте так:
#pragma segment = "NEAR_ID" __farflash
char __farflash* pNEAR_ID_end = __segment_end("NEAR_ID");
а то и просто
uint32_t pNEAR_ID_end = __segment_end("NEAR_ID");


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
Ga_ry
сообщение Nov 25 2015, 19:15
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579



Что то читал, читал эту ветку и так и не понял как определить хватает места программе для стека или нет.
Вот например (IAR AVR) изначально по умолчанию 0x20 явно не хватало, шли сбои, увеличил до 0x44
вот последние строчки из MAP
Цитата
CSTACK DATA 00000100 - 00000144 45 dse 0
RSTACK DATA 00000145 - 00000178 34 dse 0
NEAR_I DATA 00000179 - 00000284 10C rel 0
NEAR_Z DATA 00000285 - 000002DF

во вложении скриншот memory data после работы программы

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



Сообщение отредактировал Ga_ry - Nov 25 2015, 19:31
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Nov 25 2015, 20:49
Сообщение #17


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Ga_ry @ Nov 25 2015, 22:15) *
...Как понять сейчас хватает программе этого размера?Какой минимум можно оставить для CSTACK?..


делаете три вещи
1) при выделении стэка расписываете магическим числом всю память под стэк.
2) в определённые срезы времени проверяете сколько памяти осталось расписанной вашим магическим числом(например при переключении задач, если ось)
3) скидываете каждые изменения размеров остатков стэков в лог

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

Go to the top of the page
 
+Quote Post
Ga_ry
сообщение Nov 25 2015, 21:09
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579



Понятно.
Вот только логи мне писать некуда, 8к почти под завязку (20 байт осталось) т.е. код для формир. лога вставить тоже некуда. Ноги МК тоже, НИ ОДНОЙ свободной.
Брать контроллер с большей памятью, отладку делать на нем?

А вот это изначальное заполнение FF не пойдет для магического числа?
Go to the top of the page
 
+Quote Post
Target
сообщение Nov 26 2015, 08:20
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 21-05-08
Пользователь №: 37 691



Цитата(SSerge @ Nov 25 2015, 15:51) *
#pragma segment = "NEAR_ID" __farflash
char __farflash* pNEAR_ID_end = __segment_end("NEAR_ID");


Спасибо!

Помогло так:

#pragma segment = "NEAR_ID" __farflash
void __farflash * pNEAR_ID_end = __segment_end("NEAR_ID");


Цитата(Ga_ry @ Nov 26 2015, 00:09) *
А вот это изначальное заполнение FF не пойдет для магического числа?


Обычно там 00. Можно в прерывании по таймеру или кнопке искать адрес первого ненулевого байта.
Go to the top of the page
 
+Quote Post
Ga_ry
сообщение Nov 26 2015, 10:32
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579



Цитата(Target @ Nov 26 2015, 10:20) *
Обычно там 00.

Странно, в скриншоте, который прикреплен, видно FF
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Nov 26 2015, 19:37
Сообщение #21


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Ga_ry @ Nov 26 2015, 00:09) *
...изначальное заполнение FF не пойдет для магического числа?


20 байт - можно использовать для многого sm.gif под отладчиком для просмотра/контроля - вполне.
а вот FF - тут дело такое. для скорости проверки необходимо брать всю разрядность шины данных. т.е. если у вас используются 32 разрядный мк -
то это уже 4 байта за раз можно писать/тестировать/сравнивать...

нолик 0x00 как и минус один(в стандарте сей) 0xFF чаще встречается чем какие-либо другие комбинации.
Go to the top of the page
 
+Quote Post
Ga_ry
сообщение Nov 26 2015, 21:21
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579



kolobok0, а зачем надо умножать на два?
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 26 2015, 22:04
Сообщение #23


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



а разве DEADBEEF не помогает - или религия запрещает ?
проблема из пальца выдуманная
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Nov 26 2015, 23:40
Сообщение #24


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Ga_ry @ Nov 27 2015, 00:21) *
kolobok0, а зачем надо умножать на два?


тут именно посыл вектора поиска от большего к меньшему. т.е. не искать где нехватка, а искать где слишком много и не юзается...
Go to the top of the page
 
+Quote Post
Ga_ry
сообщение Nov 27 2015, 06:23
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579



Цитата(x893 @ Nov 27 2015, 00:04) *
а разве DEADBEEF не помогает - или религия запрещает ?
проблема из пальца выдуманная

Этот Ваш стиль надменно-пренебрежительный это врожденное или приобретенное?
Ссылку дайте, я первый раз слышу о таком.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 29 2015, 09:38
Сообщение #26


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(kolobok0 @ Nov 26 2015, 00:49) *
делаете три вещи
1) при выделении стэка расписываете магическим числом всю память под стэк.
2) в определённые срезы времени проверяете сколько памяти осталось расписанной вашим магическим числом(например при переключении задач, если ось)
3) скидываете каждые изменения размеров остатков стэков в лог

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


В ОС (из-за многостековости) имеются "включаемые" режимы контроля размера стек(ов).
Алгоритм тот что указан выше.

freeRTOS:
Код
#if( configCHECK_FOR_STACK_OVERFLOW == 1 )

    /* FreeRTOSConfig.h is only set to use the first method of
    overflow checking. */
    #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()

#endif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 05:16
Рейтинг@Mail.ru


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