syoma 1 25 августа, 2021 Опубликовано 25 августа, 2021 · Жалоба Привет, Я понимаю, что архитектура уже давно устарела, но появился сабжевый вопрос. Прога на Си, много статических переменных, после последних изменений прога стала подглючивать на железе. Есть подозрение на переполнение стека, так как если для него отвести больше места - частота глюков уменьшается. Как узнать в этом ли проблема из самой программы? Средств отладки кроме самого камня на плате и осцилографов нет. Мониторить указатель стека или какие еще варианты? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 25 августа, 2021 Опубликовано 25 августа, 2021 · Жалоба Ну да, мониторинг. Если средства позволяют, можно задействовать аналог "стековой канарейки". При переполнении вызовется специальный callback, где можно будет дернуть ножкой. Но накладные расходы увеличатся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 5 25 августа, 2021 Опубликовано 25 августа, 2021 · Жалоба В стародавние времена память под стек заполняли однотипными значениями. Программу гоняли некоторое время в разных режимах. Затем - останавливали и смотрели на значения ячеек памяти, выделенной под стек. Так в первом приближении определялся потребный размер стека. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба Добавил в программу вывод максимального значения регистра указателя стека SP и получил интересный прикол: Проглядывая листинг после компилятора, вижу, что стек используется только в функциях обработки прерываний. Т.е. там стоит такое: T2_int: PUSH PSW PUSH ACC PUSH DPH PUSH DPL PUSH B PUSH _R PUSH _R+1 PUSH _R+2 PUSH _R+3 PUSH _R+4 PUSH _R+5 PUSH _R+6 PUSH _R+7 Ну и при возвращении из них, соответственно: POP _R+7 POP _R+6 POP _R+5 POP _R+4 POP _R+3 POP _R+2 POP _R+1 POP _R POP B POP DPL POP DPH POP ACC POP PSW RETI Т.е. это 13 байт + в стек пихается адрес возврата - 2 байта Program Counter(PC). Т.е. всего 15 байт. Больше PUSH и POP не используются нигде в программе - я проверял все листинги. У меня два уровня вложенности/приоритета прерываний (8051 больше не позволяет), т.е получается, что в худшем случае достаточная величина стека должна быть: 15(регистры и PC основной программы при первом прерывании) + 15 (регистры и PC первого прерывания при прерывании с более высоким приоритетом) = 30 байт, что собственно мне линкер и показывает в дампе памяти, выделив аж 29 байт на стек. Но в реале, когда я добавил мониторинг SP, при работе программы указатель стека опускается аж на 43 байта. Почему так? Это я что-то не учитываю, или это у меня прерывания неправильно работают? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба CALL'ы используются? Они тоже стек используют Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба Может, принудительное выравнивание стека компилятором используется? Согласно какому-нибудь ABI, например. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба 17 minutes ago, xvr said: CALL'ы используются? Они тоже стек используют Да, используются. Извиняюсь, мой провтык. Получается, что CALL тоже засовывает PC стек и в итоге выходит, что чтобы рассчитать нужную величину стека, нужно еще посчитать вложенность всех функций. Мда, задачка не из легких. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба А локальные переменные в функциях где у вас живут ? Или у вас два стека : программный стек и стек данных ? Как это например делает IAR для AVR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба 12 minutes ago, dimka76 said: А локальные переменные в функциях где у вас живут ? В data overlay сегменте памяти. По крайней мере судя по листингу, обращение к ним не через стек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба 5 hours ago, dimka76 said: А локальные переменные в функциях где у вас живут ? Вот тут нашел еще один прикол - у меня в прерываниях используются локальные переменные, которые, как я понял, находятся тоже в data overlay. Что произойдет с ними, если прерывание с более высоким приоритетом прервет прерывание с низким приоритетом, в котором используются локальные переменные? Получается, что оно может испортить их значение? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 26 августа, 2021 Опубликовано 26 августа, 2021 · Жалоба 8 minutes ago, syoma said: Вот тут нашел еще один прикол - у меня в прерываниях используются локальные переменные, которые, как я понял, находятся тоже в data overlay. Что произойдет с ними, если прерывание с более высоким приоритетом прервет прерывание с низким приоритетом, в котором используются локальные переменные? Получается, что оно может испортить их значение? https://www.keil.com/support/man/docs/bl51/bl51_overlaying.htm Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 27 августа, 2021 Опубликовано 27 августа, 2021 · Жалоба 20 hours ago, dimka76 said: https://www.keil.com/support/man/docs/bl51/bl51_overlaying.htm Почитал и поменял нафиг все локальные переменные в прерываниях на статические, так как не знаю насколько хорошо мой компилятор умеет этот overlay. Также заменил вызовы функций в прерываниях и где возможно в основной программе на их копии. Да, размер кода слегка увеличился, но думаю так будет надежнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться