ethercat idle_thread流程图

在这里插入图片描述
有上图可以看到 ec_master_idle_thread 线程是由igb模块加载后系统自动进入idle thread 线程

2 状态机

以IDLE为例,状态机周期调用关系如下图所示:
在这里插入图片描述
其中ec_master_idle_thread()的调用周期与系统滴答时间有关:

//send interval in IDLE phase
ec_master_set_send_interval(master, 1000000/HZ);

ec_fsm_master 状态机的种类(查看结构体ec_fsm_master):

	/* 各个不同的状态机,每个状态机都有对应的不同的源码文件,如fsm_coe对应源码实现为/master/fsm_coe.h和/master/fsm_coe.c文件中 */
    ec_fsm_coe_t fsm_coe; /**< CoE state machine */
    ec_fsm_soe_t fsm_soe; /**< SoE state machine */
    ec_fsm_pdo_t fsm_pdo; /**< PDO configuration state machine. */
    ec_fsm_change_t fsm_change; /**< State change state machine */
    ec_fsm_slave_config_t fsm_slave_config; /**< slave state machine */
 
	/* 从站扫描状态机,主站状态机中的子状态机 */
    ec_fsm_slave_scan_t fsm_slave_scan; /**< slave state machine */

查看完毕该结构体可以看到主站状态机中还存在一些子状态机,如fsm_coe,fsm_soe,fsm_pdo,fsm_change,fsm_slave_config,基本的模式就是主站状态机在需要执行子状态机的时候,会一直等待子状态机完成相应工作,然后再执行之后的程序转入下一状态
在这里插入图片描述
从上图可以看到ec_master.ko加载后初始化状态机为ec_fsm_master_state_start。

那么继续看主站状态机,主站状态机的状态函数会在初始化的时候初始化到./master/fsm_master.c/ec_fsm_master_state_start()函数,该函数中会对状态机子报文进行填充,进行本周期的子报文数据发送,在此使用了BRD类型子报文(关于BRD子报文的作用可以查看这部分内容https://welsey.blog.csdn.net/article/details/105288222)进行数据发送,通过BRD类型子报文获取从站个数,然后进入下一个状态函数,也就是./master/fsm_master.c/ec_fsm_master_state_broadcast()中进行解析。由于使用的是BRD,对应的返回的子报文的WKC(WKC计算公式参考https://welsey.blog.csdn.net/article/details/105289253)也就是主站连接的从站的个数,这样通过判断与之前存储的从站个数时候一致就可以判断主站连接的从站有无变化,如果判断发生变化,那么就需要进行主站对从站的重新扫描过程

1.首先调用ec_master_clear_slaves()函数清除主站连接的从站链表,而后以刚扫描完毕得到的从站个数进行从站空间申请,并将主站的从站链表指向该位置。之后做的工作就是为新申请的从站链表空间进行内容初始化,以及对从站寄存器的一些初始化。
2.从站的配置地址存储在0x0010~0x0011,先进行对从站配置地址的清除(就是直接使用BWR报文直接写入0x0000到该寄存器);之后的配置地址写入在之后的从站扫描子状态机中进行。然后就是写入0x0900寄存器,写入该寄存器会锁存写入时候的本地时间,该时间用来使用在DC过程。
3.执行从站扫描状态机,该状态机是主站状态机中的子状态机,主站会在ec_fsm_master_state_scan_slave()函数中等待该子状态机执行完毕,至于执行是否完毕的标准就是子状态机有无正常结束或者异常结束(通过两个无内容的状态函数实现)。
4.从站扫描子状态机:该状态机的类为./master/fsm_slave_scan.h/ec_fsm_slave_scan,具体内容如下:

struct ec_fsm_slave_scan
{
    ec_slave_t *slave; /**< Slave the FSM runs on. */
 
    ec_datagram_t *datagram; /**< Datagram used in the state machine. */
    ec_fsm_slave_config_t *fsm_slave_config; /**< Slave configuration state machine to use. */
    ec_fsm_pdo_t *fsm_pdo; /**< PDO configuration state machine to use. */
    unsigned int retries; /**< Retries on datagram timeout. */
 
    void (*state)(ec_fsm_slave_scan_t *); /**< State function. */
 
    uint16_t sii_offset; /**< SII offset in words. */
    ec_fsm_sii_t fsm_sii; /**< SII state machine. */
};

执行到该子状态机首先就是对从站的配置地址(0x0010~0x0011)的设置,由于最开始是从站变化导致的主站重新扫描,因此从站的配置地址是需要重新设置的,该设置地址是使用EC_DATAGRAM_APWR子报文进行设置的,自增式物理写入的方式,每个从站都会参与转发他,且每个从站对该子报文处理完毕后都会在APD位置+1,当那个从站检测到APD为0的时候,就会正式处理该子报文。因此该子报文类型适合于从站配置地址无效的情况下进行。

5.写入从站的配置地址后就可以使用配置寻址方式进行指定从站的寻址了。也就是EC_DATAGRAM_FPRD类型子报文。首先获取以下当前的从站状态(0x0130~0x0131)检测从站有无已知异常。如果没有就可以继续之后的获取从站基础信息。

6.ec_fsm_slave_scan_state_base()函数用于获取从站基础信息,主要包括FMMU个数、sync个数,FMMU是否支持位操作,从在哪是否支持DC,从站DC时间范围等信息。如果从站支持DC系统,那么就先进行DC的一些设置

7.获取DL状态:DL也就Data link,表示数据链路状态。他在0x0110~0x0111寄存器中存放。分别针对从站4个端口有无连接,有无回路闭合和信号是否有检测到进行信息获取。

8.获取SII信息,SII信息存放在EEPROM中,且第一个SII信息存放在EEPROM的0x40位置,然后利用SII信息获取子状态机对SII信息进行获取,大体来说就是根据SII每个项的存储格式可以获取到最终存储SII信息占据的空间大小,而后根据该空间大小将所有的SII信息获取复制到内存中,之后再进行SII信息的提取解析(./master/fsm_slave_scan.c/ec_fsm_slave_scan_state_sii_data())。

9.提取完毕SII信息后,如果支持从站COE协议,那么就继续执行./master/fsm_slave_scan.c/ec_fsm_slave_scan_enter_preop()状态函数,该状态函数中启用了从站配置子状态机,该状态机器会进行从站状态转换过程中一系列配置设置以及设置从站状态向目标设置状态变更。

10.大体上一个从站的由init状态转变向preop状态的流程如上,之后就是依次将主站连接的每个从站都执行一次上述流程。之后不断做从站的重新扫描。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值