在上層申請主站,完成各種主從站的配置項之後,通過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數據的收發是在系統上同時執行的.