Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Причины зависания и их поиск
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
forever failure
В общем такая проблема: есть устройство, которое периодически отказвает в работе - зависает. Более подробно:
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. Самое трудное - воспроизвести эту проблему не в условиях эксплуатации, а на месте, где её можно решить. Одно из устройств сейчас гоняю всяко - на мороз его выставляю, помехи возле него создаю, влажность повышенную - всё нипочём, - всегда бы так работало. Какие ещё дестабилизирующие средства можно применить ?
defunct
Цитата(forever failure @ Dec 3 2007, 13:39) *
Одно из устройств сейчас гоняю всяко - на мороз его выставляю, помехи возле него создаю, влажность повышенную - всё нипочём, - всегда бы так работало. Какие ещё дестабилизирующие средства можно применить ?

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

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

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

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

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

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

нет.
sensor_ua
На TWI может висеть атмелевская 24-я, требующая 9 клоков до начала работы.
forever failure
на TWI висит rtc+fram FM3130 может ли она так шину завесть, что её надо сбрасывать отключением питания ? По поводу WDT тоже не совсем понятно, похоже сброс всё таки есть, но он не помогает, так как есть что-то, что не сбрасывается сигналом, генерируемым вочдогом.
Ещё один момент был - когда замерял все напряжения на зависшем устройстве - при касании щупа вольтметра этой ноги PD3 успройство ожило и пошло работать дальше, почему и возникло предположение про порты ввода-вывода.
bodja74
Включите BOD + управлять питанием или сбросом остальных устройств через контроллер при инициализации ,так как они могут продолжать работать ниже порога BOD и естественно это вызовет коллизию на шине.
А в общем очень похоже на гульки по питанию ,у меня такие номера выделывала кренка когда перегревалась или сдыхала,сам транс тоже может - если маломощный стоит.
forever failure
BOD включен, уровень = 2.7в. В нормальном режиме напряжение питания примерно 4 в, при работе может изменятся да 4.5 в, в зависимости от тока потребления других устройств. Источник питания - маломощный импульсный стабилизатор плюс ограничивающий резистор 15 Ом по шине питания.

Хуже всего, что не получается эту ситуацию воспроизвести.
bodja74
Начинается ... :D
15 Ом - это много ,при токе в 100мА ,сопротивление даст просадку в полтора вольта.Зажгете пару лишних светодиодов и уйдте в ступор.
Вы осциллом питание меряли ? там наверное не 4 вольта ,а полный абзац smile.gif
forever failure
15 Ом - это требование по искробезопасности цепи, его никак не обойти. А максимальный ток потребления по внутренним цепям с овсеми светодиодами - порядка 60 мА. Конечно, хреновая ситуация, но от неё никак не избавится. Осциллятором смотрел - ступеньку в полвольта видно, когда все потребители отключаются. Больше никаких особенностей, всякой высокочастотной ереси по питанию н наблюдается.
GDI
Цитата
Самое подозрительное в отношение зависания место - ожидание установки единицы на PD3:
while (!(PIND & BIT(PD3))); /* wait pwr signal */.
В реальном устройстве этот пин соединён через резистор 1к с шиной питания и вроде всегда должна там быть единица.

Почему бы не попробовать закомментировать эту строку и не прогнать программу на реальном устройстве если там всегда должна быть единица. И чего вы вообще хотели добиться этой командой?
bodja74
Никогда не видели как взлетает сетевой электролит и разрываются высоковольтные транзисторы при перенапряжении или перегрузках в ИПБ ?
Вам за это сопротивление меньше всего переживать нужно ,пускай кто делал ,тот и переживает.
Для этого есть другое решение вопроса - подается 8-10вольт на сопротивление 10-15Ом на пару ватт,а на выходе стабилитрон на 5.1В.Все это обеспечит более менее нормальное напряжение на девайсе.
forever failure
Переживать мне и нужно, иначе всё это будут прелести совместной отладки - один переводит стрелы на другого и т. д. А по поводу взрывов электролитов - там не та ситуация совсем. Каждый лишний вольт/миллиампер/милигенри/микрофарада - это просто криминал, потому недопустимо. Решение про 8-10 вольт, стабилитрон и тем более пару ватт не устаривает, как энергоёмкое и неискробезопасное.

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

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

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

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

Но в любом случае, ни одну из версий пока не удаётся проверить по причине непроявления проблемы на рабочем столе.
sensor_ua
Попробуй перед
reset_tm (); /* r/w twi */
выдать
twi_stop();
fmdost
Цитата(sensor_ua @ Dec 3 2007, 19:38) *
Попробуй перед
reset_tm (); /* r/w twi */
выдать
twi_stop();


В код не вникал.

Подавать команду стоп нельзя!!! Сбрасывают микросхемы висящие на i2c только многократной подачей команды старт.

ЗЫ. Очень хорошее описание работы с шиной i2c, в пдф.
SasaVitebsk
Цитата(forever failure @ Dec 3 2007, 17:32) *
Вообще хотелось бы увидеть здесь советы по воспроизведению проблемы, потому что причины могут быть разными, и вовсе не такими как предполагаются.


Простите, но Вы не совсем правы. Именно питание вызывает сложные, трудновоспроизводимые и уникальные глюки. И к советам bodja74 надо отнестись со всей ответственностью. Я бы это сделал немедленно, правда предлагаю вам другой подход.

1. Поставить (на время проверки) отличный и мощный блок питания. Это необходимо сделать чтобы однозначно определится в чём проблема. В программной части или аппаратной.

2. По результатам испытаний проводить дальнейшее исследование.


И ещё один момент из моей практики. WDT необходимо использовать тогда, когда к программной части нет претензий. Никаких сбоев и висов. Так как WDT предназначена для выхода из виса по аппаратным проблемам, но не по программным хомутам. По этому, в случае программного виса, вам сначало надо
1. Отключить WDT.
2. Локализовать место или выявить причину виса.
3. Продумать организацию WDT (а не бездумно воткнуть сброс в каждый цикл)
4. Включить WDT.
sensor_ua
Цитата
Подавать команду стоп нельзя!!!

Нельзя сразу после START (в приведенной Вами доке почему-то STOP непосредственно после START позволителен - Fig. 16). Но соглашусь, что в данном случае нельзя, потому как неизвестно что же было перед этим. Сброс логики шины согласно спецификации действительно делается подачей S и/или Sr. Но в спецификации шины примеров как на Fig. 14(a) и Fig. 14(cool.gif что-то не находится. Просветите, плз, а то чего-то не попадалось таких наворотов. Максимум чего приходилось испорльзовать - в описании сброса AT24.
1. Clock up to 9 cycles.
2. Look for SDA high in each cycle while SCL is high.
3. Create a start condition.
fmdost
Цитата(sensor_ua @ Dec 3 2007, 23:58) *
...Просветите, плз, а то чего-то не попадалось таких наворотов. Максимум чего приходилось испорльзовать - в описании сброса AT24...

Не совсем понял вопроса, проясните.
ИМХО. Рис 14а наверное что-бы слейв гарантированно отпустил таки этот SDA, и что-бы не проверять линию SDA в мастере.
Некорректное начало/завершение обмена i2c системах ограничения доступа бывает очень часто. Сделал контроллер ключей с проверкой напряжения питания, оказалось что ВСЕ! кто ставил его на замки защёлки вернули с жалобами на сигнал просадки питания. (Просадка ниже 7 вольт дольше 250 милисекунд!!!!)

forever failure Попробуйте отключать модули по очереди, и смотреть. А ещё лучше, задейтвовать какой нибудь свободный светодиодик или порт. И включать его по очереди после каждого модуля. То-есть:

Включить светодиод
ини модуля 1
ВЫлючить светодиод
....
протестил, переставить на модуль 2 итд.


А ещё красивее WDT переставить на генерацию прерывания, и выводить к какой-нибудь порт, адрес возврата.
Наверняка есть цельный порт только на выход, и с него тестером можно считать.
sensor_ua
Цитата
Не совсем понял вопроса, проясните.

В спецификации на шину (смотрю v2.1) не нашёл способов сброса шины соответствующих указанным на рис 14a и 14b (br24l16.pdf). Кроме того там указано, что нельзя давать "пустое" сообщение - оно illegal format, но не нашёл чего случится страшного при этом. Зато в доке от Rohm есть на рис 16 разрисовка такого случая и описано, мол чего-то таки будет работать. Непонятно это филипс недорасписал (или я криво читал) или у ребят из Rohm фантазия развитая или чего не договаривают. Откуда по 14 проклокиваний перед стартами?
forever failure
Ещё такая деталь: стартап тайм, определённое фьюзами равно 65 мсек. Если WDT включен и работает при каком-то вечном зависоне это можно видеть как периодическое притухание индикаторных светодиодов с периодом таймаута вочдога (65 мс каждые 2 сек). Совершенно точно помню, что в эксплуатации при зависании этого не было, т. е. выглядело так, как будто WDT не срабатывал.
vesago
А индуктивной нагрузочкой случаем не управляет ваш аппарат?
forever failure
нет, ничем он не управляет, но электромагнитная обстановка вокруг него может быть тяжёлой (всякие пускатели, выключатели ампер так на 200, силовае кабели и т. д.)
vesago
Ну тогда, когда отделите мух от котлет - убедитесь в безгрешности софта, внешний вачдог. Зря не поставили вроде fm3104. Еще - понизить подтяжку по и2ц и частоту.
D H
IMHO зависон в twi. Отключите twi устройство и получите бесконечный цикл и, следовательно, зависон. Проверяйте подключение, подтягивающие резисторы и т.д. Короче, подтяжка SCL SDA и проводники идущие к ним.
oran-be
Цитата(forever failure @ Dec 4 2007, 10:43) *
Ещё такая деталь: стартап тайм, определённое фьюзами равно 65 мсек. Если WDT включен и работает при каком-то вечном зависоне это можно видеть как периодическое притухание индикаторных светодиодов с периодом таймаута вочдога (65 мс каждые 2 сек). Совершенно точно помню, что в эксплуатации при зависании этого не было, т. е. выглядело так, как будто WDT не срабатывал.

Все вроде честно. Прога на цикле ожидания флага от ТВАЯ, как и положено виснет, собака сбрасывает проц, после чего прога опять, как и положено виснет. Отлаживать софт с собакой - плохая практика. Отключите собаку и вычисляйте места зависонов конкретно. Хотя они ясны и так.
forever failure
Что бы что-то попробовать, нужно, чтоб ситуация хотябы иногда повторялась.
Рекомендаций уже было дано достаточно много, но чтоб их проверить, нужно как-то вызвать зависающую ситуацию. Сейчас, у меня никак не получается вызвать такое.

Это на текущий момент проблема более основная, чем исправление причины зависания.

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

Поэтому заменив что-то в коде или исправив в источнике питания или ещё что-то сделав, я сейчас так и не узнаю - устранена причина или нет - на рабочем столе оно и так работает во всех позах без каких либо исправлений.
sensor_ua
Нужно аж симитировать сброс проца во время работы по TWI
forever failure
Цитата(sensor_ua @ Dec 4 2007, 17:42) *
Нужно аж симитировать сброс проца во время работы по TWI

Было и такое. зависает до первого срабатывания WDT, то есть на две сек, а дальше норамльно работает.
D H
Не подсоединияй устройство по TWI, вот и получишь свой искомый зависон.
После этого сиди, правь исходники.
fmdost
Цитата(sensor_ua @ Dec 4 2007, 07:23) *
Непонятно это филипс недорасписал (или я криво читал) или у ребят из Rohm фантазия развитая или чего не договаривают. Откуда по 14 проклокиваний перед стартами?

Как-то смутно i2c у Филипса описано.

forever failure В некоторых мануалах на микросхемы 24c01 пишут, что микросхема начинает гарантированно работать через 0.15 (!!!) секунды.
Пороверка наличия/работоспособности устройства, должна иметь выход по таймауту. Иначе как индицировать поломку?
zltigo
Цитата(Т.Достоевский @ Dec 4 2007, 22:13) *
Как-то смутно i2c у Филипса описано.

smile.gif У Филипс - отцов основателей I2C расписано все очень четко и ясно. Просьба с реализацией и описаеием I2C ака TWI от Atmel в одну кучу не кидать.
fmdost
Цитата(zltigo @ Dec 5 2007, 02:04) *
smile.gif У Филипс - отцов основателей I2C расписано все очень четко и ясно. Просьба с реализацией и описаеием I2C ака TWI от Atmel в одну кучу не кидать.

Ясно дело разные вещи. Дело было давно, интернет был медленный, потом стало как-то неинтересно. В пдф ИМХО лучшее что нашёл laughing.gif .
forever failure
Тов. Достоевский, у меня там FM3130 прицеплено, а не 24c01.

Пока что опыты и надругательства над шиной TWI положительного результата не дали. При возникновения какой-либо проблемы, вызывающей зависание, после первого рестарта работоспособность восстанавливается полностью.
forever failure
Чисто случайно нашёл сейчас свою тему, на какую следовало бы,в общем-то, отрапортовать : "Хэппи энд".
Косяк нашёлся, дело было не в шине I2C, не в питании, и не в разводке платы.
Проблема крылась в небольшом куске ассемблерного программного кода :
CODE
SIG_UART0_RECV:
push r16 ; 2
in r16, IO_PORT(SREG) ; 1
push r17 ; 2

lds r17, LED_PORT ; 2 /* atmega128 */
ori r17, RECV_LED ; 1
sts LED_PORT, r17 ; 2 /* atmega128 */

push r30 ; 2
push r31 ; 2

in r31, IO_PORT(UDR0) ; 1 /* atmega128 */

in r17, IO_PORT(UCSR0A) ; 1 /* atmega128 */
andi r17, parity_error ; 1
lds r30, modbus_line_state ; 2
or r30, r17 ; 1
sts modbus_line_state, r30 ; 2

lds r16, modbus_line_timeout; 2
out IO_PORT(TCNT0), r16 ; 1 /* atmega128 */

in r17, IO_PORT(TIMSK) ; 1 /* atmega128 */
ori r17, BIT(TOIE0) ; 1
out IO_PORT(TIMSK), r17 ; 1 /* atmega128 */

in r17, IO_PORT(TIFR) ; 1
ori r17, BIT(TOV0) ; 1
out IO_PORT(TIFR), r17 ; 1

mov r17, r31 ; 1

lds r30, rxtx_buffer_ptr ; 2
lds r31, rxtx_buffer_ptr + 1; 2

st Z+, r17 ; 2
cpi r30, lo8(rxtx_buffer + RECV_MODBUS_BUFFER_SIZE) /* buffer size <= 256 bytes */
breq HERE + 8 ; 1 / 2

sts rxtx_buffer_ptr, r30 ; 2
sts rxtx_buffer_ptr + 1, r31; 2

pop r31 ; 2
pop r30 ; 2
pop r17 ; 2
out IO_PORT(SREG), r16 ; 1
pop r16 ; 2
reti

Даже не очень опытный глаз тут сможет найти ошибку, которая в сочетании с другими дефектами программного кода (в частности сбросом собаки более, чем в одном месте приложения) с единичной вероятностью приводит к отказу устройства.
Отсюда вывод (особенно всем тем, кто иногда заявляет "ИАР/ГЦЦ - глючит, атмел гонит брак"): мойте руки перед едой и не экономьте заварку. То есть, просто надо соблюдать простые элементарные правила - в частности чаще тестировать код, проверять в коде возвращаемые функциями значения.
Но, хотя ни один из ответов по теме не мог бы решить проблему непосредственно, некоторые неспецифические рекомендации данные здесь, помогли в конечном итоге отловить этого жука. В частности, полезной оказалась рекомендация оставить сброс WDT только в одной точке приложения (и то, только после проверки некоторых условий),
и помогла запись в EEPROM запись состояний регистра SREG при возникновении ошибки шины I2C и при возникновении других критических ошибок.
Спасибо всем, кто ответил по этой теме.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.