2015-06-09 32 views
2

我開發的C++實現的固件應用程序,我想知道究竟是什麼樣的問題,一個好的設計模式:設計模式來處理中斷數據

  1. 在主循環中,我會打斷當我使用UART通信從設備收到數據時
  2. 我會發送一個AT命令並等待來自設備的回覆,如果設備回覆OK,我將發送下一個AT命令,直到所有命令完成
  3. 如果設備回覆NOK(不行),我會重新發送命令

我已經考慮過STATE機器了,但我仍然認爲這個實現並不優雅,因爲我正在等待主循環中的響應,轉換到另一個狀態。

應該實現哪種設計模式?

+0

在主循環中是否還有其他時間敏感操作正在進行?或者是上面所要做的一切? – harmic

+0

@harmic yup,上面是它所要做的所有事情 – Tim

+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 */ 
    
    } 
    
0

我會使用「分治&」的原則,以您的問題分成管理,能夠子問題。你可以使用在不同的抽象級別以下模式:

  • 你可以使用一個結構,建築設計模式,如「圖層模式」和以下出現的上下文來構建你的源代碼:
    • 增加可維護性(大優勢)
    • 性能(可忽略的,假設「足夠的硬件性能」)
  • 你可以使用一個設計模式解決調度管理浩下降一般管理 線程。我會推薦一種模式,這會導致對輸入異步事件(「傳入UART數據」)的良好響應。 如果您使用實時操作系統(RTOS),您可以檢查是否可以配置不同的調度機制。一個線程可以是「接收數據」 (在執行「發送數據」之後輸入,在所有數據已被接收後退出 ),第二個線程「命令處理程序」(在「接收數據」線程的 退出之後輸入,退出後應該發送的命令具有 )和第三個線程「發送數據」(在所有數據發送完畢後退出「命令 處理程序」後退出)。可以將優先級(最高,..., 最低)分配如下:「接收數據」,「命令處理程序」, 「發送數據」。使用「靜態優先級模式」導致以下 產生的背景:
    • 穩定性(這是可以預見的線程在過載情況下失敗 想想接受的東西,而發送的進行中......)
    • 傳入事件的反應良好
    • 「無界優先級反轉」可能是由於阻塞資源共享 - >將需要執行的ressource共享模式的
  • 您可以使用「關鍵註冊離子模式「(禁用任務切換)或 」防護呼叫模式「(〜互斥信號)來保護資源 」UART外設「。
  • 當活動線程根據其他輸入UART數據而變化時,可以使用「觀察者模式」(等同於「監視模式」)來管理 已檢測到 。
  • 爲了檢測傳入的UART數據和/或檢測傳輸的所有數據,可以使用「中斷模式」。 (假設UART支持相關的中斷功能)
  • 在最低級別的抽象級別上,可以使用可能的「狀態 機器」模式實現發送數據和接收 中的數據UART驅動程序(UART外設狀態:發送/接收的字節,錯誤等)。

你可以找到很多摘要和參考文獻所提到的 等設計在C對eswp3.org模式的例子。 (對不起,我目前無法連接超過2個網站的 ,我會在贏得 足夠的聲望後這樣做)