Who_are_you? 0 9 августа, 2017 Опубликовано 9 августа, 2017 · Жалоба Программирую систему на ATmega128 и неважно на СИ или Паскале в WinAvr или МикроПаскале Но возникает ситуация когда прошу, например, подпрограмме вывести на LCD текст, а она вываливается (перезапускает main); или не выполняются переходы при работе с прерываниями. Я предполагал что это из-за стека, но нигде не видел в реальных программах даже обращений к стеку. Мои эксперименты со стеком ничего не дали. Как добиться логичности, чтобы переходы были такие, как написаны в программе, а не с глюками? Не могут же разные компиляторы иметь похожие проблемы! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 9 августа, 2017 Опубликовано 9 августа, 2017 · Жалоба Вы название темы правильно указывайте - "Глюки моей программы для мега128" :) Что значит "не видел в реальных программах даже обращений к стеку"? Как только в программе появляется функция, так сразу там есть обращение к стеку. А по теме - отлаживайте. Если есть отладчик - после появления проблемы останавливайте выполнение и смотрите, где вы оказались и почему, какое состояние стека, глобальных данных. Дальше ставите бряки (в т.ч. на изменение данных) и выясняете проблемное место. Если отладчика нет - делаете минимально работающую программу и постепенно добавляете в нее функционал. Когда появляются проблемы - тщательно изучаете добавленное последним... Причину перезагрузки (сброс, вотчдог и т.п.) можно выяснить, в меге128 помнится есть соотв. регистр. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 9 августа, 2017 Опубликовано 9 августа, 2017 · Жалоба Непомнящий Евгений, спасибо за корректировку выражений. Почему-то не могу настроить WinAvr совместно с AvrStudio Как поймать неправильный выход из подпрограмм? По программе я после Break должен выйти из for, а реально начинается перезагруз заново main. Может есть для мега128 какой-то общий подход, в том числе и контроля стека? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 9 августа, 2017 Опубликовано 9 августа, 2017 · Жалоба Может есть для мега128 какой-то общий подход, в том числе и контроля стека? Заполните стек неким паттерном (0xdeadbeaf или на ваш вкус) и гляньте, что с ним сразу после перезагрузки. Дальше можно поставить бряк на изменение памяти вблизи низа стека - по идее в нормально режиме работы ваша программа туда доходить не должна. Узнайте причину перезагрузки (см даташит, есть какой-то регистр с соотв. флагами). Если это вотчдог - отключите его, так проще выловить зависания ПО. А так - получите минимальную рабочую программу и постепенно добавляйте кусочки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 9 августа, 2017 Опубликовано 9 августа, 2017 · Жалоба вотчдог - отключен программа большая, но была рабочая: LCD- работа с меню Добавляю кусочками Все работало пока не всунул работу с портом по прерыванию. Прерывание настроил, но в некоторых случаях из глубины меню нет выхода по программе, а реально начинается перезагруз заново main. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 9 августа, 2017 Опубликовано 9 августа, 2017 · Жалоба Вначале функции main прочитайте регистр MCUSR: в нем побитовые источники перегрузки контроллера. Очень странно, что контроллер ресетится: при программной ошибке это довольно маловероятное событие, скорее он должен просто зависнуть. Ресет наводит на мысль перегрузки по аппаратной причине: собака, или просадка питания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 10 августа, 2017 Опубликовано 10 августа, 2017 · Жалоба Все работало пока не всунул работу с портом по прерыванию. Прерывание настроил, но в некоторых случаях из глубины меню нет выхода по программе, а реально начинается перезагруз заново main. Вот сюда и копайте. Нет ли "гонки" между основной программой и прерыванием (volatile, запрет прерываний при работе с разделяемыми данными), нет ли вызова каких-то "тяжелых" функций из прерывания (который кушают много стека) и т.п. Засеките размер используемого стека до и после прерывания, вставьте проверку - если стека осталось мало - повиснуть, выдав наружу сигнал об этом Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 10 августа, 2017 Опубликовано 10 августа, 2017 · Жалоба Проверьте на всякий случай фьюзы. Не установлен ли фьюз совместимости с 103. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 11 августа, 2017 Опубликовано 11 августа, 2017 · Жалоба Я в чем не прав? #define BUFFER_SIZE 255 // unsigned char RxBuf [BUFFER_SIZE]; // // void LCD_WriteText (char font, char * text) void PRFMenu (void) // { char *buffer="0"; char cchh; unsigned char rank[3] = {0,0,0}; cchh = (char)RxBuf[7]; LCD_WriteText (8,&cchh); // 1 itoa (RxBuf[3],buffer,10); LCD_WriteText (8,buffer); // 2 itoa (rank[2], buffer, 10); LCD_WriteText (8,buffer); // 3 } объявление указателя buffer на строку из 2 байтов // 1 - в RxBuf[7] - символ а во 2 и 3 случае в buffer запихивается байт или больше или нужно присвоение через cchh = RxBuf[3], чтобы стек не вводить в казус? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 11 августа, 2017 Опубликовано 11 августа, 2017 · Жалоба Я в чем не прав? ну вообще говоря при чем тут стек? char *buffer="0"; // это указатель на константу в памяти. Си дает так сделать? Может и дает, но менять ее нельзя. Для avr это по факту будет 2 байта в ОЗУ itoa (RxBuf[3],buffer,10); // вы меняете константу :maniac: Более того, если RxBuf[3] скажем 123, то вы меняете 4 байта (1,2,3,\0), т.е. расстреливаете 2 байта ОЗУ после этой константы Лучше как-то так char buffer[4]; itoa (RxBuf[3],buffer,10); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 11 августа, 2017 Опубликовано 11 августа, 2017 · Жалоба ну вообще говоря при чем тут стек? объявление переменной в подпрограмме занимает место в стеке Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 11 августа, 2017 Опубликовано 11 августа, 2017 · Жалоба cchh = (char)RxBuf[7]; LCD_WriteText (8,&cchh); // 1 Этот код тоже неаккуратный и он рабочий лишь потому, что в результате построения фрейма стека по соседству с cchh счастливым образом оказался завершающий строку ноль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Who_are_you? 0 15 августа, 2017 Опубликовано 15 августа, 2017 · Жалоба Почему в 1) случае выводится не всегда указанный текст, а во 2) случае все четко // void Text_Menu_String (char font, unsigned char x, unsigned char y, char * text) // 1) Код: Text_Menu_String (8,20,1, "Error_RS422: "); // 2) Код: char ER [] = "Error_RS422: ") Text_Menu_String (8,20,1, ER); // Разрешены прерывания только по UART ну и sei(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 15 августа, 2017 Опубликовано 15 августа, 2017 (изменено) · Жалоба Зависит от компилятора, но обычно для первого случая он генерирует такую же переменную, как и во втором случае: char _сгенерируемая_компилятором_метка_ [] = "Error_RS422: "; Text_Menu_String (8,20,1, _сгенерируемая_компилятором_метка_); только вот складирует эти переменные в самостоятельно определенном сегменте памяти. Скорее всего именно эта память и портится. Изменено 15 августа, 2017 пользователем aiwa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 15 августа, 2017 Опубликовано 15 августа, 2017 · Жалоба Почему в 1) случае выводится не всегда указанный текст, а во 2) случае все четко потому что у avr классическая гарвардская архитектура (и флеш отмаплен только на адресное пространство команд, а озу только на данные) и константы из флеша загружаются специальными командами во 2 случае данные из флеша копируются в переменную размещенную в ОЗУ. А в 1, размещаются в стеке В любом случае происходит лишнее копирование данных! Поэтому для AVR функции которые принимают аргумент в виде константной строки используют специальный тип, что бы строка оставалась во флеше... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться