|
Определение использования стека возвратов и данных |
|
|
|
Jan 13 2012, 23:15
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Нужно определить сколько нужно программе выделять стека. Думаю определить опытным путём: заполняю RSTACK и CSTACK определёнными ненулевыми значениями. CODE #pragma inline=forced extern "C" { inline unsigned char *GetY(void) { asm("mov R16, R28"); asm("mov R17, R29"); } };
#pragma segment="CSTACK" #pragma segment="RSTACK" unsigned char *dbg_ptr, *dbg_begin; //--------------------------------------------------------------------------- int main() { // очистка стека данных dbg_ptr=GetY(); dbg_begin=(unsigned char *)__segment_begin("CSTACK"); do { *dbg_begin++=0; } while (dbg_begin<dbg_ptr); // заполнение стека данных символом 'D' dbg_begin=(unsigned char *)__segment_begin("CSTACK"); do { *dbg_begin++='D'; } while (dbg_begin<dbg_ptr); // очистка стека возвратов dbg_ptr=reinterpret_cast<TStackItem*>(*((volatile unsigned short*)0x3D)); dbg_ptr-=3; dbg_begin=(unsigned char *)__segment_begin("RSTACK"); do { *dbg_begin++=0; } while (dbg_begin<dbg_ptr); // заполнение стека возвратов символом 'R' dbg_begin=(unsigned char *)__segment_begin("RSTACK"); do { *dbg_begin++='R'; } while (dbg_begin<dbg_ptr); // while (1) { // программа } Вроде работает (нет ли граблей каких, пока не понял). Какие есть способы сделать лучше/правильней? Особенно не нравится функция GetY (обычно не использую ни inline, ни тем более asm-inline, поэтому не уверен в правильности реализации). MCU=xmega256A3. Спасибо.
Сообщение отредактировал IgorKossak - Jan 14 2012, 16:52
Причина редактирования: [codebox]!!!
|
|
|
|
|
 |
Ответов
|
Jan 16 2012, 10:53
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Непомнящий Евгений @ Jan 16 2012, 08:53)  если зайти на вкладку linker\list и поставить там все галки, то вы получите map Можно бы подробней с этого места Цитата(Непомнящий Евгений @ Jan 16 2012, 08:53)  расчет стека. Однако он сильно примерный и в моем случае очень завышенный IAR себе цену набивает? Как это - завышенный? Цитата(Непомнящий Евгений @ Jan 16 2012, 08:53)  А вообще обычно делаю также - забиваю стек 0xff и после часа-двух работы под нагрузкой смотрю до каких значений дошло Приведите пример, если нетрудно - об этом и вопрос.
|
|
|
|
|
Jan 16 2012, 11:04
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(_Артём_ @ Jan 16 2012, 13:53)  Можно бы подробней с этого места Свойства проекта, линкер, list, ставите все галки, выбираете module map, HTML При этом после компиляции в папке build\list будет .html файл. В нем есть секция с расчетом стека Цитата IAR себе цену набивает? Как это - завышенный? Он берет сумму стеков всех цепочек функций, которые могут быть одновременно вызваны, в т.ч. из прерываний. При этом естественно не учитывается логика приложения (например у меня какие-то функции принципиально не могут работать параллельно). Рекурсия по моему также не учитывается. В общем, если у вас есть место в ОЗУ, можно взять эти значения. У меня ОЗУ дефицит, поэтому гоняю в железе и смотрю на предельные Цитата Приведите пример, если нетрудно - об этом и вопрос. Ну собственно такой же код, как и у вас. Единственно - я адреса начала стеков вбивал ручками, не знал про возможность их получить программно. Ну а после часа-двух работы стопаю и смотрю в отладчике на показания.
|
|
|
|
|
Jan 16 2012, 12:37
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Непомнящий Евгений @ Jan 16 2012, 13:04)  Свойства проекта, линкер, list, ставите все галки, выбираете module map, HTML При этом после компиляции в папке build\list будет .html файл. В нем есть секция с расчетом стека Да увидел. Осталось понять что там к чему. Цитата(Непомнящий Евгений @ Jan 16 2012, 13:04)  Он берет сумму стеков всех цепочек функций, которые могут быть одновременно вызваны, в т.ч. из прерываний. Берёт сумму? С какой стати? Компилятор не может знать логику программы, поэтому суммировать нет никакого смысла (и как мне кажется IAR не суммирует): откуда компилятору знать когда и при каких условиях разрешаются прерывания/делаются косвенные вызовы функций? Цитата(Непомнящий Евгений @ Jan 16 2012, 13:04)  В общем, если у вас есть место в ОЗУ, можно взять эти значения. У меня ОЗУ дефицит, поэтому гоняю в железе и смотрю на предельные Без разницы дефицит или нет дефицита: нужно смотреть... Цитата(Непомнящий Евгений @ Jan 16 2012, 13:04)  Ну а после часа-двух работы стопаю и смотрю в отладчике на показания. Пока другого варианта кроме как смотреть через час-два не вижу. Хотя наверное можно как-то распарсить файл выдаваемый линкером и просчитать что там в сумме выходит (частично вручную). Но пока не понял как...
|
|
|
|
|
Jan 16 2012, 12:45
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(_Артём_ @ Jan 16 2012, 15:37)  Да увидел. Осталось понять что там к чему. Раздел call graph, самый конец Цитата Берёт сумму? С какой стати? Компилятор не может знать логику программы, поэтому суммировать нет никакого смысла (и как мне кажется IAR не суммирует): откуда компилятору знать когда и при каких условиях разрешаются прерывания/делаются косвенные вызовы функций? Компилятор знает, что из если из функции f вызываются функции g и h, то стек f = max(стек g, стек h) + локальный стек f. Так он делает для всех функций, к тому же он считает что функции верхнего уровня - это main и функции прерываний. Отсюда он и выводит размер стека Про косвенные вызовы он разумеется не знает, поэтому оценка примерная. Конкретно для моих программ она обычно очень завышена. Я когда-то давно пытался с ней что-то делать, но потом забил и смотрю в железе.
|
|
|
|
|
Jan 16 2012, 13:28
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Непомнящий Евгений @ Jan 16 2012, 14:45)  Раздел call graph, самый конец Да, нашёл (но ещё не понял что там). спасибо. Цитата(Непомнящий Евгений @ Jan 16 2012, 14:45)  Компилятор знает, что из если из функции f вызываются функции g и h, то стек f = max(стек g, стек h) + локальный стек f. Согласен. Цитата(Непомнящий Евгений @ Jan 16 2012, 14:45)  Про косвенные вызовы он разумеется не знает, поэтому оценка примерная.
Конкретно для моих программ она обычно очень завышена. Оценка должна быть заниженной (КМК). Цитата(Непомнящий Евгений @ Jan 16 2012, 14:45)  Я когда-то давно пытался с ней что-то делать, но потом забил и смотрю в железе. Так наверное и придётся делать.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|