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

📄 profibus.c

📁 profibus-dp主站源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// $Id: profibus.c,v 1.0.0                                          2004/01/13
//-----------------------------------------------------------------------------
//
//      ProfiM - PROFIBUS MASTER DRIVER FOR WINDOWS NT/2000
//
// Author:  
//      Pavel Trnka, CTU FEE
//      trnkap@seznam.cz
// With help and advices from:
//      Ing. Petr Smolik, CTU FEE
//      Ing. Pavel Pisa, CTU FEE
//      Ing. Pavel Burget, CTU FEE
//
//-----------------------------------------------------------------------------
//
// Popis:
// ------
//   Hlavni cast ProfiMu. Zajistuje beh stavoveho automatu Profibus mastera,
// zpracovavani pozadavku od aplikacni vrstvy, reakce na prichozi ramce ze
// sbernice. Dale zajistuje detekci chybovych stavu na sbernici a v samotnem
// Masteru s jejich naslednym zotavenim.
//
// Funkce volane z vnejsku:
// ---------------------------
//
//   PB_Init    - Inicializace Profibus mastera
//   PB_Close   - Ukonceni cinnosti
//   PB_RxByte    - Predani prijateho znaku ze sbernice nizsi vrstvou
//            masterovi
//   PB_TimeTick  - Vyvolan po vyprseni time-outu nebo vyprseni maximalne
//            mozneho intervalu, ktery casovani umoznuje. Casovani
//            je zajisteno z nizsi vrsty.
//   PB_FrameOut  - Nizsi vrstva oznamuje masterovi, ze na sbernici byl
//            vyslan cely ramec.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------


#include "Profibus.h"


//*****************************************************************************
//**  Inicializace objektu TProfibus
//**  vytvoreni LASu, GAPu a pristupovych bodu SAP
//**  nacteni konfigurace z registru nebo pouziti default parametru
//**
//**  Parametry:
//**  DeviceExtension - ukazatel na Device Extension ovladace obsahujici
//**            objekt TProfibus
//**  RegistryPath  - cesta k parametrum v registrech
//**
//*****************************************************************************

void PB_Init( PTProfibus PB,
              void *DeviceExtension,
              PUNICODE_STRING RegistryPath )
{
  LARGE_INTEGER f;

  if ( !DeviceExtension )
  {
    DbgPrint( "PB: PB_Init Error - DeviceExtension is NULL!" );
    return;
  }        
  /*      if (DeviceExtension->magic!=PROFIM_MAGIC) {   
          DbgPrint("PB: PB_Init Error - Device Extension MAGIC is invalid!");
        return;
      }*/

  //
  // Ulozeni ukazatele na DeviceExtension ovladace k umozneni pristupu k datum
  // ovladace z ostatnich rutin Profibus Mastera
  //
  PB->DeviceExtension = DeviceExtension;


  //
  // Nacteni konfigurace Profibus Mastera z registru
  //
  #ifdef PnP
    PB_GetConfigurationPnP( PB );
  #endif
  #ifndef PnP
    PB_GetConfiguration( PB, RegistryPath );
  #endif  

  //
  // Inicializace pouzivanych datovych struktur
  //
  LAS_Init( &PB->LAS, PB->HSA + 1 );      // lepe 128
  GAPL_Init( &PB->GAPL, PB->HSA + 1, PB->TS );
  SAP_Init( &PB->SAP, 64 );
  ReqB_Init( &PB->ReqB, PB->DeviceExtension );
  ResB_Init( &PB->ResB, PB->DeviceExtension );


  //
  // Zjisteni konstant pro presne odecty casovych intervalu. Je vyuzivan Performance Counter.
  // Pozor uplne jinak nez v user space - vraci frekvenci v parametru a hodnotu casovace jako vysledek
  //
  KeQueryPerformanceCounter( &f );
  //
  // Vypocet kolik ticku Performance counteru odpovida intervalu Tbit (doba vysilani jednoho bitu)
  //          
  PB->Tbit = ( int ) /*124;*/f.QuadPart /
             PB->BaudRateNum/*Baud_rate_num_default*/;  // pocet tiku Performance Counteru na jeden bit = Tbit 
  PB->Tbit3x = 3 * PB->Tbit;
  PB_DbgPrintL3( "PB:   Tbit=        %d Performance Counter ticks\n", PB->Tbit );
  PB->LastTicks = GetCurrentTicks();
  PB->LastUseTokenEntryTicks = GetCurrentTicks();        // melo by byt jinde - takhle pri prvnim vstupu do Use_Token nemame cas na nic

  PB->TimeOutState = TO_Stopped;
  
  PB->ActualRequest = &(PB->ReqB.LowBuffer[0]); // inicializace pro pripad chybneho predcasneho pouziti ActualRequestu (jinak nema vyznam)

  //
  // Inicializace identifikacni datove struktury
  //
  PB->Ident[0] = strlen( Vendor_name );
  PB->Ident[1] = strlen( Controller_type );
  PB->Ident[2] = strlen( HW_release );
  PB->Ident[3] = strlen( SW_release );
  PB->Ident[4] = '\x00';
  strcat( PB->Ident, Vendor_name );
  strcat( PB->Ident, Controller_type );
  strcat( PB->Ident, HW_release );
  strcat( PB->Ident, SW_release );    
  
  
  #ifdef USE_WATCHDOG
    //
    // Inicializace WatchDog timeru
    //  
    ProfiM_StartWatchDogTimer( PB->DeviceExtension );                      
  #endif

  //
  //  Spusteni Profibus Mastera
  //
  PB_InitMaster( PB );
}



//*****************************************************************************
//** Nacteni parametru Mastera z registru. Pokud se nezadari jsou pouzity
//** default parametry.
//**
//**  Parametry:
//**  RegistryPath  - cesta k parametrum v registrech
//**
//*****************************************************************************

void PB_GetConfiguration( PTProfibus PB, PUNICODE_STRING RegistryPath )
{
  /*
        PB->TS=       TS_default;
        PB->HSA=      HSA_default;
        PB->G=        G_default;
        PB->BaudRate=   Baud_rate_default;
        PB->retry_ctr=    retry_ctr_default;
        PB->default_sap=  default_sap_default;
        PB->tsl=      TSL_default;
        PB->tqui=     TQUI_default;
        PB->tset=     TSET_default;
        PB->min_tsdr=   min_TSDR_default;
        PB->max_tsdr=   max_TSDR_default;        
        PB->ttr=      TTR_default;
  */

  PRTL_QUERY_REGISTRY_TABLE parameters      = NULL;
  UNICODE_STRING            parametersPath;

  ULONG                     notThereDefault = 1234567;
  ULONG                     TSDefault;
  ULONG                     HSADefault;
  ULONG                     GDefault;
  ULONG                     Baud_rateDefault;
  ULONG                     retry_ctrDefault;
  ULONG                     default_sapDefault;
  ULONG                     TSLDefault;
  ULONG                     TQUIDefault;
  ULONG                     TSETDefault;
  ULONG                     min_TSDRDefault;
  ULONG                     max_TSDRDefault;    
  ULONG                     TTRDefault; 

  NTSTATUS                  status          = STATUS_SUCCESS;
  PWSTR                     path            = NULL;
  USHORT                    queriesPlusOne  = 13;   // Pocet polozek ctenych z registru plus jedna

  int                       i;
  int                       BR;

  //
  // Nastaveni parametru nectenych z registru na default hodnoty
  //
  PB->medium_red = medium_red_default;
  PB->in_ring_desired = in_ring_desired_default;
  PB->physical_layer = physical_layer_default;


  //
  // Naplneni datovych struktur parametersPath a parameters pro
  // dotaz do registru pomoci fce RtlQueryRegistryValues    
  //

  parametersPath.Buffer = NULL;

  //
  // Registry path is already null-terminated, so just use it.
  //
  path = RegistryPath->Buffer;

  //
  // Allocate the Rtl query table.
  //
  parameters = ExAllocatePool( PagedPool,
                               sizeof( RTL_QUERY_REGISTRY_TABLE ) * queriesPlusOne );

  if ( !parameters )
  {
    PB_DbgPrintL3( "PB: ExAllocatePool failed for Rtl in GetConfiguration\n" );
    status = STATUS_UNSUCCESSFUL;
  }
  else
  {
    RtlZeroMemory( parameters,
                   sizeof( RTL_QUERY_REGISTRY_TABLE ) * queriesPlusOne );

    //
    // Form a path to this driver's Parameters subkey.
    //

    RtlInitUnicodeString( &parametersPath, NULL );

    parametersPath.MaximumLength = RegistryPath->Length +
                                   sizeof( L"\\Parameters" );

    parametersPath.Buffer = ExAllocatePool( PagedPool,
                                            parametersPath.MaximumLength );

    if ( !parametersPath.Buffer )
    {
      PB_DbgPrintL3( "PB: ExAllocatePool failed for Path in GetConfiguration\n" );
      status = STATUS_UNSUCCESSFUL;
    }
  }

  if ( NT_SUCCESS( status ) )
  {
    //
    // Form the parameters path.
    //

    RtlZeroMemory( parametersPath.Buffer, parametersPath.MaximumLength );
    RtlAppendUnicodeToString( &parametersPath, path );
    RtlAppendUnicodeToString( &parametersPath, L"\\Parameters" );

    //
    // Gather all of the "user specified" information from
    // the registry.
    //

    for ( i = 0; i < queriesPlusOne - 1; i++ )
    {
      parameters[i].Flags = RTL_QUERY_REGISTRY_DIRECT;
      parameters[i].DefaultType = REG_DWORD;
      parameters[i].DefaultData = &notThereDefault;
      parameters[i].DefaultLength = sizeof( ULONG );
    }


    parameters[0].Name = L"TS";
    parameters[0].EntryContext = &TSDefault;
    parameters[1].Name = L"HSA";
    parameters[1].EntryContext = &HSADefault;
    parameters[2].Name = L"G";
    parameters[2].EntryContext = &GDefault;
    parameters[3].Name = L"Baud Rate";
    parameters[3].EntryContext = &Baud_rateDefault;        
    parameters[4].Name = L"retry_ctr";
    parameters[4].EntryContext = &retry_ctrDefault;                
    parameters[5].Name = L"default_sap";
    parameters[5].EntryContext = &default_sapDefault;                
    parameters[6].Name = L"TSL";
    parameters[6].EntryContext = &TSLDefault;                
    parameters[7].Name = L"TQUI";
    parameters[7].EntryContext = &TQUIDefault;                
    parameters[8].Name = L"TSET";
    parameters[8].EntryContext = &TSETDefault;                
    parameters[9].Name = L"min_TSDR";
    parameters[9].EntryContext = &min_TSDRDefault;              
    parameters[10].Name = L"max_TSDR";
    parameters[10].EntryContext = &max_TSDRDefault;                
    parameters[11].Name = L"TTR";
    parameters[11].EntryContext = &TTRDefault;                


    status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE |
                                     RTL_REGISTRY_OPTIONAL,
                                     parametersPath.Buffer,
                                     parameters,
                                     NULL,
                                     NULL );

    if ( !NT_SUCCESS( status ) )
    {
      PB_DbgPrintL3( "PB: Chyba pri cteni parametru z registru!\n" );
    }
    else
    {
      PB_DbgPrintL3( "PB: Parametry uspesne precteny z registru.\n" );
    }


    status = STATUS_SUCCESS;
  }

  //
  // Pokud parametr nebyl z registru precten priradi default hodnotu
  //

  if ( TSDefault == notThereDefault )
    PB->TS = TS_default;
  else
    PB->TS = TSDefault;
  if ( HSADefault == notThereDefault )
    PB->HSA = HSA_default;
  else
    PB->HSA = HSADefault;
  if ( GDefault == notThereDefault )
    PB->G = G_default;
  else
    PB->G = GDefault;
  if ( retry_ctrDefault == notThereDefault )
    PB->retry_ctr = retry_ctr_default;
  else
    PB->retry_ctr = retry_ctrDefault;
  if ( default_sapDefault == notThereDefault )
    PB->default_sap = default_sap_default;
  else
    PB->default_sap = default_sapDefault;
  if ( TSLDefault == notThereDefault )
    PB->tsl = TSL_default;
  else
    PB->tsl = TSLDefault;
  if ( TQUIDefault == notThereDefault )
    PB->tqui = TQUI_default;
  else
    PB->tqui = TQUIDefault;
  if ( TSETDefault == notThereDefault )
    PB->tset = TSET_default;
  else
    PB->tset = TSETDefault;
  if ( min_TSDRDefault == notThereDefault )
    PB->min_tsdr = min_TSDR_default;
  else
    PB->min_tsdr = min_TSDRDefault;
  if ( max_TSDRDefault == notThereDefault )
    PB->max_tsdr = max_TSDR_default;
  else
    PB->max_tsdr = max_TSDRDefault;
  if ( TTRDefault == notThereDefault )
    PB->ttr = TTR_default;
  else
    PB->ttr = TTRDefault;


  if ( Baud_rateDefault == notThereDefault )
    BR = Baud_rate_num_default;
  else
    BR = Baud_rateDefault;

  PB->BaudRateNum = BR;

  switch ( BR )
  {
    case 9600:
      PB->BaudRate = kbaud_9_6;   break;
    case 19200:
      PB->BaudRate = kbaud_19_2;  break;        
    case 45450:
      PB->BaudRate = kbaud_45_45; break;                
    case 93750:
      PB->BaudRate = kbaud_93_75; break;                
    case 187500:
      PB->BaudRate = kbaud_187_5; break;                
    case 375000:
      PB->BaudRate = kbaud_375;   break;                        
    case 500000:
      PB->BaudRate = kbaud_500;   break;                
    case 750000:
      PB->BaudRate = kbaud_750;   break;                        
    case 1500000:
      PB->BaudRate = mbaud_1_5;   break;                        
    case 3000000:
      PB->BaudRate = mbaud_3;   break;
    case 6000000:
      PB->BaudRate = mbaud_6;   break;        
    case 12000000:
      PB->BaudRate = mbaud_12;    break;        

⌨️ 快捷键说明

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