?? profibus.c
字號:
default:
PB->BaudRate = kbaud_9_6; break;
}
//
// Vypis nastaveni do logu
//
PB_DbgPrintL3( "PB: Parametry mastera: \n" );
PB_DbgPrintL3( "PB: Baudrate= %lubps\n", PB->BaudRateNum );
PB_DbgPrintL3( "PB: TS= %lu\n", PB->TS );
PB_DbgPrintL3( "PB: HSA= %lu\n", PB->HSA );
PB_DbgPrintL3( "PB: G= %lu\n", PB->G );
PB_DbgPrintL3( "PB: retry_ctr= %lu\n", PB->retry_ctr );
PB_DbgPrintL3( "PB: default_sap= %lu\n", PB->default_sap );
PB_DbgPrintL3( "PB: TSL= %lu tbit\n", PB->tsl );
PB_DbgPrintL3( "PB: TQUI= %lu tbit\n", PB->tqui );
PB_DbgPrintL3( "PB: TSET= %lu tbit\n", PB->tset );
PB_DbgPrintL3( "PB: TTR= %lu tbit\n", PB->ttr );
PB_DbgPrintL3( "PB: min_TSDR= %lu tbit\n", PB->min_tsdr );
PB_DbgPrintL3( "PB: max_TSDR= %lu tbit\n", PB->max_tsdr );
//
// Free the allocated memory before returning.
//
if ( parametersPath.Buffer )
ExFreePool( parametersPath.Buffer );
if ( parameters )
ExFreePool( parameters );
}
//*****************************************************************************
//** Pro PnP verzi.
//** Nacteni parametru Mastera z registru. Pokud se nezadari jsou pouzity
//** default parametry.
//*****************************************************************************
#ifdef PnP
void PB_GetConfigurationPnP( PTProfibus PB )
{
int i;
int BR;
HANDLE regKeyHandle;
ULONG Data;
NTSTATUS code;
//
// Read values from registry
//
code = IoOpenDeviceRegistryKey( PB->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_WRITE,
®KeyHandle );
if ( NT_SUCCESS( code ) )
{
if ( GetRegistryDWord ( regKeyHandle, L"TS", &Data) )
PB->TS = Data;
else
PB->TS = TS_default;
if ( GetRegistryDWord ( regKeyHandle, L"HSA", &Data) )
PB->HSA = Data;
else
PB->HSA = HSA_default;
if ( GetRegistryDWord ( regKeyHandle, L"G", &Data) )
PB->G = Data;
else
PB->G = G_default;
if ( GetRegistryDWord ( regKeyHandle, L"retry_ctr", &Data) )
PB->retry_ctr = Data;
else
PB->retry_ctr = retry_ctr_default;
if ( GetRegistryDWord ( regKeyHandle, L"default_sap", &Data) )
PB->default_sap = Data;
else
PB->default_sap = default_sap_default;
if ( GetRegistryDWord ( regKeyHandle, L"TSL", &Data) )
PB->tsl = Data;
else
PB->tsl = TSL_default;
if ( GetRegistryDWord ( regKeyHandle, L"TQUI", &Data) )
PB->tqui = Data;
else
PB->tqui = TQUI_default;
if ( GetRegistryDWord ( regKeyHandle, L"TSET", &Data) )
PB->tset = Data;
else
PB->tset = TSET_default;
if ( GetRegistryDWord ( regKeyHandle, L"min_TSDR", &Data) )
PB->min_tsdr = Data;
else
PB->min_tsdr = min_TSDR_default;
if ( GetRegistryDWord ( regKeyHandle, L"max_TSDR", &Data) )
PB->max_tsdr = Data;
else
PB->max_tsdr = max_TSDR_default;
if ( GetRegistryDWord ( regKeyHandle, L"TTR", &Data) )
PB->ttr = Data;
else
PB->ttr = TTR_default;
if ( GetRegistryDWord ( regKeyHandle, L"Baud Rate", &Data) )
BR = Data;
else
BR = Baud_rate_num_default;
ZwClose( regKeyHandle );
}
//
// 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;
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;
default:
PB->BaudRate = kbaud_9_6; break;
}
//
// Vypis nastaveni do logu
//
PB_DbgPrintL3( "PB: Parametry mastera(PnP): \n" );
PB_DbgPrintL3( "PB: Baudrate= %lubps\n", PB->BaudRateNum );
PB_DbgPrintL3( "PB: TS= %lu\n", PB->TS );
PB_DbgPrintL3( "PB: HSA= %lu\n", PB->HSA );
PB_DbgPrintL3( "PB: G= %lu\n", PB->G );
PB_DbgPrintL3( "PB: retry_ctr= %lu\n", PB->retry_ctr );
PB_DbgPrintL3( "PB: default_sap= %lu\n", PB->default_sap );
PB_DbgPrintL3( "PB: TSL= %lu tbit\n", PB->tsl );
PB_DbgPrintL3( "PB: TQUI= %lu tbit\n", PB->tqui );
PB_DbgPrintL3( "PB: TSET= %lu tbit\n", PB->tset );
PB_DbgPrintL3( "PB: TTR= %lu tbit\n", PB->ttr );
PB_DbgPrintL3( "PB: min_TSDR= %lu tbit\n", PB->min_tsdr );
PB_DbgPrintL3( "PB: max_TSDR= %lu tbit\n", PB->max_tsdr );
}
#endif
//*****************************************************************************
//** Ukonceni cinnosti mastera - uklid.
//**
//*****************************************************************************
void PB_Close( PTProfibus PB )
{
#ifdef USE_WATCHDOG
ProfiM_StopWatchDogTimer( PB->DeviceExtension );
#endif
PB->TimeOutState = TO_Stopped;
//delete RxFrame;
SAP_Close( &PB->SAP );
LAS_Close( &PB->LAS );
GAPL_Close( &PB->GAPL );
ReqB_Close( &PB->ReqB );
ResB_Close( &PB->ResB );
}
//*****************************************************************************
//** Uvedeni Mastera do pocatecniho stavu. Prechod do stavu Listen_Token
//** a spusteni time-outu k detekci necinnosti na sbernici.
//**
//*****************************************************************************
void PB_InitMaster( PTProfibus PB )
{
PB->MasterState = Offline;
PB->LastState = Offline;
PB->StationStatus = Master_not_ready;
PB->PS = -1;
PB->NS = -1;
PB->InBufLen = 0; // prijimaci buffer prazdny
PB->DuplicitAddressCounter = 0; //citac poctu vyskytu duplicitni adresy s TS na sbernici
PB->IgnoreTokenCounter = 0; //token od jine stanice nez PS je nekolik cyklu ignorovan s pouzitim tohoto citace
PB->FrameRepeatCounter = 0; //citac poctu opakovaneho vyslani zadosti pokud odpoved neprichazi
PB->G_CountDown = PB->G; //odpocet poctu pruchodu stavem PassToken mezi updaty GAPu
//
// RLL - Remote Live List
//
PB->RLL_Status = RLL_Stopped;
PB_SelfTest( PB );
PB->ColdStart = FALSE;
PB->FdlEventEnabled = FALSE; // priznak povoleni FDL Event indication
PB_ChangeMasterState( PB, Listen_Token );
PB_DbgPrintL2( "PB: Bod spusteni Profibusu !!!\n" );
// WRITE_PORT_UCHAR ( 0x2f8, 0x33 );
PB->AllInitialized = TRUE;
//
// Spusteni timeoutu k detekci necinnosti na sbernici
//
PB_SetTimeOut( PB, Tto, TO_StartNow );
PB_DbgPrintL2( "PB: Tto odstartovan...\n" );
}
//*****************************************************************************
//** Selftest mastera - moznost testovat jestli je pripojen interface
//** RS232<->RS485 vyslanim znaku do HW loopbacku a overenim jeho zpetneho
//** prijmu podle nastaveni smeru vysilani.
//**
//** RTS=TRUE - vyslany znak je opet prijat
//** RTS=FALSE - vyslany znak se jiz zpetne neobjevi
//**
//*****************************************************************************
BOOLEAN PB_SelfTest( PTProfibus PB )
{
//
// Neni implementovano
//
return TRUE;
}
//*****************************************************************************
//** Vola se pro zmenu stavu mastera - provadi pouze ty oparece, ktere
//** nasleduji bezprostredne po zmene stavu. Vetsina funkci je jinak
//** event-driven, je vyvolana prichodem znaku(ramce) nebo vyprsenim
//** time-outu.
//**
//** Parametry:
//** to - stav do ktereho se ma Master prepnout
//**
//*****************************************************************************
void PB_ChangeMasterState( PTProfibus PB, TMasterState to )
{
fdl_rb * Request = NULL;
int NextToTest;
//
// Ulozeni predchozi stavu mastera
//
PB->LastState = PB->MasterState;
PB->MasterState = to;
switch ( to )
{
case Active_Idle:
if ( PB->NS == PB->TS )
PB_ChangeMasterState( PB, Use_Token ); // nas master je na sbernici jedinym masterem - muzeme rovnou prejit do stavu Use_Token
else
PB_SetTimeOut( PB, Tto, TO_StartNow ); // spusteni time-outu k detekci rozpadu logickeho kruhu
break;
//*************************************************************
case Claim_Token:
if ( PB->LastState == Listen_Token ) // studeny start okruhu
{
LAS_NoStations( &PB->LAS );
PB->ColdStart = TRUE;
PB_ChangeMasterState( PB, Pass_Token );
break;
}
if ( PB->LastState == Active_Idle ) // na sbernici ustal provoz
{
//
// Pokud ma nas master nejnizsi adresu privlastnime si Token
//
int LAS_PS;
LAS_PS = LAS_PreviousStation( &PB->LAS, PB->TS );
if (LAS_PS >= PB->TS)
PB_ChangeMasterState( PB, Use_Token );
else
//
// Stanice s nejnizsi adresou mohla prestat pracovat, takze jeste
// spoustime time-out po jehoz vyprseni bude vymazana z LASu a
// vyzkousena dalsi stanice s nejnizsi adresou
// Timeout bezi pres Active_Idle.
//
PB_ChangeMasterState( PB, Active_Idle );
}
break;
//*************************************************************
case Use_Token:
if ( PB->LastState != Await_Data_Resp )
PB->UseTokenEntryTicks = GetCurrentTicks();
//
// Budovani Remote Life Listu - pokud cas dovoluje je na zacatku
// kazdeho vstupu do Use_Token testovana jedna stanice pozadavkem
// Request FDL Status.
//
if ( PB->RLL_Status == RLL_TestNext )
{
if ( PB_IsTimeForSending( PB ) || PB->RLL_Priority == high )
{
PB_SendRequestFDLStatuswithReply( PB, PB->RLL_Station );
PB_ChangeMasterState( PB, Await_Data_Resp );
}
else
{
PB_ChangeMasterState( PB, Check_Access_Time );
}
break;
}
//
// V bufferu pozadavku neni nic - prechod do stavu Check_Access_Time
//
if ( ReqB_Empty( &PB->ReqB ) )
{
PB_ChangeMasterState( PB, Check_Access_Time ); break;
}
//
// Pokud nam zbyva cas zacneme zpracovavat pozadavek - nejprve ty s vysokou
// prioritou. Pokud cas k vysilani uz neni, tak zpracujeme pouze jeden pozadavek
// s vysokou prioritou (pokud nejaky v bufferu je).
//
if ( PB_IsTimeForSending( PB ) )
{
if ( !ReqB_HighEmpty( &PB->ReqB ) )
{
ReqB_GetDeleteNextHigh( &PB->ReqB, &Request );
}
else if ( !ReqB_LowEmpty( &PB->ReqB ) )
{
ReqB_GetDeleteNextLow( &PB->ReqB, &Request );
}
}
else if ( PB->LastState != Await_Data_Resp &&
!ReqB_HighEmpty( &PB->ReqB ) )
{
ReqB_GetDeleteNextHigh( &PB->ReqB, &Request );
}//jestlize neni a zadny cas a zatim po prichodu do Use_Token nebyla vyslana zadna zprava from!=Await_Data_Response
if ( Request != NULL )
{
//
// Zpracovani pozadavku
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -