⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bf_util.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 4 页
字号:

} /* end of bf_ActivateMapping() */



/*---------------------------------------------------------------------------
** bf_AddMapping()
**---------------------------------------------------------------------------
*/

void bf_AddMapping( BF_AddTrrblType *pTrrbl )
{
   UINT16                         iMappingEntry;
   volatile bf_MappingEntryType  *psMappingEntry;


   GS_UseCritical();

   /*
   ** If an entry already exists, glom onto it.
   */

   iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );

   if( iMappingEntry != BF_NO_MAPPING )
   {
      bf_s.asMappingEntries[ iMappingEntry ].iConfiguredUsers++;
      return;
   }

   /*
   ** Check to make sure mapping doesn't run off end of data area
   */

   if( pTrrbl->iAppDataOffset + pTrrbl->iMaxSize > bf_s.asAppDataAreas[ pTrrbl->eAppDataAreaId ].iSize )
   {
      /*
      ** Put an error code in the trrbl, and return.
      */

      pTrrbl->eStatus = BF_MAPPING_BOUND_ERROR;
      return;
   }

   /*
   ** New entry gets created one past the last entry in the list.
   */

   psMappingEntry = &bf_s.asMappingEntries[ bf_s.iMappingEntries ];

   psMappingEntry->iClass             = pTrrbl->iClass;
   psMappingEntry->iInstance          = pTrrbl->iInstance;
   psMappingEntry->fCon               = pTrrbl->fCon;

   psMappingEntry->eAppDataAreaId     = pTrrbl->eAppDataAreaId;
   psMappingEntry->iAppDataAreaOffset = pTrrbl->iAppDataOffset;
   psMappingEntry->iMaxMappingSize    = pTrrbl->iMaxSize;

   psMappingEntry->iStatusBit         = pTrrbl->iStatusBit;
   psMappingEntry->iStatusStyle       = pTrrbl->iStatusStyle;

   psMappingEntry->iConfiguredUsers   = 1;
   psMappingEntry->iActiveUsers       = 0;

   psMappingEntry->iTransportId       = 0;
   psMappingEntry->iActiveEntry       = BF_NO_MAPPING;
   psMappingEntry->iActiveSubList     = 0;

   /*
   ** Subtract the size of the status data from the size of the
   ** mapping entry.  The status data does not appear in the data area.
   */

   switch( psMappingEntry->iStatusStyle )
   {
   case CD_RI_STYLE_32_BIT:
      psMappingEntry->iMaxMappingSize -= 4;
      break;

   case CD_RI_STYLE_ZERO_LEN:
   case CD_RI_STYLE_PURE_DATA:
   case CD_RI_STYLE_HEARTBEAT:
   default:
      /*
      ** These styles don't have any status size associated with them
      */
      break;
   }

   /*
   ** Make it official by adding to the size of the list.
   */

   GS_EnterCritical();
   {
      bf_s.iMappingEntries++;
   }
   GS_ExitCritical();

} /* end of bf_AddMapping() */



/*---------------------------------------------------------------------------
** bf_DeactivateMapping()
**---------------------------------------------------------------------------
*/

void bf_DeactivateMapping( BF_DeTrrblType *pTrrbl )
{
   UINT16                         iActiveSubList;
   UINT16                         iAppDataAreaId;
   UINT16                         iLastEntry;
   UINT16                         iMappingEntry;
   volatile BF_ActiveEntryType   *psActiveEntry;
   volatile bf_ActiveSubListType *psActiveSubList;
   volatile bf_AppDataAreaType   *psAppDataArea;
   volatile bf_MappingEntryType  *psMappingEntry;
   CM_AppOpenCloseTrrblType		 *psAppOpenCloseTrrbl;	/* October,28th 2005, H.F. */
   UINT16						  iTransport;			/* October,28th 2005, H.F. */


   GS_UseCritical();

   /*
   ** Find the appropriate entry & validate that it exists and is active.
   */

   iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );

   if( iMappingEntry == BF_NO_MAPPING )
   {
      return;
   }

   psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];

   /*
   ** Only delete the active entry when the last user goes away.
   */

   if( psMappingEntry->iActiveUsers > 0 )
   {
      psMappingEntry->iActiveUsers--;
   }

   if( psMappingEntry->iActiveUsers > 0 )
   {
	  /*
	  ** start edits: October,28th 2005, H.F.
	  **
	  ** Problem: iTransportId is NOT unique for a Consumer Assembly.
	  **		  If there are 3 class 1 connections to the same Consumer
	  **		  Connection Point, there will also be 3 iTransportIds.
	  **		  However, it is used for mapping entries. So it can happen
	  **		  that the iTransportId, that is currently used for mapping
	  **		  a Consumer Assembly is now used in conjunction with another
	  **		  Consumer Assembly, as the associated connection to the 
	  **		  first Consumer Assembly was closed and so the iTransportId
	  **		  was released and is now used by another connection to the
	  **		  second Consumer Assembly. The mapping of the first Consumer
	  **		  Assembly has been overwritten by the mapping of the second
	  **		  Consumer Assembly, then. And this can result in an Access
	  **		  Violation when closing the connection to the first Consumer
	  **		  Assembly.
	  **
	  ** Workaround: Re-Map the Consumer Connection Point, if the connection
	  **			 with the currently actually used iTransportId is closed.
	  **			 And delete the mapping for this iTransportId.
	  */

	  /* check, if Consumer */
	  if( psMappingEntry->fCon )
	  {
		  /* get 'iTransportId' of closing transport */
		  psAppOpenCloseTrrbl = (CM_AppOpenCloseTrrblType *)pTrrbl->xUserHandle;
		  iTransport = psAppOpenCloseTrrbl->psConnRecord->iConTransportId;

		  /* delete mapping */
		  bf_s.aiMappingByTransport[ iTransport ] = BF_NO_MAPPING;

		  /* check, if actually used mapping has just been deleted */
		  if( psMappingEntry->iTransportId == iTransport )
		  {
			  /* find another mapping */
			  psMappingEntry->iTransportId = 1;
			  while( psMappingEntry->iTransportId <= EN_CD_LAST_C1C_TRANSPORT )
			  {
				  if( bf_s.aiMappingByTransport[ psMappingEntry->iTransportId ] == iMappingEntry )
				  {
					  /* get active entry */
					  psActiveEntry = &bf_s.asActiveEntries[ psMappingEntry->iActiveEntry ];

					  /* assign new iTransportId */
					  psActiveEntry->iTransportId = psMappingEntry->iTransportId;

					  break;
				  }

				  psMappingEntry->iTransportId++;
			  }
		  }
	  }

	  /*
	  ** end edits: October,28th 2005, H.F.
	  */

      
	  return;
   }

   if( psMappingEntry->iActiveEntry == BF_NO_MAPPING )
   {
      return;
   }

   /*
   ** Collect convenience pointers and such.
   */

   iAppDataAreaId  = psMappingEntry->eAppDataAreaId;
   psAppDataArea   = &bf_s.asAppDataAreas[ iAppDataAreaId ];
   psActiveSubList = &psAppDataArea->asActiveSubList[ psMappingEntry->iActiveSubList ];
   psActiveEntry   = &bf_s.asActiveEntries[ psMappingEntry->iActiveEntry ];

   /*
   ** Remove the penalty for the entry being deactivated.
   */

   psActiveSubList->lCpuTimeAreaSubList -= psAppDataArea->lCpuTimePerEntry + ( psAppDataArea->lCpuTimePerByte * psActiveEntry->iResyncSize );

   /*
   ** If there are entries remaining in this active entry sub list,
   ** take the last entry in the list and backfill the hole we're creating.
   ** In any case, bump the active entry counts.
   */

   GS_EnterCritical();
   {
      iLastEntry = psActiveSubList->iActiveEntry1 + psActiveSubList->iActiveEntries - 1;

      if( ( psActiveSubList->iActiveEntries > 1 ) &&
          ( psMappingEntry->iActiveEntry != iLastEntry ) )
      {
         bf_MoveActiveEntry( psMappingEntry->iActiveEntry, iLastEntry );
      }

      psActiveSubList->iActiveEntries--;
      bf_s.iActiveEntries--;

   /*
   ** Zap the references to the now defunct active entry.
   */

   iActiveSubList = psMappingEntry->iActiveSubList + 1;
   psActiveSubList++;
   bf_s.aiMappingByTransport[ psMappingEntry->iTransportId ] = BF_NO_MAPPING;

   psMappingEntry->iTransportId   = 0;
   psMappingEntry->iActiveEntry   = BF_NO_MAPPING;
   psMappingEntry->iActiveSubList = 0;

   }
   GS_ExitCritical();

   /*
   ** Roll the remaining active entry lists down to fill the vacated space.
   */

   while( iAppDataAreaId < AD_NUM_APP_DATA_AREAS )
   {
      while( iActiveSubList < BF_NUM_SUB_LISTS )
      {
         if( psActiveSubList->iActiveEntries > 0 )
         {
            GS_EnterCritical();
            {
               psActiveSubList->iActiveEntry1--;
               bf_MoveActiveEntry( psActiveSubList->iActiveEntry1, psActiveSubList->iActiveEntry1 + psActiveSubList->iActiveEntries );
            }
            GS_ExitCritical();
         }
         iActiveSubList++;
         psActiveSubList++;
      }

      /*
      ** Roll to the next app mem area starting with the first sub list.
      */

      iAppDataAreaId++;
      psAppDataArea++;

      iActiveSubList  = 0;
      psActiveSubList = &psAppDataArea->asActiveSubList[ 0 ];
   }

   /*
   ** Debug aid.  Clean out the last entry in the list
   ** (we've just abandoned it).
   */

   psActiveEntry = &bf_s.asActiveEntries[ bf_s.iActiveEntries ];
   psActiveEntry->pSource        = NULL;
   psActiveEntry->pDestination   = NULL;
   psActiveEntry->iResyncSize    = 0;
   psActiveEntry->iTranBufOffset = 0;
   psActiveEntry->pAddStatus     = NULL;
   psActiveEntry->iTransportId   = 0;

} /* end of bf_DeactivateMapping() */



/*---------------------------------------------------------------------------
** bf_DeleteMapping()
**---------------------------------------------------------------------------
*/

void bf_DeleteMapping( BF_DeTrrblType *pTrrbl )
{
   UINT16                         iMappingEntry;
   volatile bf_MappingEntryType  *psMappingEntry;
   volatile bf_MappingEntryType  *psLastEntry;


   GS_UseCritical();

   /*
   ** Find the entry in the main list.
   */

   iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );

   if( iMappingEntry == BF_NO_MAPPING )
   {
      return;
   }

   psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];

   /*
   ** Delete one user.  Bail if there are more users left.
   */

   psMappingEntry->iConfiguredUsers--;

   if( psMappingEntry->iConfiguredUsers > 0 )
   {
      return;
   }

   /*
   ** This is the last user.  We really need to delete the mapping entry.
   ** Make sure the entry is deactivated.
   */

   while( psMappingEntry->iActiveUsers )
   {
   bf_DeactivateMapping( pTrrbl );
   }

   /*
   ** Bump the mapping entry count.
   ** If this was the last entry in the list, we be done.
   */

   GS_EnterCritical();
   {
      if( --bf_s.iMappingEntries == iMappingEntry )
      {
         GS_ExitCritical();
         goto Cleanup;
      }

      /*
      ** More stuff left in the list. Copy down the last entry in the list
      ** to fill the space left by the deleted entry.
      ** Assume the entry being deleted is already disabled.
      */

      psLastEntry    = &bf_s.asMappingEntries[ bf_s.iMappingEntries ];
      psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];

      psMappingEntry->iClass             = psLastEntry->iClass;
      psMappingEntry->iInstance          = psLastEntry->iInstance;
      psMappingEntry->fCon               = psLastEntry->fCon;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -