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数据的收发是在系统上同时执行的.

你可能感兴趣的:(linux,EtherCAT主站)