用于处理中断数据的设计模式

时间:2015-06-09 01:08:24

标签: c design-patterns

我正在开发一个用C实现的固件应用程序,我想知道这种问题的优秀设计模式是什么:

  1. 在主循环中,当我从使用UART通信的设备接收数据时,我将收到中断
  2. 我会发送一个AT命令并等待来自设备的回复,如果设备回复OK,我将发送下一个AT命令直到所有命令完成
  3. 如果设备回复NOK(不正常),我将再次重新发送命令
  4. 我已经考虑了STATE机器,但我仍然认为实现不优雅,因为我在等待主循环中的响应,转移到另一个状态。

    我应该实施哪种设计模式?

2 个答案:

答案 0 :(得分:2)

这听起来像是一个简单的客户端 - 服务器(消费者 - 生产者)模型问题。

简答:监控设计模式。

答案很长......

当您说“我将获得中断”时,您是说会触发硬件中断,还是会发生执行更改?在硬件中断的情况下,这将是特定于平台的。 Even something as simple as a keyboard hardware interrupt routine takes a bit of effort to implement

如果是另一种情况,你可以拥有一个主/经理线程,一个工作线程,以及:

  1. 让主循环只使用互斥锁和spin-lock,等待工作线程报告数据准备就绪,而工作线程阻止等待I / O存储在互斥锁保护的缓冲区中。
  2. 不是旋转锁定,而是使用condvarcondition variable),这样就不会烧掉CPU并且不必要地浪费周期。

    /*
     *  Solution to Producer Consumer Problem
     *  Using Ptheads, a mutex and condition variables
     *  From Tanenbaum, Modern Operating Systems, 3rd Ed.
     */
    
    /*
        In this version the buffer is a single number.
        The producer is putting numbers into the shared buffer
        (in this case sequentially)
        And the consumer is taking them out.
        If the buffer contains zero, that indicates that the buffer is empty.
        Any other value is valid.
    */
    
    #include <stdio.h>
    #include <pthread.h>
    
    #define MAX 10000000000         /* Numbers to produce */
    pthread_mutex_t the_mutex;
    pthread_cond_t condc, condp;
    int buffer = 0;
    
    void* producer(void *ptr) {
      int i;
    
      for (i = 1; i <= MAX; i++) {
        pthread_mutex_lock(&the_mutex); /* protect buffer */
        while (buffer != 0)            /* If there is something 
                          in the buffer then wait */
          pthread_cond_wait(&condp, &the_mutex);
        buffer = i;
        pthread_cond_signal(&condc);    /* wake up consumer */
        pthread_mutex_unlock(&the_mutex);   /* release the buffer */
      }
      pthread_exit(0);
    }
    
    void* consumer(void *ptr) {
      int i;
    
      for (i = 1; i <= MAX; i++) {
        pthread_mutex_lock(&the_mutex); /* protect buffer */
        while (buffer == 0)         /* If there is nothing in 
                           the buffer then wait */
          pthread_cond_wait(&condc, &the_mutex);
        buffer = 0;
        pthread_cond_signal(&condp);    /* wake up consumer */
        pthread_mutex_unlock(&the_mutex);   /* release the buffer */
      }
      pthread_exit(0);
    }
    
    int main(int argc, char **argv) {
      pthread_t pro, con;
    
      // Initialize the mutex and condition variables
      /* What's the NULL for ??? */
      pthread_mutex_init(&the_mutex, NULL); 
      pthread_cond_init(&condc, NULL);      /* Initialize consumer condition variable */
      pthread_cond_init(&condp, NULL);      /* Initialize producer condition variable */
    
      // Create the threads
      pthread_create(&con, NULL, consumer, NULL);
      pthread_create(&pro, NULL, producer, NULL);
    
      // Wait for the threads to finish
      // Otherwise main might run to the end
      // and kill the entire process when it exits.
      pthread_join(&con, NULL);
      pthread_join(&pro, NULL);
    
      // Cleanup -- would happen automatically at end of program
      pthread_mutex_destroy(&the_mutex);    /* Free up the_mutex */
      pthread_cond_destroy(&condc);     /* Free up consumer condition variable */
      pthread_cond_destroy(&condp);     /* Free up producer condition variable */
    
    }
    

答案 1 :(得分:0)

我会使用&#34; divide&amp;征服&#34;将您的问题分解为可管理的子问题的原则。您可以在不同的抽象级别中使用以下模式:

  • 你可以使用像&#34; Layer Pattern&#34;使用以下结果上下文构造源代码:
    • 提高可维护性(大优势)
    • 性能下降(可忽略,假设&#34;足够的硬件性能&#34;)
  • 您可以使用设计模式来解决调度问题 线程管理一般。我会推荐一个导致a的模式 对传入异步事件的良好响应(&#34;传入的UART数据&#34;)。 如果您使用实时操作系统(RTOS),您可以检查是否不同 调度机制是可配置的。一个线程可能是&#34;接收数据&#34; (执行&#34后输入;发送数据&#34;,在所有数据完成后退出 收到的),第二个线程&#34;命令处理程序&#34; (后进入 退出&#34;接收数据&#34;线程,退出后将发送的命令 已被确定)和第三个线程&#34;发送数据&#34; (退出&#34; comand后输入 处理程序&#34;,在所有数据发送后退出)。优先事项(最高,.., 最低)可以按如下方式分配:&#34;接收数据&#34;,&#34;命令处理程序&#34;, &#34;发送数据&#34;。使用&#34;静态优先级模式&#34;导致以下内容 结果背景:
    • 稳定性(可预测哪个线程在过载情况下失败。 想一想在发送过程中收到一些东西......)
    • 对传入事件的良好反应
    • &#34;无限优先级倒置&#34;可能由于阻止资源共享而发生 - &GT;需要实施资源共享模式
  • 您可以使用&#34;关键区域模式&#34; (禁用任务切换)或 &#34;守卫呼叫模式&#34; (〜互斥信号量)保护资源 &#34; UART外设&#34;。
  • &#34; Observer Pattern&#34; (等于&#34;监控模式&#34;)可用于管理 当活动线程根据输入的UART数据变化而变化时 是否被发现。
  • 检测传入的UART数据和/或检测所有数据 传输了&#34;中断模式&#34;可用于。 (假设UART支持相关的中断功能)
  • 在最低级别的抽象中,您可以使用其中一种可能的状态 机&#34;用于发送数据和接收数据的模式实现 UART驱动程序(UART外设状态:发送/接收字节,错误等)。

您可以找到许多摘要和对上述示例的参考 和eswp3.org上的C中的其他设计模式。 (对不起,我无法做到 目前超过2个网站的超链接。我会在赚钱后这样做 足够的声誉...)