【问题标题】:Dependency reset design pattern (embedded C)依赖重置设计模式(嵌入式 C)
【发布时间】:2014-06-15 06:35:06
【问题描述】:

伙计们,我正在开发一个使用 I2C 模块的 C 嵌入式系统。使用 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.
}

谢谢!

【问题讨论】:

  • 很多时候,您无法高效地实现 I2C(或其他外围总线)来满足所有目的。编写适合您的情况的内容并不难,因此您无需为“设计模式”操心,这是一个在高级语言中很常见的术语。

标签: c design-patterns i2c


【解决方案1】:

如何将所有设备初始化到“聚合”函数并在需要时调用它?

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
}

【讨论】:

    【解决方案2】:

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

    尤其是watchdog timer 适合您的情况。

    我认为不是 I2C 模块应该重置硬件。

    【讨论】:

    • 我要重置的只是外部硬件,即 I2C 总线上的从设备,我所在的平台允许我将 I2C 外围硬件分别重置到 uC 的其余部分,所以我会喜欢这样做并保留正确的状态,而不是用 WD 重置整个事情
    猜你喜欢
    • 2011-05-08
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多