Linux中EtherCAT主站执行过程

2019-07-13 05:53发布

在上层申请主站,完成各种主从站的配置项之后,通过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 ", 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... "); return 0; } EtherCAT总线的状态机从内核线程创建开始就不停的执行,检测总线状态、初始化各个从站以及进行相关数据处理,但状态机只能填充它自己需要发送的数据和读取已经接收到的数据,而不能执行数据的收发,以一定周期在EtherCAT总线上进行数据的收发需要我们自己再应用层完成,所以实际上状态机和EtherCAT数据的收发是在系统上同时执行的.