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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Глюки программирования mega128, в WinAvr или МикроПаскале
Who_are_you?
сообщение Aug 9 2017, 07:15
Сообщение #1


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

Группа: Участник
Сообщений: 185
Регистрация: 5-02-10
Из: Донецк
Пользователь №: 55 329



Программирую систему на ATmega128
и неважно на СИ или Паскале в WinAvr или МикроПаскале

Но возникает ситуация когда прошу, например,
подпрограмме вывести на LCD текст, а она вываливается (перезапускает main);
или не выполняются переходы при работе с прерываниями.

Я предполагал что это из-за стека, но нигде не видел в реальных программах даже обращений к стеку.
Мои эксперименты со стеком ничего не дали.
Как добиться логичности, чтобы переходы были такие, как написаны в программе, а не с глюками?
Не могут же разные компиляторы иметь похожие проблемы!
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Aug 9 2017, 11:21
Сообщение #2


Знающий
****

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



Вы название темы правильно указывайте - "Глюки моей программы для мега128" sm.gif

Что значит "не видел в реальных программах даже обращений к стеку"? Как только в программе появляется функция, так сразу там есть обращение к стеку.

А по теме - отлаживайте. Если есть отладчик - после появления проблемы останавливайте выполнение и смотрите, где вы оказались и почему, какое состояние стека, глобальных данных. Дальше ставите бряки (в т.ч. на изменение данных) и выясняете проблемное место.

Если отладчика нет - делаете минимально работающую программу и постепенно добавляете в нее функционал. Когда появляются проблемы - тщательно изучаете добавленное последним...

Причину перезагрузки (сброс, вотчдог и т.п.) можно выяснить, в меге128 помнится есть соотв. регистр.
Go to the top of the page
 
+Quote Post
Who_are_you?
сообщение Aug 9 2017, 15:35
Сообщение #3


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

Группа: Участник
Сообщений: 185
Регистрация: 5-02-10
Из: Донецк
Пользователь №: 55 329




Непомнящий Евгений, спасибо за корректировку выражений.

Почему-то не могу настроить WinAvr совместно с AvrStudio

Как поймать неправильный выход из подпрограмм?
По программе я после Break должен выйти из for,
а реально начинается перезагруз заново main.

Может есть для мега128 какой-то общий подход, в том числе и контроля стека?
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Aug 9 2017, 15:44
Сообщение #4


Знающий
****

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



Цитата(Who_are_you? @ Aug 9 2017, 18:35) *
Может есть для мега128 какой-то общий подход, в том числе и контроля стека?


Заполните стек неким паттерном (0xdeadbeaf или на ваш вкус) и гляньте, что с ним сразу после перезагрузки. Дальше можно поставить бряк на изменение памяти вблизи низа стека - по идее в нормально режиме работы ваша программа туда доходить не должна.

Узнайте причину перезагрузки (см даташит, есть какой-то регистр с соотв. флагами). Если это вотчдог - отключите его, так проще выловить зависания ПО.

А так - получите минимальную рабочую программу и постепенно добавляйте кусочки.

Go to the top of the page
 
+Quote Post
Who_are_you?
сообщение Aug 9 2017, 16:47
Сообщение #5


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

Группа: Участник
Сообщений: 185
Регистрация: 5-02-10
Из: Донецк
Пользователь №: 55 329



вотчдог - отключен

программа большая, но была рабочая: LCD- работа с меню
Добавляю кусочками

Все работало пока не всунул работу с портом по прерыванию.
Прерывание настроил, но в некоторых случаях из глубины меню
нет выхода по программе, а реально начинается перезагруз заново main.
Go to the top of the page
 
+Quote Post
aiwa
сообщение Aug 9 2017, 17:31
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Вначале функции main прочитайте регистр MCUSR: в нем побитовые источники перегрузки контроллера.

Очень странно, что контроллер ресетится: при программной ошибке это довольно маловероятное событие, скорее он должен просто зависнуть.
Ресет наводит на мысль перегрузки по аппаратной причине: собака, или просадка питания.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Aug 10 2017, 05:07
Сообщение #7


Знающий
****

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



Цитата(Who_are_you? @ Aug 9 2017, 19:47) *
Все работало пока не всунул работу с портом по прерыванию.
Прерывание настроил, но в некоторых случаях из глубины меню
нет выхода по программе, а реально начинается перезагруз заново main.


Вот сюда и копайте. Нет ли "гонки" между основной программой и прерыванием (volatile, запрет прерываний при работе с разделяемыми данными), нет ли вызова каких-то "тяжелых" функций из прерывания (который кушают много стека) и т.п.

Засеките размер используемого стека до и после прерывания, вставьте проверку - если стека осталось мало - повиснуть, выдав наружу сигнал об этом
Go to the top of the page
 
+Quote Post
aiwa
сообщение Aug 10 2017, 10:54
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Проверьте на всякий случай фьюзы.
Не установлен ли фьюз совместимости с 103.
Go to the top of the page
 
+Quote Post
Who_are_you?
сообщение Aug 11 2017, 09:29
Сообщение #9


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

Группа: Участник
Сообщений: 185
Регистрация: 5-02-10
Из: Донецк
Пользователь №: 55 329



Я в чем не прав?

Код
#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],
чтобы стек не вводить в казус?
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Aug 11 2017, 09:59
Сообщение #10


Знающий
****

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



Цитата(Who_are_you? @ Aug 11 2017, 12:29) *
Я в чем не прав?


ну вообще говоря при чем тут стек?
Код
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);


Go to the top of the page
 
+Quote Post
Who_are_you?
сообщение Aug 11 2017, 10:42
Сообщение #11


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

Группа: Участник
Сообщений: 185
Регистрация: 5-02-10
Из: Донецк
Пользователь №: 55 329



Цитата
ну вообще говоря при чем тут стек?

объявление переменной в подпрограмме занимает место в стеке
Go to the top of the page
 
+Quote Post
aiwa
сообщение Aug 11 2017, 11:23
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Код
cchh = (char)RxBuf[7];                          LCD_WriteText (8,&cchh); // 1


Этот код тоже неаккуратный и он рабочий лишь потому, что в результате построения фрейма стека по соседству с cchh счастливым образом оказался завершающий строку ноль.
Go to the top of the page
 
+Quote Post
Who_are_you?
сообщение Aug 15 2017, 09:40
Сообщение #13


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

Группа: Участник
Сообщений: 185
Регистрация: 5-02-10
Из: Донецк
Пользователь №: 55 329



Почему в 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();
Go to the top of the page
 
+Quote Post
aiwa
сообщение Aug 15 2017, 11:02
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Зависит от компилятора, но обычно для первого случая он генерирует такую же переменную, как и во втором случае:
Код
char _сгенерируемая_компилятором_метка_ [] = "Error_RS422: ";
Text_Menu_String (8,20,1, _сгенерируемая_компилятором_метка_);

только вот складирует эти переменные в самостоятельно определенном сегменте памяти.
Скорее всего именно эта память и портится.

Сообщение отредактировал aiwa - Aug 15 2017, 11:03
Go to the top of the page
 
+Quote Post
KRS
сообщение Aug 15 2017, 15:04
Сообщение #15


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Who_are_you? @ Aug 15 2017, 12:40) *
Почему в 1) случае выводится не всегда указанный текст,
а во 2) случае все четко

потому что у avr классическая гарвардская архитектура (и флеш отмаплен только на адресное пространство команд, а озу только на данные) и константы из флеша загружаются специальными командами
во 2 случае данные из флеша копируются в переменную размещенную в ОЗУ.
А в 1, размещаются в стеке

В любом случае происходит лишнее копирование данных!
Поэтому для AVR функции которые принимают аргумент в виде константной строки используют специальный тип, что бы строка оставалась во флеше...
Go to the top of the page
 
+Quote Post

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

 


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


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