|
Как определить максимальную реальную глубину CSTACK моей программы?, в отладчике |
|
|
|
Oct 14 2015, 08:35
|
Участник

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

|
Есть ли какая-нибудь встроенная особенность отладчика IAR, которая автоматически показывает максимальную глубину CSTACK, которая произошла в моей программе за время отладки встроенным отладчиком?
Сейчас приходится вручную приблизительно прикидывать, сколько скушает SCTACK, а хотелось бы поточнее.
Думаю, вопрос подойдет про разные платформы. Конкретно - AVR.
Сообщение отредактировал Разработчики - Oct 14 2015, 08:36
|
|
|
|
|
Oct 14 2015, 08:48
|
Участник

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

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

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

|
Спасибо. Я посмотрел, он довольно сильно завышает.
А можно как-то из программы определить границы (начало и конец) SCTACK - где расположено?
Сообщение отредактировал Разработчики - Oct 14 2015, 11:22
|
|
|
|
|
Oct 14 2015, 12:49
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Сергей Борщ @ Oct 14 2015, 15:43)  Можно попросить линкер построить дерево вызовов и сложить глубину основного цикла с максимальной глубиной обработчиков прерываний. Вообще без отладчика. Не канает если есть косвенные вызовы. Цитата(Разработчики @ Oct 14 2015, 17:21)  А можно как-то из программы определить границы (начало и конец) SCTACK - где расположено? Стек в программе не определяют, а задают. Если что. Так же как любой другой массив.
|
|
|
|
|
Oct 14 2015, 12:53
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(Разработчики @ Oct 14 2015, 14:21)  А можно как-то из программы определить границы (начало и конец) SCTACK - где расположено? __segment_begin("CSTACK") __segment_end("CSTACK") и нужно не забыть заранее сделать так: #pragma segment = "CSTACK"
|
|
|
|
|
Oct 14 2015, 13:55
|
Участник

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

|
Цитата(den_po @ Oct 14 2015, 15:53)  и нужно не забыть заранее сделать так: #pragma segment = "CSTACK" Я имел в виду системный сегмент CSTACK, а не мой. Цитата(jcxz @ Oct 14 2015, 15:49)  Стек в программе не определяют, а задают. Если что. Так же как любой другой массив. Для массива можно из программы узнать, куда его запихал компилятор. А CSTACK?
|
|
|
|
|
Oct 14 2015, 14:01
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(Разработчики @ Oct 14 2015, 16:55)  Я имел в виду системный сегмент CSTACK, а не мой. Они оба - один и тот же сегмент. Просто сишный компилятор не знает о нём, если ему не подсказать.
|
|
|
|
|
Oct 14 2015, 14:11
|
Участник

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

|
Цитата(den_po @ Oct 14 2015, 17:01)  Они оба - один и тот же сегмент. Просто сишный компилятор не знает о нём, если ему не подсказать. Понял. Спасибо!
|
|
|
|
|
Oct 15 2015, 05:23
|
Гуру
     
Группа: Свой
Сообщений: 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).
|
|
|
|
|
Oct 15 2015, 06:38
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(jcxz @ Oct 15 2015, 08:23)  Я не знаю, что в Вашей программе означает символьное имя CSTACK. Это только Вы можете знать. В моих проектах это имя не используется. То есть вы НИКОГДА не использовали иаровский стартап и его же конфиги линкера по умолчанию?
|
|
|
|
|
Nov 25 2015, 11:33
|
Участник

Группа: Участник
Сообщений: 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 байта, а третий - ноль.
|
|
|
|
|
Nov 25 2015, 12:51
|
Профессионал
    
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Nov 25 2015, 19:15
|

Местный
  
Группа: Свой
Сообщений: 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
|
|
|
|
|
Nov 25 2015, 20:49
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Ga_ry @ Nov 25 2015, 22:15)  ...Как понять сейчас хватает программе этого размера?Какой минимум можно оставить для CSTACK?.. делаете три вещи 1) при выделении стэка расписываете магическим числом всю память под стэк. 2) в определённые срезы времени проверяете сколько памяти осталось расписанной вашим магическим числом(например при переключении задач, если ось) 3) скидываете каждые изменения размеров остатков стэков в лог это даст Вам однозначную картину поедания стэка и его нехватки. т.к. процесс отладки не быстрый то и анализируя статистику таких логов Вы сможете без труда отловить и странные поведения программы и необходимость добавить для стэка памяти. выделение стэка для задачи нужно начать с большего предела (прикидываете сколько нужно, умножаете на два и т.п..)
|
|
|
|
|
Nov 26 2015, 08:20
|
Участник

Группа: Участник
Сообщений: 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. Можно в прерывании по таймеру или кнопке искать адрес первого ненулевого байта.
|
|
|
|
|
Nov 26 2015, 19:37
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Ga_ry @ Nov 26 2015, 00:09)  ...изначальное заполнение FF не пойдет для магического числа? 20 байт - можно использовать для многого  под отладчиком для просмотра/контроля - вполне. а вот FF - тут дело такое. для скорости проверки необходимо брать всю разрядность шины данных. т.е. если у вас используются 32 разрядный мк - то это уже 4 байта за раз можно писать/тестировать/сравнивать... нолик 0x00 как и минус один(в стандарте сей) 0xFF чаще встречается чем какие-либо другие комбинации.
|
|
|
|
|
Nov 27 2015, 06:23
|

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

|
Цитата(x893 @ Nov 27 2015, 00:04)  а разве DEADBEEF не помогает - или религия запрещает ? проблема из пальца выдуманная Этот Ваш стиль надменно-пренебрежительный это врожденное или приобретенное? Ссылку дайте, я первый раз слышу о таком.
|
|
|
|
|
Nov 29 2015, 09:38
|
Профессионал
    
Группа: Свой
Сообщений: 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
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|