本文描述了如何通过Anybus CompactCom 40 驱动程序设置模块PROFINET设备名称,首先介绍了与PROFINET名称设置相关的对象、实例、属性,随后构建设置PROFINET名称的命令序列。
适用产品
AB6605、AB6675、AB6610(烧写PROFINET协议固件)、AB6680(烧写PROFINET协议固件)
注意事项
本文简要的介绍了如何通过Anybus CompactCom 40驱动程序设置模块PROFINET设备名称,更多详细信息请参考官网手册:
《Anybus CompactCom 40 - Software Design Guide》
《Anybus CompactCom 40 - Host Application Implementation Guide》
《Anybus CompactCom 40 - PROFINET IRT Network Guide》
设置模块PROFINET设备名称分为两种情况
- 在模块初始化完成之前设置模块PROFINET设备名称,设置立即生效。
- 在模块初始化完成之后设置模块PROFINET设备名称,设置后需将模块重置后才可生效。
目录
- 在模块初始化完成之前设置模块PROFINET设备名称
- 在模块初始化完成之后设置模块PROFINET设备名称
在模块初始化完成之前设置模块PROFINET设备名称
- 在用户手册中查询PROFINET设备名称的对象/实例/属性 具体信息请参考《Anybus CompactCom 40 - PROFINET IRT Network Guide》的13.5.7小节。 通过驱动程序设置PROFINET设备名称,需要驱动发送Set_Attribute 命令到模块,该属性在Anybus CompactCom40 Network Configuration Object(0x04)的实例20实现,实例属性列表如下。
-
在驱动程序中设置PROFINET设备名称的方法
- 在用户初始化命令序列中添加设置模块PROFINET名称的命令(命令序列(Command sequencer)说明请参考《Anybus Compact 40 Host application implementation guide》第40页)
- 与之相关的函数:在驱动源码example_app文件下的appl_abcc_handler.c文件中有 void ABCC_CbfUserInitReq(void)函数,负责将用户命令序列添加至驱动消息发送队列,用户需要在appl_asUserInitcmdSeq[]中通过ABCC_CMD_SEQ( CmdBuilder1, RespHandler1 )方法添加设置PROFINET设备名称的命令。CmdBuilder1为命令构建函数的指针,RespHandler1为模块回复消息处理函数指针,无需处理命令的消息回复时可设置为NULL。
-
代码示例:
-
首先参考ABCC_CmdSeqCmdStatusType UpdateIpAddress( ABP_MsgType* psMsg ),实现ABCC_CmdSeqCmdStatusType UpdatePIRDevicename(ABP_MsgType* psMsg )函数:为提高命令执行的可靠性,可在函数中设置命令执行的判定条件,并通过函数返回值告知驱动该命令是否需要执行。命令构建函数返回值类型必须为ABCC_CmdSeqCmdStatusType,为一个枚举类型,其定义如下:
-
typedef enum ABCC_CmdSeqCmdStatus
{
ABCC_SEND_COMMAND,
ABCC_SKIP_COMMAND,
ABCC_CMD_ABORT_SEQ
}
ABCC_CmdSeqCmdStatusType; -
代码示例如下。
ABCC_CmdSeqCmdStatusType UpdatePIRDevicename( ABP_MsgType* psMsg )
{
UINT16 iNetworkType;
iNetworkType = ABCC_NetworkType(); //Get Network Type
if(iNetworkType==ABP_NW_TYPE_PIR||
iNetworkType==ABP_NW_TYPE_PRT)
{
appl_fNwSupportsPIRstationname=TRUE; //Network Type is PROFINET
}
if ((appl_fNwSupportsPIRstationname) && //The condition of command sent
(appl_fPIRstationname)) //Opened in application layer
{
ABCC_SetMsgHeader( psMsg,
4, //Network Configuration Object Code
20, //PROFINET station name instance Code
5,//Attribute Code
ABP_CMD_SET_ATTR,//Set_Attribute command code
strlen(pir_devciename),//the length of station name String
ABCC_GetNewSourceId() );
ABCC_SetMsgString( psMsg, (char*)pir_devciename, strlen(pir_devciename), 0 );
return( ABCC_SEND_COMMAND );//Send the command
}
return( ABCC_SKIP_COMMAND );//Skip the command
} - 随后在appl_asUserInitcmdSeq[]用户命令序列中添加PROFINET设备名称设置命令。
-
-
- void ABCC_CbfUserInitReq(void)在函数的末尾调用了ABCC_AddCmdSeq(appl_asUserInitCmdSeq, UserInitDone)
UserInitDone():由于命令序列是一系列命令的组合,命令不会同时执行完毕,因此在命令序列执行完成后,驱动程序会通过调用UserInitDone()函数通知用户初始化命令序列的完成。
-
- 实现一个在应用层调用的函数void APPL_SetPIRDevicename(char* devicename)设置模块PROFINET设备名称,开启命令执行标志。为了区分设置PROFINET名称命令是在模块化完成之前还是之后完成,定义一个标志量appl_fSetPIRDeviceNameInProgress用于区分命令的执行时段。
代码如下:
static BOOL appl_fSetPIRDeviceNameInProgress = FALSE;
void APPL_SetPIRDevicename(char* devicename)
{
if( appl_fSetPIRDeviceNameInProgress )
{
/*
** DeviceName updated next time
*/
return;
}
if( appl_fUserInitDone == FALSE )
{
pir_devciename = devicename;
}
appl_fPIRstationname = TRUE;
}
- 实现一个在应用层调用的函数void APPL_SetPIRDevicename(char* devicename)设置模块PROFINET设备名称,开启命令执行标志。为了区分设置PROFINET名称命令是在模块化完成之前还是之后完成,定义一个标志量appl_fSetPIRDeviceNameInProgress用于区分命令的执行时段。
-
- 最后在main.c的主循环中调用void APPL_SetPIRDevicename( char* devicename )函数,调用位置如下所示。
-
while(eAbccHandlerStatus == APPL_MODULE_NO_ERROR )
{
APPL_SetPIRDevicename("yqtest1");
eAbccHandlerStatus = APPL_HandleAbcc();
}
其实现原理与在模块初始完成之前设置类似,但需要用户自行构建命令序列,其实现框架与appl_asUserInitcmdSeq[]命令序列的构建及调用执行过程类似。
在模块初始化之后的设置需要将模块重置后才可生效。
代码实现示例:
- 定义设置PROFINET设备名称的命令序列,appl_setPIRDeviceNameCmdseq[],命令构建函数ABCC_CmdSeqCmdStatusType UpdatePIRDevicename(ABP_MsgType* psMsg )已于上文中实现。
-
static const ABCC_CmdSeqType appl_setPIRDeviceNameCmdseq[]=
{
ABCC_CMD_SEQ( UpdatePIRDevicename, NULL ),
ABCC_CMD_SEQ_END()
};
-
- 定义函数self_SetDevicename(),添加命令序列。
-
void self_SetDevicename(void)
{
ABCC_AddCmdSeq(appl_setPIRDeviceNameCmdseq,PdUpdateDeviceNameDone);
} - 补充说明:命令序列执行完成后可执行一个回调函数,可用于通知用户或者驱动,设备名称已经设置完成。
- 如例:PdUpdateDeviceNameDone(),该函数在ABCC_AddCmseq()中作为回调函数传入。 如果用户需要自己实现该回调函数,请注意回调函数的返回值与参数不可更改。
-
static void PdUpdateDeviceNameDone( void )
{
appl_fPIRstationnameSetdone=TRUE;
ABCC_PORT_DebugPrint(("set PIR DeviceName as:%s\n",pir_devciename));
ABCC_PORT_DebugPrint(("Please reset ABCC to enable the DeviceName setting\n"));
}
-
- 实现一个在应用层调用的函数APPL_Inprocess_SetPIRDevicename(),其函数入口为指向存储PROFINET设备名称的字符型数组指针,该函数调用self_SetDevicename()。
-
void APPL_Inprocess_SetPIRDevicename(char* devicename)
{
if(appl_fUserInitDone)
{
appl_fPIRstationname=TRUE; //
pir_devciename=devicename; //get command devicename
self_SetDevicename();
}
}
-
- 在主循环中调用void APPL_Inprocess_SetPIRDevicename(char* devicename),本示例中通过模拟外部条件触发(如HMI、设备配置上位机软件等)的方式判断执行命令,本示例中的外部触发条件为通过串口接收触发指令(用户请根据需求自行实现触发方式),并在程序主循环中通过Switch语句判断指令类型并执行响应命令。
-
while(eAbccHandlerStatus == APPL_MODULE_NO_ERROR )
{
APPL_SetPIRDevicename("yqtest1"); //set DeviceName in init
eAbccHandlerStatus = APPL_HandleAbcc();
//set attribute after abbc init through UART1 Command protocal further information in usart.c
if(appl_fUserInitDone==TRUE&&Sdef_NewCommandFlag==1)
{
switch(Sdef_setcommand)
{
case Sdef_SetIP_Cmd: //set IP Mask GateWay
appl_self_SetIP(9,Sdef_setData);
Sdef_NewCommandFlag=0;
break;
case Sdef_SetDeviceName_Cmd: // set DeviceName in process
APPL_Inprocess_SetPIRDevicename("yqtest1");
Sdef_NewCommandFlag=0;
break;
}
}
-
- 重置Anybus CompactCom 40
附加信息
以上代码仅作参考,不作为功能的最终实现,最终实现需要根据实际情况而定,请您先梳理该功能实现的流程,并参考官网英文手册实现功能需求。
官网手册下载地址如下: