加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – 需要产生稳定的10mSec中断

发布时间:2020-12-14 05:36:19 所属栏目:Windows 来源:网络整理
导读:我有一个应用程序,我需要在 Windows 7/32位计算机(也将同时运行其他应用程序)上以10毫秒的速率(100赫兹)运行.此中断可能会有一些最迟(100uSec)响应,但不能长时间漂移.我有一个程序,我已加载并使用NtSetTimerResolution将计时器设置为10毫秒分辨率,然后使用Cr
我有一个应用程序,我需要在 Windows 7/32位计算机(也将同时运行其他应用程序)上以10毫秒的速率(100赫兹)运行.此中断可能会有一些最迟(100uSec)响应,但不能长时间漂移.我有一个程序,我已加载并使用NtSetTimerResolution将计时器设置为10毫秒分辨率,然后使用CreateTimerQueue / CreateTimereQueueTimer函数创建一个计时器,其中一个回调例程切换GPIO引脚(暂时) – 这会产生预期的方波,只要我不对系统做任何其他事情.当我开始其他几个过程时,方波的精确度就会消失.有没有办法在定时器中断上获得更高的优先级(或者是否有我可以使用的另一个定时器),这将产生更稳定的输出(可能是SMI)?我的代码如下所示,使用Windows DDK的x86检查构建环境构建,并从具有管理员权限的命令shell运行:

/*

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 ddlnnnnnn" );
        return;
    }

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

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

    pNtQueryTimerResolution( &ulMinRes,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 systemnnnnnn" );
            return;
        }
    }

    CreateTimerQueueTimer( &phNewTimer,phNewQueue,TimerProc,NULL,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 );
}

解决方法

您可以使用 SetThreadPriority为关键线程赋予优先权.在这种情况下,您可能需要显式创建一个线程并使用 CreateWaitableTimerEx,SetWaitableTimerExWaitForSingleObjectEx而不是 CreateTimerQueueTimer.确保关键线程永远不会在等待之间执行太长时间,否则Windows可能会停止正常工作.

如果最大延迟为100微秒,这可能还不够.您可能需要使用SetPriorityClass函数将进程优先级类设置为REALTIME_PRIORITY_CLASS,但请确保您的程序永远不会占用CPU很长时间,否则Windows将无法正常工作.特别是,如果您的程序挂起,整个操作系统将挂起;在这种情况下,没有办法停止程序关闭电源.

即使这可能还不够. Windows不是一个实时操作系统,它可能无法让它做你想要的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读