大家好,欢迎来到IT知识分享网。
本文介绍CANopen中的NMT状态机,及在CanFestival中的实现过程。
一、NMT状态机
CANopen中状态机包含4个状态:Initialisation、Pre-operational、Operational和Stopped。
相互之间的关系和跳转条件如下:
其中,从Initialisation到Pre-operational的跳转一般是从节点自动完成的,其它跳转一般由主节点发送NMT帧触发。
二、NMT帧格式
NMT帧的ID为0,NodeID为需要控制的节点号,若要控制所有节点则NodeID为0。
其中cs(Command Specifier)在def.h中定义:
/* NMT Command Specifier, sent by master to change a slave state */
/* ------------------------------------------------------------- */
/* Should not be modified */
#define NMT_Start_Node 0x01
#define NMT_Stop_Node 0x02
#define NMT_Enter_PreOperational 0x80
#define NMT_Reset_Node 0x81
#define NMT_Reset_Comunication 0x82
三、CanFestival中的实现
CanFestival关于NMT的代码主要在nmtMaster.c、nmtSlave.c和States.c中,以从节点为例,当收到NMT帧时的处理流程为:
canDispatch() -> proceedNMTstateChange() :
void proceedNMTstateChange(CO_Data* d, Message *m)
{
......
if( ( (*m).data[1] == 0 ) || ( (*m).data[1] == *d->bDeviceNodeId ) ){ switch( (*m).data[0]){ /* command specifier (cs) */ case NMT_Start_Node: if ( (d->nodeState == Pre_operational) || (d->nodeState == Stopped) ) setState(d,Operational); break; case NMT_Stop_Node: if ( d->nodeState == Pre_operational || d->nodeState == Operational ) setState(d,Stopped); case NMT_Enter_PreOperational: if ( d->nodeState == Operational || d->nodeState == Stopped ) setState(d,Pre_operational); break; case NMT_Reset_Node: setState(d,Initialisation); case NMT_Reset_Comunication: setState(d,Initialisation); break; }/* end switch */
}/* end if( ( (*m).data[1] == 0 ) || ( (*m).data[1] == bDeviceNodeId ) ) */
}
}
在setState()中将d->nodeState设为相应的状态,并执行相应状态下的动作。
四、实例
帧0:停止节点1。
帧1:停止所有节点。
帧2:复位所有节点通信。
帧3::启动节点1。
帧4:启动所有节点。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/11072.html