依赖重置设计模式(嵌入式C)

时间:2014-04-29 10:56:38

标签: c design-patterns i2c

伙计们,我正在使用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.
    //
}

重置和重新初始化序列: 如果已经发生了上面的正常序列,但现在改变了I2C ISR以检测错误:

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.
}

谢谢!

2 个答案:

答案 0 :(得分:1)

如何将所有设备初始化设置为#39;聚合#39;功能并在需要时调用它?

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
}

答案 1 :(得分:0)

对于嵌入式上下文中的设计模式,请查看herehere

特别是watchdog timer适合你的情况。

我认为不应该重置HW的I2C模块。