Обсуждаем контроллеры компании Atmel.
Ответить

Обработка исключений

Чт апр 07, 2022 06:33:48

Доброго дня и весеннего всем настроения.
Давным давно делал большой, для себя, проект на ATmege32. Несколько тысяч строк кода и проект готов. Все бы ничего, но в этом изделии использовался датчик температуры/влажности HTU21. Датчик подключается по I2C. И иногда, датчик не отвечал в отведенный тайминг и девайс зависал. Тогда, не долго думая, просто использовал WatcDog и так и использовал эту поделку. При сбоях поделка просто перезагружалась и продолжала работу. Спустя несколько лет, решил вернуться к этой проблеме. первое что пришло в голову, это обработка исключений. ПРошивку писал на С++ в Атмел Студио 7. Вставил конструкцию Try...Catch, атмел студио, даже опознал синтаксис. попробовал собрать и получаю ошибку "exception handling disabled use '-fexceptions' to enable". Хм, вроде бы все понятно, нужно просто включить исключения. Но я как то даже растерялся, где это сделать? :dont_know:

Начал гуглить. И информации практически нет. Где то на форумах даже встречал что эта конструкция не будет работать на AVR, мол камушек не поддерживает.

ну и собственно вопрос, можно ли использовать исключения, если можно то как?
А если нельзя, то может как то по другому решить эту проблему а не перезагружать все устройство.

Re: Обработка исключений

Чт апр 07, 2022 08:49:39

...по другому решить...

Вводится тайм-аут, в течение которого бяка должна ответить. Например, на Т/С0.

Re: Обработка исключений

Чт апр 07, 2022 14:39:30

Ну раз более изящных решений нет, буду делать так. спасибо.

Re: Обработка исключений

Пт апр 22, 2022 23:51:57

Обработка исключений - дорогое удовольствие. Тут и раскрутка стека и создание объекта, не просто так по умолчанию это выключено. Если брать конкретно IIC, то я делал драйвер с ограничением таймаута.

Код:
/*
 * Выставляет на шину байт данных.
 */
void iic_ll_write(uint8_t d)
{
        if (error != IIC_NO_ERROR) {
                return;
        }

        TWDR = d;
        TWCR = (1 << TWINT) | (1 << TWEN);
        twi_wait(1 << TWINT);
        if (_twsr_not(TWI_MT_DATA_ACK)) {
                error |= IIC_ERROR_WRITE;
        }
        return;
}

/*
 * \brief Ожидание завершения операции.
 * \details
 */
void twi_wait(const uint8_t mask)
{
        uint8_t c;
        for (c = 0; (TWCR & mask) == 0; c++) {
                if (c > IIC_TIMEOUT) {
                        error |= IIC_ERROR_WAIT;
                        break;
                }
                _delay_us(950);
        }
}


По нормальному функция twi_wait завершается, если за отведенное время в регистре TWCR сбросится бит, совпадающий с битом в параметре mask. Иначе устанавливается глобальная переменная error, которую может проверить вызывающий код.
Ответить