Схема проектирования сброса зависимостей (встроенный C)

45
4

Люди, я работаю над встроенной системой в C, которая использует модуль I2C. Другие модули, которые используют I2C, имеют модуль I2C как зависимость, или "дочерняя система". Они передают ему структуры контекста сообщения и когда модуль I2C готов, он асинхронно отправляет или читает сообщения по указанию контекста, выполняя обратный вызов из контекста, чтобы позволить вышележащему модулю знать, что работа завершена, успешно или с ошибкой.

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

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

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

Чтобы проиллюстрировать это иначе:

Нормальная инициализация I2C и внешней аппаратной последовательности:

initExtIOExpander() {
context_t initialisationMsg = {/*...*/};
i2cSend(&initialisationMsg )
}

initExtADC() {
context_t initialisationMsg = {/*...*/};
i2cSend(&initialisationMsg )
}

i2cSend() {
// Start sending data using passed context,
}

interrupt i2c_isr() {
//If the message completed run the callback handle in the current context
// else do the next part of the message, etc.
}

main () {
//...
initI2c();
initExtIOExpander();
initExtADC();
//...
// Use external devices here.
//
}

Сброс и повторная инициализация: если нормальная последовательность сверху уже произошла, но теперь IS2 I2C изменяется для обнаружения ошибок:

interrupt i2c_isr () {
//If there was an error reset external H/W, and own H/W
// but how to know to call initExtIOExpander() and initExtADC()??
// this module might know about the ADC if it is processing and ADC
// message but it has "forgotten" about the IO expander or any other
// device
// else if the message completed run the callback handle in the current
// context
// else do the next part of the message, etc.
}

Благодарю!

спросил(а) 2014-04-29T13:56:00+04:00 5 лет, 7 месяцев назад
2
Решение
46

Как насчет того, чтобы вся инициализация ваших devies была "агрегирована" и вызывала ее при необходимости?

void init_all_i2c_devices(void) {
initExtIOExpander();
initExtADC();
...
}

interrupt i2c() {
....
init_all_i2c_devices();// or i2c_init_callback()
}

main() {
init_i2c();
init_all_i2c_devices();
// set_i2c_init_callback(init_all_i2c_devices) if need
}

ответил(а) 2014-04-29T16:07:00+04:00 5 лет, 7 месяцев назад
Еще 1 ответ
33

Для шаблонов проектирования во встроенном контексте смотрите здесь и здесь.

Особенно сторожевой таймер подходит вашему делу.

Я думаю, что это не модуль I2C, который должен сбросить HW.

ответил(а) 2014-04-29T15:03:00+04:00 5 лет, 7 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема