?? profibus.c
字號:
//-----------------------------------------------------------------------------
// $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( ¶metersPath, 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( ¶metersPath, path );
RtlAppendUnicodeToString( ¶metersPath, 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 = ¬ThereDefault;
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 + -