English 中文(简体)
需要生产一个稳定的 10mSec 中断
原标题:Need to produce a stable 10mSec interrupt

我有一个程序, 我需要在 Windows 7/ 32 位计算机上以 10msec 速率 (100hz) 运行( 100hz ) 。 此中断程序可能会有一些最短的迟( 100uSec) 响应, 但不能长期漂移。 我有一个程序, 我已装入并使用 NtSetTimerRUT 将计时器设定为 10msec 分辨率, 然后使用 CreateTimerQuue/ CreateTimereQueTimer 函数创建一个计时器, 并有一个回调程序, 以切换 GPIO 针( 此时) - 生成预期的平方波, 只要我不在系统上做其他事情。 当我开始其他几个程序时, 我的平方波的精度会从窗口中跳出。 是否有办法在计时器中断时提高优先级水平( 或者我可以使用另一个计时器) 来产生更稳定的输出( perhaps the SMI)? 我的代码在下面,, 并且 使用 X86 检查了 Windows DDDK 管理员的设置环境 。

/*

Abstract:

Simple console test app for a 10mSec timer interrupt service

Enviroment:

Administrator Mode

*/


/* INCLUDES */

#include     <windows.h>
#include     <winioctl.h>
#include     <stdio.h>
#include     <string.h>
#include     <stdlib.h>
#include     <conio.h>
#include     <strsafe.h> 

#include     <stdlib.h>
#include     <stdio.h>

#include     <winsock2.h>
#include     <mswsock.h>

#pragma warning(disable:4127)   // condition expression is constant

FARPROC pNtQueryTimerResolution;
FARPROC pNtSetTimerResolution;

static  HANDLE    NTDLLModuleHandle;
static  HINSTANCE hInpOutDll;

typedef         void  (   __stdcall  *lpOut32 )( short , short );
typedef  short        (   __stdcall  *lpInp32 )( short );
typedef  BOOL         (   __stdcall  *lpIsInpOutDriverOpen )( void );

//Some global function pointers (messy but fine for an example)
lpOut32              gfpOut32;
lpInp32              gfpInp32;
lpIsInpOutDriverOpen gfpIsInpOutDriverOpen;


void CALLBACK TimerProc(void* lpParameter,
    BOOLEAN TimerOrWaitFired);

// MAIN

VOID  __cdecl    main( void )
{
    ULONG ulMinRes = 0;
    ULONG ulMaxRes = 0;
    ULONG ulCurRes = 0;

    HANDLE phNewQueue;
    HANDLE phNewTimer;

    phNewQueue        = CreateTimerQueue( );

    NTDLLModuleHandle = LoadLibrary( "NTDLL.DLL" );

    if( NULL == NTDLLModuleHandle )
    {
        return;
    }

    // Get the function pointers,
    pNtQueryTimerResolution = GetProcAddress( NTDLLModuleHandle, "NtQueryTimerResolution" );
    pNtSetTimerResolution = GetProcAddress( NTDLLModuleHandle, "NtSetTimerResolution" );

    if( ( pNtQueryTimerResolution == NULL ) || ( pNtSetTimerResolution == NULL ) )
    {
        printf( "unable to link to ddl





" );
        return;
    }

    pNtQueryTimerResolution( &ulMinRes, &ulMaxRes, &ulCurRes );
    printf( "MMR:  %d   %d   %d
", ulMinRes, ulMaxRes, ulCurRes );

    ulMaxRes = 100000;
    pNtSetTimerResolution( ulMaxRes, TRUE, &ulCurRes );

    pNtQueryTimerResolution( &ulMinRes, &ulMaxRes, &ulCurRes );
    printf( "MMR:  %d   %d   %d
", ulMinRes, ulMaxRes, ulCurRes );

    //Dynamically load the DLL at runtime (not linked at compile time)
    hInpOutDll = LoadLibrary( "InpOut32.DLL" ); 
    if( hInpOutDll != NULL )
    { 
        gfpOut32 = ( lpOut32 )GetProcAddress( hInpOutDll, "Out32" );
        gfpInp32 = ( lpInp32 )GetProcAddress( hInpOutDll, "Inp32" );
        gfpIsInpOutDriverOpen
            = ( lpIsInpOutDriverOpen )GetProcAddress( hInpOutDll, "IsInpOutDriverOpen" );

        if( gfpIsInpOutDriverOpen( ) )
        {
            gfpOut32( 0xA01, 0x00 );
        }
        else
        {
            printf( "unable to create timer system





" );
            return;
        }
    }

    CreateTimerQueueTimer( &phNewTimer, phNewQueue, TimerProc, NULL, 0, 10, 
                       WT_EXECUTEINTIMERTHREAD );

    do
    {
        Sleep( 1 );
    } while( TRUE );
}

void CALLBACK TimerProc(void* lpParameter,
    BOOLEAN TimerOrWaitFired)
{
    WORD wData;    

    UNREFERENCED_PARAMETER  ( lpParameter );
    UNREFERENCED_PARAMETER  ( TimerOrWaitFired );

    wData = gfpInp32( 0xA00 );
    wData++;
    gfpOut32( 0xA00, wData );
}
问题回答

您可以使用 < a href=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

这也许还不够, 如果最大时差为 100 微秒。 您可能需要使用 < a href=" http:// msdn. microsoft. com/ en- us/ library/ windows/ desktop/ ms686219% 28v=v. 85%29. aspx" rel= “ nofollow” @ code> SetritorityClass 函数, 设置您的进程优先级为 RealTIME_ PRIORITY_ CLASS, 使用 < a href=" 来设置 。 但要确定您的程序永远不会长期持有 CPU 或 Windows 将停止正常工作 。 特别是如果您的程序挂起, 整个 OS 将会挂起 ; 在这种情况下, 在关闭电源之前无法停止程序 。

即使这样也不够。 Windows并不是一个实时操作系统,它也不可能按照您的要求去做。

My experience with Windows and milli second is that it is not reliable. I measured the Sleep api with an Oscilloscope via the Nusbio device. And Sleep(0) is different from not calling the method at all. Sleep(5) and Sleep(15) give inconsistent result sometime some time the wait is the same.

如果您想要此精度, 您需要一个微控制器, 可以与您的 Windows 应用程序交谈 。





相关问题
Why running a service as Local System is bad on windows?

I am trying to find out the difference between difference service account types. I tumbled upon this question. The answer was because it has powerful access to local resources, and Network Service ...

Programmatically detect Windows cluster configuration?

Does anyone know how to programatically detect that a Windows server is part of a cluster? Further, is it possible to detect that the server is the active or passive node? [Edit] And detect it from ...

get file icon for Outlook appointment (.msg)

I ve read Get File Icon used by Shell and the other similar posts - and already use SHFileInfo to get the associated icon for any given extension, and that works great. However, Outlook uses ".msg" ...

Identifying idle state on a windows machine

I know about the GetLastInputInfo method but that would only give me the duration since last user input - keyboard or mouse. If a user input was last received 10 minutes ago, that wouldn t mean the ...

Terminating a thread gracefully not using TerminateThread()

My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function. At the moment I am using ...

热门标签