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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
forever failure
сообщение Dec 3 2007, 10:39
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



В общем такая проблема: есть устройство, которое периодически отказвает в работе - зависает. Более подробно:
mcu - Atmega128 управляет двумя устройствами по шине SPI, плюс одно на шине TWI, плюс на усарт повешен преобразователь в интерфейса rs485, через который и идёт связь с внешним миром. По внешним светодиодикам зависон выглядит так, как будто после перезагрузки по какой-то причине (по вотчдогу или пропаданию питания) контроллер начинает по новой инициализироваться и на каком-то этапе входит в вечный цикл, который обычно должен выполнятся очень быстро. После снятия напряжения питания и его восстановления зависон исчезает (на некоторое время).
Привожу часть кода инициализации, с возможно проблемными местами (пояснения ниже):
Код
/******************************************************************************/
/* avr-gcc v 4.1.2 */
#include <avr/io.h>

#define BIT(b)    (1 << b)

void spi_transmit (unsigned char c)
   {
   asm ("wdr");
   SPDR = c;
   while (!(SPSR & BIT(SPIF)));
   }  
  
void spi_str_transmit (const unsigned char * str, unsigned char size, unsigned char no)
   {
   static const unsigned char cs_bit [] = {BIT(PB4), BIT(PB6)};
   PORTB &= ~cs_bit [no];
    
   for (;size--;)
      spi_transmit (*str++);
    
   PORTB |= cs_bit [no];    
   }  
/******************************************************************************/
void twi_transmit (unsigned char data, unsigned char flags, const unsigned char stat)
   {
   asm ("wdr");
   TWDR = data;
   TWCR = flags;    
   while (!(TWCR & BIT (TWINT)));
   }

void send_twi_addr (const char a)
   {
   twi_transmit (a, BIT(TWINT) | BIT(TWEN), 0x18);
   }  

void send_twi_byte (const char b)
   {
   twi_transmit (b, BIT(TWINT) | BIT(TWEN), 0x28);
   }      
  
unsigned char read_twi_byte (void)
   {
   twi_transmit (0xFF, BIT(TWEA) | BIT(TWINT) | BIT(TWEN), 0x50);
   return TWDR;
   }    
  
void twi_start (void)
   {
   twi_transmit (0xFF, BIT(TWSTA) | BIT(TWINT) | BIT(TWEN), TWI_START);
   }    
  
void twi_stop (void)
   {  
   TWCR = BIT (TWSTO) | BIT (TWINT) | BIT (TWEN);
   TWCR = BIT (TWSTO) | BIT (TWINT);
   }

/******************************************************************************/

void init (void)
   {
   DDRF |= BIT(PF4) | BIT(PF5) | BIT(PF6) | BIT(PF7);   /* all leds */
   PORTF |= BIT(PF4) | BIT(PF5) | BIT(PF6) | BIT(PF7);  /* on */
  
   asm ("wdr");

   WDTCR = BIT(WDCE) | BIT(WDE);
   WDTCR = BIT(WDP2) | BIT(WDP1) | BIT(WDP0);           /* watchdog timeout ~ 2 sec  */
   WDTCR = BIT(WDE);  

   DDRE = BIT (0x03);                                   /* w/r rs485 driver ctrl. output enable */

   DDRA |= BIT(PA3);                                    /* debug led */
   PORTA |= BIT(PA3);                                   /* off */
   PORTD |= BIT(PD3);                                   /* internal pullup resistor */

   PORTB = BIT(PB7) | BIT(PB6)  | BIT(PB5) | BIT(PB0) | BIT(PB4);  
   DDRB = BIT(PB7) | BIT(PB6) | BIT(PB5) | BIT(PB4) | BIT(PB2) | BIT(PB1) | BIT(PB0);  
  
   while (!(PIND & BIT(PD3)));                          /* wait pwr signal */
    
   SPCR = BIT(SPE) | BIT(MSTR) | (SPR0);                /* init SPI (250 kHz) */

/* Two wire interface initialization */
   TWSR = 0; /* <- setting prescaler */
   TWBR = 0;  /* F_CPU / 16;  Bit rate = 250 kHz */

   EIMSK = BIT(INT7) | BIT(INT6) | BIT(INT3);           /* Extrnal intr. 7, 6, 3  */
   EICRB = BIT(ISC71) | BIT(ISC61);                     /* Falling edge sens.  */
  
   EICRA = BIT(ISC31);                                  /* Falling edge sens. */

   PORTE = ~BIT(0x03);                                  /* w/r rs485 driver read enable */

   UCSR0B = BIT(RXCIE0) | BIT(TXCIE0) | BIT(RXEN0) | BIT(TXEN0); /* enable intr/ on recv/send  byte  usart0 */
   UCSR0C = BIT(UCSZ01) | BIT(UCSZ00) | BIT(UPM01) | BIT(UPM00); /* async, even parity, 2 stop bit 8 bit usart0 */
   init_r (0);       /* spi_str_transmit */
   init_r (1);       /* spi_str_transmit */
  
   reset_tm ();      /* r/w twi  */
   init_s ();        /* r/w twi  */
   init_m ();        /* eeprom_read ->  UBRR0H, UBRR0L; */
   clear_list ();    /* r/w twi  */
   asm ("sei");
   PORTF &= ~(BIT(PF4) | BIT(PF5) | BIT(PF6) | BIT(PF7)); /* leds off */
   }
  
void loop (void)
   {
   for (;;)
      { /* ... */ }
   }
  
int main (void)
   {
   init ();
   loop ();
   return 0;
   }

Самое подозрительное в отношение зависания место - ожидание установки единицы на PD3:
while (!(PIND & BIT(PD3))); /* wait pwr signal */.
В реальном устройстве этот пин соединён через резистор 1к с шиной питания и вроде всегда должна там быть единица.
Другие места, где возможно организуется вечный цикл - в функциях twi_transmit и spi_transmit.

В связи с этим возникли такие вопросы :
1. Может ли линия порта ввода-вывода (и вообще порты ввода - вывода) входит в такое состояние, что уровни с неё не читаются корректно (то есть единица не воспринимается как единица)?
2. Могут ли так зависать внутринние устройства TWI - SPI, что чтение их статусных регистров всегда возвращает одно и тоже ?
3. Самое трудное - воспроизвести эту проблему не в условиях эксплуатации, а на месте, где её можно решить. Одно из устройств сейчас гоняю всяко - на мороз его выставляю, помехи возле него создаю, влажность повышенную - всё нипочём, - всегда бы так работало. Какие ещё дестабилизирующие средства можно применить ?
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 3 2007, 11:17
Сообщение #2


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(forever failure @ Dec 3 2007, 13:39) *
Одно из устройств сейчас гоняю всяко - на мороз его выставляю, помехи возле него создаю, влажность повышенную - всё нипочём, - всегда бы так работало. Какие ещё дестабилизирующие средства можно применить ?

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

Если проблема воспроизводится в "поле", то было бы непохо в ваше изделие вставить возможность делать хотя бы частичный дамп памяти и регистров проца и периферии, например по прерыванию от WDT, и сохранять его в eeprom с возможностью вычитки после рестарта..

Кстати, если устройство подвисло, то почему не перезагрузилось по WDT?

Цитата
2. Могут ли так зависать внутринние устройства TWI - SPI, что чтение их статусных регистров всегда возвращает одно и тоже ?

Могут, если некоторые состояния намерено или случайно игнорируются драйвером.

Цитата
1. Может ли линия порта ввода-вывода (и вообще порты ввода - вывода) входит в такое состояние, что уровни с неё не читаются корректно (то есть единица не воспринимается как единица)?

нет.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Dec 3 2007, 11:53
Сообщение #3


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



На TWI может висеть атмелевская 24-я, требующая 9 клоков до начала работы.


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 3 2007, 12:06
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



на TWI висит rtc+fram FM3130 может ли она так шину завесть, что её надо сбрасывать отключением питания ? По поводу WDT тоже не совсем понятно, похоже сброс всё таки есть, но он не помогает, так как есть что-то, что не сбрасывается сигналом, генерируемым вочдогом.
Ещё один момент был - когда замерял все напряжения на зависшем устройстве - при касании щупа вольтметра этой ноги PD3 успройство ожило и пошло работать дальше, почему и возникло предположение про порты ввода-вывода.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 3 2007, 12:10
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Включите BOD + управлять питанием или сбросом остальных устройств через контроллер при инициализации ,так как они могут продолжать работать ниже порога BOD и естественно это вызовет коллизию на шине.
А в общем очень похоже на гульки по питанию ,у меня такие номера выделывала кренка когда перегревалась или сдыхала,сам транс тоже может - если маломощный стоит.
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 3 2007, 12:23
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



BOD включен, уровень = 2.7в. В нормальном режиме напряжение питания примерно 4 в, при работе может изменятся да 4.5 в, в зависимости от тока потребления других устройств. Источник питания - маломощный импульсный стабилизатор плюс ограничивающий резистор 15 Ом по шине питания.

Хуже всего, что не получается эту ситуацию воспроизвести.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 3 2007, 12:38
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Начинается ... :D
15 Ом - это много ,при токе в 100мА ,сопротивление даст просадку в полтора вольта.Зажгете пару лишних светодиодов и уйдте в ступор.
Вы осциллом питание меряли ? там наверное не 4 вольта ,а полный абзац smile.gif
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 3 2007, 12:43
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



15 Ом - это требование по искробезопасности цепи, его никак не обойти. А максимальный ток потребления по внутренним цепям с овсеми светодиодами - порядка 60 мА. Конечно, хреновая ситуация, но от неё никак не избавится. Осциллятором смотрел - ступеньку в полвольта видно, когда все потребители отключаются. Больше никаких особенностей, всякой высокочастотной ереси по питанию н наблюдается.
Go to the top of the page
 
+Quote Post
GDI
сообщение Dec 3 2007, 12:55
Сообщение #9


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
Самое подозрительное в отношение зависания место - ожидание установки единицы на PD3:
while (!(PIND & BIT(PD3))); /* wait pwr signal */.
В реальном устройстве этот пин соединён через резистор 1к с шиной питания и вроде всегда должна там быть единица.

Почему бы не попробовать закомментировать эту строку и не прогнать программу на реальном устройстве если там всегда должна быть единица. И чего вы вообще хотели добиться этой командой?


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 3 2007, 13:01
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Никогда не видели как взлетает сетевой электролит и разрываются высоковольтные транзисторы при перенапряжении или перегрузках в ИПБ ?
Вам за это сопротивление меньше всего переживать нужно ,пускай кто делал ,тот и переживает.
Для этого есть другое решение вопроса - подается 8-10вольт на сопротивление 10-15Ом на пару ватт,а на выходе стабилитрон на 5.1В.Все это обеспечит более менее нормальное напряжение на девайсе.
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 3 2007, 13:32
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Переживать мне и нужно, иначе всё это будут прелести совместной отладки - один переводит стрелы на другого и т. д. А по поводу взрывов электролитов - там не та ситуация совсем. Каждый лишний вольт/миллиампер/милигенри/микрофарада - это просто криминал, потому недопустимо. Решение про 8-10 вольт, стабилитрон и тем более пару ватт не устаривает, как энергоёмкое и неискробезопасное.

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

По поводу подозрительной строки - в данной строке ожидается готовность устройства, которое выставляет уровень 1. Сейчас оно отключено, потому нога просто через резистор подтянута к питанию. Опять таки, совсем не уверен, что исключение этой строки решит проблему - во первых и что делать, когда эта проверка будет нужна (а он обязательно понадобится) - во вторых.
Go to the top of the page
 
+Quote Post
GDI
сообщение Dec 3 2007, 13:49
Сообщение #12


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
По поводу подозрительной строки - в данной строке ожидается готовность устройства, которое выставляет уровень 1. Сейчас оно отключено, потому нога просто через резистор подтянута к питанию. Опять таки, совсем не уверен, что исключение этой строки решит проблему - во первых и что делать, когда эта проверка будет нужна (а он обязательно понадобится) - во вторых.

Я предлагаю это сделать для проверки, для локализации места зависания, если зависания после этого прекратятся, то вы будете знать, где копать.
Кстати, щуп осциллографа - это емкость, может стоит добавить емкость между Pin3 и землей?
И еще, зачем проверять состояние пина так рано? Я бы сперва провел инициализацию всей перефирии(SPI, TWI, UART), а уж потом стал проверять готовность какого то другого устройства, хотя у вас тут могут быть свои резоны...


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
oran-be
сообщение Dec 3 2007, 13:52
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621



Цитата(forever failure @ Dec 3 2007, 16:06) *
на TWI висит rtc+fram FM3130 может ли она так шину завесть, что её надо сбрасывать отключением питания ? По поводу WDT тоже не совсем понятно, похоже сброс всё таки есть, но он не помогает, так как есть что-то, что не сбрасывается сигналом, генерируемым вочдогом.
Ещё один момент был - когда замерял все напряжения на зависшем устройстве - при касании щупа вольтметра этой ноги PD3 успройство ожило и пошло работать дальше, почему и возникло предположение про порты ввода-вывода.

При условии, что слэйв на шине вследствии некоторых факторов не выставляет АСК, создаются предпосылки для надежного завмсания TWI модуля. Для надежной работы модуля лучше всего использовать асинхронную библиотеку из Атмеловской аппликухи, дополнив ее контролем ошибок. Зависон определяется по 0(наиболее типичная ситуация) в статус регистре. Зависон модуля снимается его полным отключением отключением(запретом) и последующей переинициализации модуля.
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 3 2007, 16:11
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Про емкость между пином и землёй - несколько раз возникала такая идея, попробую.
Но, кстати, в одном из девайсов я соединил напрямую шину питания и пин (ну да, не самая лучшая идея), и всё равно ничего не изменилось.
Версия про зависание шины TWI кажется наиболее правдоподобной и вероятной.
Есть ещё несколько версий, так в частности, этой программе, как можно заметить неиспользуемые выводы контроллера оставлены висящими в воздухе, что, тоже может быть источником проблем.

Но в любом случае, ни одну из версий пока не удаётся проверить по причине непроявления проблемы на рабочем столе.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Dec 3 2007, 16:38
Сообщение #15


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Попробуй перед
reset_tm (); /* r/w twi */
выдать
twi_stop();


--------------------
aka Vit
Go to the top of the page
 
+Quote Post

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

 


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


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