Утилита для нахождения необходимого и достаточного объёма стека.

Copyright © 2004-2005, Сергей Пинигин.

VER:1.59 [03.2005]
RAM, как и денег, сколько бы не было - все равно мало...

Зачем это надо?

Стек нужно считать ВСЕГДА:

  1. Чтобы быть уверенным, что стек не переполнится при работе ПО аппаратуры во всех режимах и всех возможных ситуациях. John Regehr в своих работах характеризует это как 'stack safety' _ критерий надёжности встраиваемых систем.

    Как правило, проверить все режимы работы ПО при всех возможных стеченьях обстоятельств достаточно затруднительно или вообще не представляется возможным (пример: самая напряжённая ситуация возникнет всего 1 раз в течение одного года непрерывной работы или трёх лет, или ...).

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

  1. Чтобы ясно представлять потребление стека функциями (не штудируя ASM листинги), а после анализа оптимально использовать стек, особенно при большом количестве вложенных вызовов.
  2. Чтобы точно знать, сколько ещё осталось памяти для "кучи".
  3. Чтобы контролировать Си-компилятор и иногда находить его тонкие места. ;-)

Если в системе применяется OS или прерывания с несколькими уровнями приоритетов или и первое и второе, то необходимо вычислять максимальный объем стека для каждой задачи и каждого обработчика прерывания. Затем выбрать максимум для каждой группы обработчиков с одинаковым приоритетом и вычислять сумму максимумов групп... На листочке карандашом это делать быстро надоедает.

C-analise из комплекта Softune красив, но не практичен для частого применения (подробнее, пример отчёта), но это и не основная его задача, что следует из названия. Поэтому и сделана утилита CALC_STK, благо Си-компилятор Softune предоставляет исчерпывающую информацию для построения дерева вызовов и расчётов.

Выполняемые операции:

  • Нахождение всех возможных цепочек вызовов функций.

  • Вычисление максимального объёма стека (МОС) для функции

    • с учетом вызова библиотечных функций
    • с учетом вызовов функций по указателю (список формирует пользователь)
  • Вычисление МОС для

    • списка функций (список формирует пользователь)

    • группы функций и вычисление

      • максимума из элементов группы

        Применение: обработчики прерываний с одинаковым приоритетом

      • суммы элементов группы

        Применение: результирующий стек для обработчиков прерываний всех уровней и main

  • Выводит список всех функций (type: ROOT), вызовы которых не найдены:

    • _main, _task's
    • Обработчики прерываний.
    • Функции, вызываемые по указателю.
    • Не используемые функции - мёртвый груз, только занимают место...

Входные файлы:

Обязательные:

  • .STK-файлы проекта.

  • .MAP-файл проекта.

    Секция "Input module(s)" должна содержать список включенных в проект объектных файлов и библиотек.

    Список НЕ сортируется программой CALC_STK, поэтому:

    • Библиотеки должны перечисляться после указания всех объектных файлов.
    • Если библиотек несколько и каждая приведена не один раз, то все строки с именем одной библиотеки должны идти по порядку.

Необязательные:

  • .STK-файлы библиотек от Softune V3 или Softune V6.

    Требуется при использовании библиотечных функций.

    После инсталляции располагаются в каталоге [Softune Path]\lib\9xx\

Результаты работы утилиты:

Все данные о процессе работы программы поступают на стандартное устройство вывода, для сохранения результатов и последующего анализа следует перенаправить вывод в файл стандартными средствами операционной системы.

Выходные данные:

  • Протокол процесса считывания файлов с данными о потреблении стека.
  • Список ROOT-функций.
  • Результаты вычислений:
    • Все возможные цепочки вызовов для исследуемой функции.
    • Величина объёма стека для каждой цепочки вызовов.
    • МОС для функции (!!! без учета предупреждений).
    • Первая цепочка с МОС (выводится после всех вычислений).
    • Количество цепочек объем стека которых равен МОС.
    • Предупреждения:
      • {A}: наличие в функции асм-вставок. Результат не учитывает операций со стеком в асм-вставках.
      • +??? (_func_x): вызов не найденной в предоставленных файлах функции, в скобках указано имя неизвестной функции. Стек цепочки вычисляется до неизвестного вызова.
      • {Z}: зацикливание вызовов в цепочке. Стек цепочки вычисляется до повторного вызова функции.
    • МОС для списка функций.
    • Максимум МОС для группы функций.
    • Сумма МОС группы функций или списка групп.

Единица измерения глубины стека:

Все вычисления выполняются и выводятся в BYTE

Порядок действий:

1. Получить информацию о потреблении стека функциями.

Необходимо компилировать все файлы проекта с опцией '-INF STACK'.

Примечание

При размещении stk-файлов проекта в одном каталоге с объектными файлами не требуется указывать путь в параметре -I.

Stk-файлы стандартных библиотек должны находиться в каталоге с библиотеками.

2. Собрать проект и получить map-файл.

Обычно map-файл размещают в каталоге проекта LST, он имеет расширение mp1 или map.

3. Выполнить вычисления.

Параметры запуска описаны в Приложении 1. Форматы дополнительных файлов описаны в Приложении 2 и Приложении 3

Вывод стОит перенаправить в файл, для последующего анализа

CALC_STK.EXE LST\PROJECT.MAP >_MAIN.CSS

или

CALC_STK.EXE LST\PROJECT.MAP -F _Test -i LST >_TEST.CSS

Примечание

Если в map-файле (перед именами объектных файлов) или /I-параметре присутствуют относительные каталоги, то запускать следует в том каталоге, относительно которого эти каталоги заданы.

4. Анализировать результаты.

  • Размер стека для каждой цепочки вложенных вызовов.
  • Максимальная величина размера стека.
  • Предупреждения.

Пример 1 - вычислить МОС и отобразить максимальную цепочку.

Пример 2 - вывести все цепочки в альтернативном виде, вычислить МОС.

Приложение 1.

Подсказка по параметрам строки запуска:

  RUN:                calc_stk.exe [path]MAP-FILE [PARAMETERS]

TARGET:        /f _XXX         - function name (default: _main)
               /g list.grp     - list function and group for analyse

ADD FILES:     /p ptr_file.pst - file with '$pointer_call' replace info
               /e exc_file.lst - file with list exclude objects stk-file

PATH:          /i path         - path for find objects stk-file

RESULT FORMAT: /m              - maximum and warning result [{A}|+???|{Z}]
                                 {A}  - inline asm
                                 +??? - no info of stack
                                 {Z}  - recursive call in chain
               /c              - chain, result for chain and maximum
               /v              - view chain with maximum stack size
      default:                 - result for chain and maximum

OTHER:         /l              - view list of ROOT-function

DEBUG: /q [/r|/s]  - read operation of stack info files and result of scan

Запуск.

Вычислить стек для функции _main:

CALC_STK.EXE LST\PRJ.MAP

Вычислить стек для функции _main (stk-файлы проекта расположены в каталоге lst):

CALC_STK.EXE LST\PRJ.MAP -I LST

Вычислить стек для списка функции:

CALC_STK.EXE LST\PRJ.MAP /G FUNC.LST

Параметры.

Префиксом может быть '-' или '/'.

Имена параметров не чувствительны к регистру.

-M  == /m

Цели (необходимо указать одно из):

/f _XXX:Исследовать одну функцию (по умолчанию: _main).
/g stack.grp:Файл со списком функций и/или групп.

Дополнительные файлы:

/p ptr.pst:

Файл замен $pointer_call на списки функций, вызываемых по указателю.

/e exc.lst:

Файл списка исключенных из обработки objstk-файлов.

В каждой строке имя файла. Кандидаты : start.stk, mb90f***.stk. Если указан файл исключений, и не существует какой-нибудь objstk-файл (или его не удается найти) из списка MAP-файла, то выполнение программы завершается с кодом ошибки.

Каталог размещения stk-файлов проекта:

/i path:Полный или относительный (от каталога, в котором выполняется calc_stk.exe) путь.

Результаты:

/m:

Максимальное значение и результаты цепочек с предупреждениями [ {A} | +??? | {Z} ]

/c:

Текстовый вид цепочек вызовов, результат для каждой завершённой цепочки и максимальное значение.

Дополнительный ключ /a - альтернативный вариант вывода цепочек вызовов.

/v:

Вывести цепочку вызовов с максимальным стеком.

по умолчанию:

Результаты для всех цепочек вызовов и максимальное значение.

Дополнительно:

/l:

Вывести список всех функций (type: ROOT), вызовы которых не найдены:

  • _main, _task's
  • Обработчики прерываний.
  • Функции, вызываемые по указателю.
  • Не используемые функции - мёртвый груз

Отладка:

/q:Включить отладочную информацию. Протокол чтения objstk-файлов.
/r:Дополнительный к /q: результат считывания файлов.
/s:Дополнительный к /q: вывод базы после первого прохода.

Приложение 2.

Формат файла описания замен при вызовах по указателю.

Для каждой указанной функции ссылка

$pointer_call

заменяется на приведённый список вызываемых по указателю функций.

Имя функции, для которой известны вызываемые по указателю функции
[TAB]   имя вызываемой функции1
[TAB]   имя вызываемой функции2
# ремарка
Имя2
...
# ремарка

Пример:

file begin:
-----------
     _main
             _test1
             _test2
     # ля-ля
---------
file end.

Приложение 3.

Формат файла списка групп функций.

Пример:

file begin:
-----------
        # Простой список (до списка групп)
        _main
        _test1
        _test2
        #
        # Именованный - группы
        #
        # [тип группы][Имя]
        # + - стеки (максимумы) составных частей суммируются
        # = - выбирается максимум из элементов группы
        # * - ссылка на группу/функцию, которая должна быть описана выше
        #
        =IntLevel_0
        _ih_rx_CAN0
        _ih_tx_CAN0
        #
        =IntLevel_1
        _ih_Uart0
        _ih_Uart1
        #
        # Одностековый вариант
        #
        +SystemStack
        *IntLevel_0
        *IntLevel_1
        *_main
        #
---------
file end.

Гарантии.

Присылайте пиво, будут и гарантии ;-).

Системные требования.

Операционная система Windows 95/98/2000/XP/2003/NT.
Место на жёстком диске 150 килоБайт.
Процессор: достаточно Intel: 166MHz.

Ограничения.

  • Не поддерживается режим компиляции с ключем -K ADDSP.
  • Не анализируется признак вызова статических функций. Поэтому имена всех функций без исключения должны быть индивидуальными.

DownLoad.

calc_stk_1-59.rar [72К].

Архив содержит:

  • calc_stk.exe
  • Документация:
    • readme.html
    • history.html
    • c_analyse.html
  • Каталог с примером (sample):
    • lst\ MAP-файл.
    • obj\ STK-файлы проекта.
    • readme.txt - краткое описание.
    • test_calc.bat - батник для получения файлов с основными видами отчетов.
    • c_analyse.gif - результат работы Softune C-analise.

Участники проекта:

Александр Бельченко

Алексей Дистель

Андрей Мозжевилов

Алексей Мусин