|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionFor a variety of business and technical reasons, Microsoft Windows Vista, XP/2000 operating systems are increasingly being considered as a platform for deployment of real-time systems. The reasons include:
The Hadcon's real time module (RTM) has been developed to bring "hard " real time capabilities (such as creation of timers, system thread, of management by resources – memory, ports, interrupts) to Windows, excepting necessity of creating of the driver. RTM ArchitecturePrecise execution of events is critical in a real-time system. RTM provides complete flexibility to the developer to determine the appropriate timer resolution for their system. Timer interval values can be set between 100 microsecond and 1 millisecond (100,200,500,1000). The timer interval is default inside of [AddNewInst] section rtmdrv.inf file's RTM uses the "mixed" code i.e. timer's, interrupt's routines (working in Ring 0) and user routines (working in Ring 3) are incorporated in one DLL module. //
//
#pragma code_seg( "RTMCODE ")
Specifies a code section where functions are to be allocated.
For example:
#pragma code_seg( "RTMCODE ")
void timer1(unsigned dwmess )
{
/*
code
*/
..................
}
#pragma code_seg()
#pragma data_seg( "RTMDATA ")
Specifies a code section where initialized data are to be allocated.
For example:
#pragma data_seg( "RTMDATA ")
char buff[10] = {0};
int k1 = 0;
#pragma data_seg()
#pragma bss_seg( "RTMBSS ")
char buff[10];
int k1;
#pragma bss_seg()
TimersRTM uses the system timer.The system timer generates system ticks at a fixed rate of one tick per millisecond(or 100, 200 ,500 microsecond), which is the rate at which a timer interrupt is generated and serviced by the operating system (interrupt service routine ISR). This is in contrast to the Windows waitable timer, which is an object on which a thread can wait, or against which a thread can receive notification. Example Code#pragma code_seg( "RTMCODE ")
//
//
void timer1(unsigned dwmess )
{
int i;
unsigned nstate;
unsigned nvalue;
unsigned short ndigport;
if(nstop ) return ;
if(initLpt == 0)
{
_asm {
mov dx,378h
mov ax,0
out dx,ax ;//outp(BASE_LPT,0);
add dx,2; CR
mov ax,2eh
out dx,ax ;//outp(BASE_LPT+CR,0x2e);
}
initLpt =1;
rtmsqrt(1.5);
/*
code
*/
..................
}
#pragma code_seg()
void func()
{
int error;
HANDLE tm;
if(RtmInit(hRTMDLL,KERNEL_MODE) == -1) return 0;
RtmDebug(hRTMDLL ,TRUE);
tm = RtmCreateTimer
(hRTMDLL ,timer_anl,0x2000,stanl.quantum,KERNEL_MODE);
RtmStartTimer(hRTMDLL ,tm,0x3000);
error = RtmTimerPostMessage(hRTMDLL ,tm,0x100);
}
Using ThreadsThe #pragma code_seg( "RTMTHR ")
//
// thread code
//
#pragma code_seg()
Example Code#pragma code_seg( "RTMTHR ")
//
//
void writetofile(PWSTR pfl,UINT addr,int nsize)
{
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE FileHandle = NULL;
UNICODE_STRING fileName1;
NTSTATUS status;
fileName1.Buffer = NULL;
fileName1.Length = 0;
fileName1.MaximumLength = 256;
DbgPrint("start");
fileName1.Buffer = (unsigned short *)ExAllocatePool(PagedPool,
fileName1.MaximumLength);
DbgPrint("111");
RtlZeroMemory(fileName1.Buffer, fileName1.MaximumLength);
status = RtlAppendUnicodeToString(&fileName1, pfl);
InitializeObjectAttributes (&objectAttributes,
(PUNICODE_STRING)&fileName1,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
status = ZwCreateFile(&FileHandle,
FILE_APPEND_DATA,
&objectAttributes,
&IoStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if(NT_SUCCESS(status))
{
ZwWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatus,
(void *)addr,
nsize,
NULL,
NULL );
ZwClose(FileHandle);
DbgPrint ("Close file");
}
if(fileName1.Buffer)
ExFreePool(fileName1.Buffer);
}
int systhread(void *param)
{
unsigned int _cr3 = 0;
PVOID pv;
PHYSICAL_ADDRESS pf;
n_count_task++;
if(n_count_task == 10)
{
_asm mov eax,cr3
_asm mov _cr3,eax
pf.HighPart = 0;
pf.LowPart = _cr3;
pv = MmGetVirtualForPhysical (pf);
writetofile(L"\\??\\C:\\tmp\\qqq1",(UINT)pv ,0x1000);
}
return 0;
}
#pragma code_seg()
void func()
{
int error;
HANDLE tm;
HANDLE th;
if(RtmInit(hRTMDLL,KERNEL_MODE) == -1) return 0;
th = RtmCreateThread(hRTMDLL ,(THREAD_START_ROUTINE)systhread,NULL);
}
InterruptsRTM allows a process to directly interface with a device without having to write a Windows driver via typedef struct _tagRTMINTERUPT {
INTERFACE_TYPE itype;
ULONG nVector ;
ULONG BusNumber ;
ULONG VenID ;
ULONG DevID;
unsigned char bShared;
void *lpParameter;
INTERRUPT_ROUTINE newintr;
) RTMINTERRUPT;
Example Code#pragma data_seg( "RTMDATA ")
int _isr = 0;
#pragma data_seg()
//
//
void newintr(void *pv)
{
_isr++;
/*
-------------------------
*/
}
int func1()
{
HANDLE tm; int count;
RTMCONNINTERRUPT cinter;
HANDLE pi,pi1;
if(RtmInit(hRTMDLL, KERNEL_MODE) == -1) return 0;
cinter.BusNumber = 1;
cinter.DevID = 0x2f00;
cinter.nVector =0;
cinter.VenID = 0x14f1;
cinter.itype = PCIBus;
cinter.lpParameter = NULL;
cinter.newintr = newintr;
pi = RtmConnectInterrupt(hRTMDLL ,&cinter);
cinter.BusNumber = 0;
cinter.nVector =1;
cinter.itype = Isa;
cinter.lpParameter = NULL;
cinter.newintr = newintr;
pi1 = RtmHookInterrupt (hRTMDLL ,&cinter);
count = _isr;
count = _isr;
count = _isr;
RtmUnhookInterrupt (hRTMDLL ,pi1);
}
E-mail: info@hadcon.ru
|
||||||||||||||||||||||