zoukankan      html  css  js  c++  java
  • 在不采用硬件计时器的情况下如何创建更精确的计时器

    在不采用硬件计时器的情况下如何创建更精确的计时器?最精确周期能否达到1毫秒? 

    对于精确值的要求不同,所采用的办法不同。以下阐述几种办法。 

    1、在单线程中循环调用API Sleep函数,Sleep函数精确程度为如果Sleep(N),那么实际睡眠时间在N到N+1毫秒之间。而且还要注意调用Sleep的线程优先级的问题。如果任务过多并且此线程优先级低,那误差就更大些。 

    2、调用API QueryPerformanceCounter函数,举例如下: 

     1 LARGE_INTEGER  liFrequency; 
     2 if (QueryPerformanceFrequency(&liFrequency))  // 查询系统时钟的频率,这里将返回1000  
     3 {
     4      liFrequency.QuadPart /= 1000;
     5      LARGE_INTEGER  liTimeOut; 
     6      if (QueryPerformanceCounter(&liTimeOut))   //得到截至到当前累计发生的系统时钟中断次数 
     7      {
     8           liTimeOut.QuadPart += liFrequency.QuadPart;   ///计算下一秒到来时总的中断次数是多少
     9           LARGE_INTEGER  liCurrent;
    10           do
    11           {
    12                     QueryPerformanceCounter(&liCurrent);    // 循环查询累计的的中断次数 
    13           } while (liCurrent.QuadPart < liTimeOut.QuadPart); ///到达下一秒
    14      }
    15 }  

    调用QueryPerformanceCounter同调用Sleep在本质上都是一样的,都是在单线程中无限循环等到周期一到执行任务,相比较 QueryPerformanceCounter要比Sleep更精确些,越精确就越要求线程的优先级,保障线程能够正常得到处理器。 

    3、以上办法难以保证周期精确到1毫秒并且WINCE系统稳定地运行,所以要从中断入手。

    以x86平台为例

    (1)先在Timer.c中将默认的 SetTimer0 (TIMER_COUNT) 中的 TIMER_COUNT /=2,SetTimer0函数负责设置系统时钟的频率,默认1毫秒发生一次中断,如果除以2就是0.5毫秒发生一次中断。

    (2)然后在fwpc.c文件中修改ISR函数PeRPISR,因为原来默认是1毫秒发生一次中断,在处理INTR_TIMER0时系统负责累计计数、管理线程的调度,返回相应的SYSINTR值,而我们没有办法再添加代码返回自己定义的SYSINTR值,所以现在要修改原来的处理代码,例如设置一个BOOL型变量,TRUE就执行原来默认的代码,而FALSE就返回我们自己定义的SYSINTR值,这样即不影响原来的ISR处理,又加入了我们的中断响应代码。ISR返回我们定义的SYSINTR后WINCE内核激活相对应的EVENT事件,我们就可以在我们编写的IST里处理任务了。 

    如何改系统调度的默认时间片值?  更改schedule.c文件中的dwDefaultThreadQuantum 变量,然后重新编译该文件并SYSGEN。调用API CeGetThreadQuantum就知道更改是否生效。 

  • 相关阅读:
    Asp.net Report动态生成
    Select2控件不能自适应的解决办法
    Bootstrap table 行编辑导航
    android – 无法解析AppCompatActivity
    Aspnet mvc移除WebFormViewEngine
    Android串口开发
    阿里云OCR图片转换成文字识别调用
    EF6实现软删除
    Audio播放
    asp.net webapi 的Request如何获取参数
  • 原文地址:https://www.cnblogs.com/91program/p/5253934.html
Copyright © 2011-2022 走看看