Linux中EtherCAT主站執行過程

在上層申請主站,完成各種主從站的配置項之後,通過ecrt_master_activate函數調用激活整個EtherCAT總線,ecrt_master_activate函數最主要的工作還是完成狀態機的啓動。

ecrt_master_activate通過kthread_run創建和運行一個內核進程,該內核進程一直在後臺運行下面這個進程函數,這就是ecrt_master_activate完成的主要工作。

接下來EtherCAT的運行主要由內核進程函數執行,只要函數kthread_stop沒有被調用,內核線程始終在while (!kthread_should_stop())循環中執行主從站的狀態機

/** Master kernel thread function for OPERATION phase.
 */
static int ec_master_operation_thread(void *priv_data)
{
    ec_master_t *master = (ec_master_t *) priv_data;
    ec_slave_t *slave = NULL;
    int fsm_exec;

    EC_MASTER_DBG(master, 1, "Operation thread running"
            " with fsm interval = %u us, max data size=%zu\n",
            master->send_interval, master->max_queue_size);

    while (!kthread_should_stop()) {/*kthread_stop()調用的時候should_stop被置位,跳出while語句退出內核線程*/ 
    /*內核線程使用while語句不斷檢查主從站的狀態機, 很多數據處理和要發送的數據都在狀態機中進行,狀態機在整個EtherCAT週期不斷運行*/
        ec_datagram_output_stats(&master->fsm_datagram); /*統計傳送失敗數據個數*/

        if (master->injection_seq_rt == master->injection_seq_fsm) {
            // output statistics
            ec_master_output_stats(master); /*統計失敗情況*/

            fsm_exec = 0;
            // execute master & slave state machines
            if (down_interruptible(&master->master_sem))
                break;
   /*開始執行主站狀態機,主站狀態機的master->fsm->state(fsm)是一個地址指針,這個地址可按時序指向多個狀態函數,狀態函數之間順接調用,從而主站進入不同狀態,原理參見手冊第五章State Machines*/

   /*在內核線程中不斷運行相應的狀態機,而不關心狀態機具體指向哪個函數,狀態機之間的轉換由狀態機自己進行,從而由狀態機來控制整個EtherCAT的運行狀態*/

   /*主站狀態機主要是在EtherCAT啓動的時候用廣播尋址獲取總線上的信息,使得我們定義的從站配置和總線上現實存在的從站相匹配,之後總線上各個從站的配置主要還是由從站狀態機完成*/
            fsm_exec += ec_fsm_master_exec(&master->fsm);
            for (slave = master->slaves;
                    slave < master->slaves + master->slave_count;
                    slave++) {
                ec_fsm_slave_exec(&slave->fsm);
    /*剛啓動的時候從站全部處於空閒狀態機,直到主站配置好從站,將從站狀態機改爲START狀態機*/
            }
            up(&master->master_sem);

            // inject datagrams (let the rt thread queue them, see
            // ecrt_master_send)
            if (fsm_exec)
                master->injection_seq_fsm++;
        }

#ifdef EC_USE_HRTIMER
        // the op thread should not work faster than the sending RT thread
        ec_master_nanosleep(master->send_interval * 1000);
#else
        if (ec_fsm_master_idle(&master->fsm)) {
            set_current_state(TASK_INTERRUPTIBLE);
            schedule_timeout(1);
        }
        else {
            schedule();
        }
#endif
    }
    
    EC_MASTER_DBG(master, 1, "Master OP thread exiting...\n");
    return 0;
}

EtherCAT總線的狀態機從內核線程創建開始就不停的執行,檢測總線狀態、初始化各個從站以及進行相關數據處理,但狀態機只能填充它自己需要發送的數據和讀取已經接收到的數據,而不能執行數據的收發,以一定週期在EtherCAT總線上進行數據的收發需要我們自己再應用層完成,所以實際上狀態機和EtherCAT數據的收發是在系統上同時執行的.

發佈了26 篇原創文章 · 獲贊 21 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章