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

 
 
 
Reply to this topicStart new topic
> Расчёт глубины стека для IAR for AVR, Предлагаю попробовать мою программу для этого
Dmitro25
сообщение Mar 25 2010, 11:57
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



Здравствуйте.
Не так давно начал пользоваться компилятором IAR for AVR (раньше пользовался CodeVisionAVR). В процессе разбирательств я понял, что, в отличие от CodeVisionAVR, IAR никак не контролирует правильность установки значений глубины стека данных (CStack) и стека возврата (RStack). Мало того, самому оценить эти значения проблематично, поскольку они могут зависеть от уровня оптимизации и других параметров. А неправильно заданные значения стеков могут привести либо к полной неработоспособности программы, либо, что хуже, к неработоспособности программы при некоторых случайно совпавших условиях.

Начав разбираться, я понял, что информацию о размере стека, который используется каждой функцией, можно получить из *.LST - файла. В конце его содержится таблица "Maximum stack usage in bytes". Там для текущего модуля проекта содержится список его функций с указанием используемого данной функцией размера CStack и RStack, а также список подфункций, которые вызываются из каждой функции модуля.

Чтобы вычислить максимальный требуемый размер каждого из стеков необходимо просмотреть все пути вызовов и выбрать максимальный по каждому из стеков.
Поскольку вручную это делать не очень удобно, я написал программу, которая находит максимальные пути автоматически.
Она приложена к данному сообщению.
Для её использования необходимо в опциях проекта включить генерацию *.LST-файлов. Программу нужно скопировать в папку "List" текущей конфигурации. После запуска программа анализирует все *.LST файлы в текущей папке, ищет максимальные пути для вычисления максимальных значений для CStack и RStack. Также программа пытается детектировать процедуры прерываний и анализирует максимальные пути для них отдельно. В качестве результата выводится сумма путей для прерываний и для обычных функций. По идее эти значения могут использоваться для задания параметров CStack и RStack компилятора.

На чём мог, я её оттестировал. Замечания и предложения приветствуются.
Прикрепленные файлы
Прикрепленный файл  Stack_1_1.zip ( 43.18 килобайт ) Кол-во скачиваний: 58
 
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Mar 25 2010, 12:05
Сообщение #2


Знающий
****

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



а файл *.map - это не то, что доктор прописал?

ЗЫ. Попробовал, загнулать с ошибкой:
Processing file: appl.lst Error: File: appl
Line: 1301
Error: 1st token must be "->" (d:\activex\Stack\Stack.dpr, line 135)

1301 строка и далее:
Par::bs_serialize(Par::TByteStream *, TPulseInfo &)
5 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
5 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)

Не работает с С++?
Go to the top of the page
 
+Quote Post
Dmitro25
сообщение Mar 25 2010, 12:22
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



2Непомнящий Евгений:
*.map файл я пытался смотреть, но нужной информации не нашёл. Может, не там искал, может, не включил нужные опции для генерации правильного файла. Подскажите, куда смотреть.

Что касается Вашего С++ файла: действительно, я пока имел возможность проверить программу только на своих С-проектах. На С++ пока ничего не пишу. Не могли бы Вы выслать окончание *.LST файла, вызвавшего ошибку, начиная со строки "Maximum stack usage in bytes:".
Go to the top of the page
 
+Quote Post
LessNik
сообщение Mar 25 2010, 12:37
Сообщение #4


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

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



Options\Linker: Generate linker listing, Static overlay map и т.д. Можно в виде HTML вывести
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Mar 25 2010, 12:58
Сообщение #5


Знающий
****

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



Цитата(Dmitro25 @ Mar 25 2010, 15:22) *
Не могли бы Вы выслать окончание *.LST файла, вызвавшего ошибку, начиная со строки "Maximum stack usage in bytes:".

CODE

Maximum stack usage in bytes:

Function CSTACK RSTACK
-------- ------ ------
Par::bs_serialize(Par::TByteStream *, TPulseInfo &)
5 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
5 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
5 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
5 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
5 2
Par::bs_serialize(Par::TByteStream *, uint &, uint_fast8_t)
0 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
0 2
Par::bs_serialize(Par::TByteStream *, uint_fast8_t &, uint_fast8_t)
0 2
-> Par::bs_serialize(Par::TByteStream *, void *, unsigned int, unsigned int)
0 2
TErrorInfo::init(uint16_t, byte, byte, byte, byte, byte)
1 2
convertVolumeLI(ulong, uint, uint)
16 4
divideWithMathRounding(ulong, ulong)
8 4
findInStr(char, tpz::stringFl) 0 2
hp_alloc(THeap *, byte) 6 4
hp_alloc_and_set_error(THeap *, byte, uint)
16 4
-> hp_alloc(THeap *, byte) 9 2
-> TErrorInfo::init(uint16_t, byte, byte, byte, byte, byte)
10 2
-> setError(TErrorInfo) 16 2
hp_dump(THeap *) 4 2
-> USART1_Transmit(byte) 4 2
-> USART1_Transmit(byte) 4 2
-> USART1_Transmit(byte) 4 2
-> USART1_Transmit(byte) 4 2
hp_free(THeap *, unsigned char *)
0 4
hp_init(THeap *, unsigned char *, uint)
4 4
pfindInStr(char, tpz::stringFl)
0 2
pi_init(TPulseInfo *, byte, uint, uint, byte)
0 2
pi_process(TPulseInfo *, byte) 0 2
pstrGetCountStr(tpz::stringFl) 0 2
pstrGetNStr(tpz::stringFl, byte)
16 4
-> TErrorInfo::init(uint16_t, byte, byte, byte, byte, byte)
10 2
-> setError(TErrorInfo) 16 2
strlenFl(tpz::stringFl) 0 2


Segment part sizes:

Function/Label Bytes
-------------- -----
TErrorInfo::init(uint16_t, byte, byte, byte, byte, byte)
30
Par::bs_serialize(Par::TByteStream *, uint_fast8_t &, uint_fast8_t)
10
Par::bs_serialize(Par::TByteStream *, uint &, uint_fast8_t)
10
hp_init(THeap *, unsigned char *, uint)
64
hp_alloc(THeap *, byte) 238
hp_alloc_and_set_error(THeap *, byte, uint)
54
?Subroutine0 10
hp_free(THeap *, unsigned char *)
132
hp_dump(THeap *) 70
?Subroutine1 10
Par::bs_serialize(Par::TByteStream *, TPulseInfo &)
176
pi_init(TPulseInfo *, byte, uint, uint, byte)
62
pi_process(TPulseInfo *, byte) 332
strlenFl(tpz::stringFl) 20
findInStr(char, tpz::stringFl) 30
pfindInStr(char, tpz::stringFl)
38
pstrGetNStr(tpz::stringFl, byte)
84
pstrGetCountStr(tpz::stringFl) 32
convertVolumeLI(ulong, uint, uint)
214
divideWithMathRounding(ulong, ulong)
144


1 760 bytes in segment CODE

1 710 bytes of CODE memory (+ 50 bytes shared)

Errors: none
Warnings: none
Go to the top of the page
 
+Quote Post
Dmitro25
сообщение Mar 25 2010, 13:18
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



2LessNik:
Спасибо за подсказку. Вы правы, дело было в галочке "Static overlay map".
Выходит, зря программу написал.
Единственно, неудобно, что в *.map файле вначале идут деревья прерываний, а затем основного кода, лучше бы наоборот. Я не разрешаю прерывания внутри функции прерывания, поэтому наложиться они не могут. А линкер суммирует размер стека из предположения, что внутри одного прерывания могут возникнуть и остальные.
Go to the top of the page
 
+Quote Post
Dmitro25
сообщение Mar 26 2010, 04:14
Сообщение #7


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



На всякий случай выкладываю программу v1.2. Жалко потраченного времени, да и вдруг кому пригодится.
Должна поддерживать С++.
Прикрепленные файлы
Прикрепленный файл  Stack_1_2.rar ( 47.07 килобайт ) Кол-во скачиваний: 87
 
Go to the top of the page
 
+Quote Post
bseyur
сообщение Mar 30 2010, 08:00
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208



Интересно, а есть ли аналогичная возможность для arm-версии? Было бы не плохо, чтобы вручную не искать зависимости функций.
Go to the top of the page
 
+Quote Post
Sajan
сообщение Apr 27 2010, 10:15
Сообщение #9


Участник
*

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



Насколько я понимаю, эта встроенная в IAR функция по анализу использования стэка есть во всех версиях. Я её использовал ещё лет 5 назад в IAR для MSP430. Правда в настройке стэка всё-равно небольшой запас ещё делаю.
Go to the top of the page
 
+Quote Post
Zlumd
сообщение Apr 29 2010, 01:05
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 12-04-05
Из: Новосибирск
Пользователь №: 4 057



Цитата(LessNik @ Mar 25 2010, 19:37) *
Options\Linker: Generate linker listing, Static overlay map и т.д. Можно в виде HTML вывести
Я у себя в проекте использую ассемблерные процедуры. Они включены в проект как файлы с расширением s90. Можно ли что-то прописать в s90-файле, чтобы в Linker-листинге учитывался размер используемого пространства в CSTACK и RSTACK ?
Go to the top of the page
 
+Quote Post
Sajan
сообщение May 1 2010, 14:35
Сообщение #11


Участник
*

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



А разве при должном оформлении процедур в ассемблере и вызове их как обычной сишной процедуры из основного тела программы (например, из main.c) эти вызовы не учитываются?
Go to the top of the page
 
+Quote Post
bseyur
сообщение May 2 2010, 11:05
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208



Цитата(Sajan @ Apr 27 2010, 17:15) *
Насколько я понимаю, эта встроенная в IAR функция по анализу использования стэка есть во всех версиях. Я её использовал ещё лет 5 назад в IAR для MSP430. Правда в настройке стэка всё-равно небольшой запас ещё делаю.

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

Сообщение отредактировал bseyur - May 2 2010, 11:06
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 25th June 2025 - 22:12
Рейтинг@Mail.ru


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