如何通过Anybus CompactCom 40驱动程序设置模块PROFINET设备名称

20 8月 2023

本文描述了如何通过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设备名称

  1. 在用户手册中查询PROFINET设备名称的对象/实例/属性                                                                        具体信息请参考《Anybus CompactCom 40 - PROFINET IRT Network Guide》的13.5.7小节。            通过驱动程序设置PROFINET设备名称,需要驱动发送Set_Attribute 命令到模块,该属性在Anybus CompactCom40 Network Configuration Object(0x04)的实例20实现,实例属性列表如下。                                       
  2. 在驱动程序中设置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。 
  3. 代码示例:

    • 首先参考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;
      }
    • 最后在main.c的主循环中调用void APPL_SetPIRDevicename( char* devicename )函数,调用位置如下所示。
    •  while(eAbccHandlerStatus == APPL_MODULE_NO_ERROR )
      {
      APPL_SetPIRDevicename("yqtest1");
      eAbccHandlerStatus = APPL_HandleAbcc();
      }
                                                            
在模块初始化完成之后设置模块PROFINET设备名称

其实现原理与在模块初始完成之前设置类似,但需要用户自行构建命令序列,其实现框架与appl_asUserInitcmdSeq[]命令序列的构建及调用执行过程类似。

在模块初始化之后的设置需要将模块重置后才可生效

代码实现示例:

  1. 定义设置PROFINET设备名称的命令序列,appl_setPIRDeviceNameCmdseq[],命令构建函数ABCC_CmdSeqCmdStatusType UpdatePIRDevicename(ABP_MsgType* psMsg )已于上文中实现。   
    •   
      static const ABCC_CmdSeqType appl_setPIRDeviceNameCmdseq[]=
      {
      ABCC_CMD_SEQ( UpdatePIRDevicename, NULL ),
      ABCC_CMD_SEQ_END()
      };
  2. 定义函数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"));
      }
  3. 实现一个在应用层调用的函数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();
      }
      }
                                       
  4. 在主循环中调用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;
      }
      }
  5. 重置Anybus CompactCom 40                                                    

附加信息

以上代码仅作参考,不作为功能的最终实现,最终实现需要根据实际情况而定,请您先梳理该功能实现的流程,并参考官网英文手册实现功能需求。

官网手册下载地址如下:

Anybus文件和文档 - CompactCom