OAL之系统时钟

WINCE (WINCE5.0 WINCE 6.0)可用的数码时钟 超大字体 利用闲置的导航仪做时钟 WINCE (WINCE5.0 WINCE 6.0) 可用的数码时钟 利用闲置的导航仪做时钟,超大字体数码时钟,不怕看不清楚,让你的导航仪发挥余热,老人家无论白天还是晚上都可以看得很清楚 立即下载

1. 系统时钟与内核的关系

        WinCE 5.0采用基于时间片的抢占式多任务的实时内核,而且每个线程可以根据需要自行设定线程时间片的大小(参考CeSetThreadQuantum函数),默认为100ms,这个默认值dwDefaultThreadQuantum也可以在OEMInit()时自行设定。在内核源文件中,与单词Quantum有关的变量名一般是指时间片,WinCE内核定义了几个与时钟有关的全局变量,他们也是内核与OAL接口的一部分:

      1) dwReschedTime,这个变量在内核的调度程序中更新,KCNextThread()是内核调度程序的一部分,它根据线程的优先级和状态决定接下来处于运行状态的线程,并根据该线程的时间片来设定dwReschedTime。顾名思义,这个变量就是指下一次运行调度程序的时间。

         既然讲的是WinCE 5.0的内核,这里就不得不插入介绍一下它的调度程序有一个新特性叫做可变的系统时钟节拍(system tick),目的就是让硬件定时器(CPU的时钟)只有在调度程序需要时才产生中断。这样不但可以提高调度程序的效率,而且有助于CPU节能(有关这点后面还会讲到)。这个特性是可选的,依赖与OAL的实现。不采用这个特性,一般每个系统时钟节拍为1ms,即每毫秒产生一个时钟中断。当然,就像默认的线程时间片一样,这个值也是可以在OEMInit()时自行设定。

      2) CurMSec,DWORD类型变量,每次时钟中断时更新,累计从系统启动到当前一共经历了多少系统时钟节拍(太绕口了,或者说系统嘀哒(tick)了多少下)。

         如果用户程序调用GetTickCount()函数,其实就是直接返回这个变量的值。如上所述可知,当系统的时钟节拍(system tick)为1ms时,CurMSec就是毫秒级的计数器,GetTickCount()的精度就不会超过1ms。

         在时钟中断处理函数(TimerISR)中除了要更新CurMSec,还要根据dwReschedTime来判断是否到了运行调度程序的时间:

if ((int)(CurMSec - dwReschedTime) >= 0) sysIntr = SYSINTR_RESCHED;

      3) curridlehigh, curridlelow, idleconv
         这几个变量实现了一个64位的计数器,反映了系统处于空闲模式(Idle mode)的时间。一般在OEMIdle()函数内更新。用户程序通过调用GetIdleTime()函数可以得到这个值。

         这里再插入一些与OEMIdle有关的知识点:

         调度算法与电源管理有紧密的联系,也就是与现阶段中央提倡的节能减排有一定的联系因为绝大多数的移动设备都是希望节能的,所以当所有线程处于阻塞状态时,内核就会通过调用OEMIdle()将CPU置于空闲模式(低功耗状态)。这种状态直到有中断发生或者有线程可运行时为止。实际上,许多设备都是要花大量时间等待用户的输入,因此如果CPU支持低功耗模式,就应该在OEMIdle函数中实现之。

         如果不采用前面提到的那个新的调度程序特性(Variable Tick Scheduler),在OEMIdle函数中还需要判断Idle的准确时间段,而可变的系统时间节拍可以事先设置好正确的时钟中断,这样OEMIdle函数就可以更快的将CPU置于低功耗状态,这也就是说它节能的理由。

         有时需要计算一段程序运行时的CPU占用率,可以使用如下代码:

dwStartTick = GetTickCount();
dwIdleSt = GetIdleTime();
Sleep(); // 被测代码段
dwStopTick = GetTickCount();
dwIdleEd = GetIdleTime();
PercentIdle = ((100*(dwIdleEd - dwIdleSt)) / (dwStopTick - dwStartTick));

         这段代码见MSDN中GetIdleTime一节,1-PercentIdle即为CPU占用率。

2. 系统时钟模块结构

         这篇文章是以PQOAL(Production-Quality OAL)结构介绍系统时钟模块的实现,PQOAL是WinCE 5.0开始才有的东东,它可以简化OAL代码的实现,并有利于OAL代码的移植。简单分析一下目录结构:
         %_WINCEROOT%/Platform/Common 为硬件无关以及CPU相关的PQOAL代码;
         %_WINCEROOT%/Platform/Common/Src/Common 为硬件无关的代码,下面以黄色背景列举这类函数;
         %_WINCEROOT%/Platform/Common/Src/$CPU$   为CPU相关代码,下面以绿色背景列举这类函数。

         如果你的平台所采用的CPU在这个目录中已经存在,比如pxa270相关代码就在%_WINCEROOT%/Platform/Common/Src/ARM/Intel/PXA27x目录下,一般情况下不需要做任何修改,这些代码就可以完成大部分OAL的功能。单就pxa270的系统时钟模块而言,不需要自己写任何代码也可以使用,但这部分代码其实没有实现WinCE 5.0才有的那个新特性(Variable Tick Scheduler)。尤其是OALCPUIdle()的默认实现只是简单的循环,最好能自行实现这个函数,使CPU置于低功耗状态。

         在OAL中,与系统时钟相关的数据结构,变量和函数接口在Oal_timer.h头文件中都有其定义或者注释。
(%_WINCEROOT%/Platform/Common/Src/Inc/Oal_timer.h)


2.1 与内核进行交互的变量和函数

      2.1.1 UINT32 OALTimerIntrHandler();
          这个就是前面提到的TimerISR,即时钟中断处理函数,返回一个SYSINTR_的值。

      2.1.2 CurMSec,前面已经提到,定义在内核源文件中。

       2.1.3 OEMIdle(),前面已经提到,已有PQOAL实现,其内部会调用OALCPUIdle()将CPU置于空闲模式(低功耗状态)。

       2.1.4 SC_GetTickCount()
       这个是内核需要的毫秒级定时器,返回从系统启动开始算起的毫秒数。如果系统时钟节拍为1ms,那么直接返回CurMSec即可,否则如果系统时钟节拍超过1ms,则需要高精度计数器来调整到一个毫秒的时间间隔。
       该函数已经由PQOAL实现,但它会调用与硬件相关的函数OALTimerCountsSinceSysTick()。

       2.1.5 pQueryPerformanceFrequency, pQueryPerformanceCounter
       内核中定义的函数指针,通过这两个函数实现高精度的计时器。
       这两个函数的原型也已经由PQOAL实现,即OALTimerQueryPerformanceFrequency和OALTimerQueryPerformanceCounter,也会调用与硬件相关的函数OALTimerCountsSinceSysTick()和OAL层变量g_oalTimer。

       2.1.6 pOEMUpdateRescheduleTime
       内核中定义的函数指针,如果要采用Variable Tick Scheduler就有必要实现这个函数,主要是根据变化了的系统节拍(tick)重新设置时钟的定时周期,从而避免不必要的时钟中断。
       PQOAL提供了OALTimerUpdateRescheduleTime函数的例子可以参考实现,它会调用与硬件相关的函数OALTimerUpdate()。

 

2.2 与其他OAL模块交互的变量和函数

      2.2.1 OALTimerInit()
      这个函数用来初始化系统时钟,通常是在OEMInit函数中调用。具体包括初始化OAL层变量g_oalTimer,初始化内核变量curridlehigh, curridlelow, idleconv,初始化内核函数指针(2.1.5,2.1.6),初始化硬件时钟定时器。

      2.2.2 g_oalTimer,OAL_TIMER_STATE结构的变量,包含各种系统时钟相关的变量。

typedef struct {
    UINT32 countsPerMSec
;                                // counts per 1 msec

    UINT32 countsMargin;                                // counts margin
    UINT32 maxPeriodMSec;                                // maximal timer period in MSec
    UINT32 msecPerSysTick;                            // msec per system tick
    UINT32 countsPerSysTick;                        // counts per system tick
    UINT32 actualMSecPerSysTick;                // actual msec per system tick
    UINT32 actualCountsPerSysTick;            // actual counts per system tick
    volatile UINT64 curCounts;                    // counts at last system tick
} OAL_TIMER_STATE, *POAL_TIMER_STATE;

      2.2.3 OALTimerCountsSinceSysTick()
      这个函数使用高精度计数器返回从上一次系统嘀哒后经过的时间,一般需要精度高于1ms,换句话说,硬件时钟的晶振频率要高于1MHz。

      2.2.4 OALTimerUpdateRescheduleTime(),参见2.1.6

      2.2.5
OALTimerRecharge(),OALTimerUpdate(),OALStall()

      2.2.6 OALGetTickCount()


3. 实现高精度定时器

         
有时用户程序希望调用QueryPerformanceCounter()和QueryPerformanceFrequency()实现精度高于1ms的计时。按照2.1.5所述,PQOAL已经基本实现了这部分代码,我们只需根据所采用的CPU实现OALTimerCountsSinceSysTick(2.2.3)。

         PXA270处理器有两组时钟通道,允许通过软件设置时钟中断,他们被称作操作系统时钟(Operating System Timer),详细内容请参考《Intel PXA27x Processor Family Developer's Manual》。

         这里只介绍一组与PXA255兼容的时钟通道,它采用3.25M晶振,即每毫秒可以计数3250次,有了它就可以实现精度高于1ms的计时器。
INT32 OALTimerCountsSinceSysTick()
{
    UINT32 LastTimerMatch 
= (g_XllpOSTHandle.pOSTRegs->osmr0 - g_oalTimer.countsPerSysTick);

    // How many ticks since the last timer interrupt?

    return (g_XllpOSTHandle.pOSTRegs->oscr0 - LastTimerMatch)
;
}
wince环境下的时钟软件 时钟软件,可在导航仪等wince设备上直接运行。车上的导航仪可以看时间,闲置的导航仪可以当时钟。 立即下载

相关推荐

wince系统时间显示

wince系统时间显示,请大家指教,适合新手

【转】OAL之系统时钟

1. 系统时钟与内核的关系 WinCE 5.0采用基于时间片的抢占式多任务的实时内核,而且每个线程可以根据需要自行设定线程时间片的大小(参考CeSetThreadQuantum函数),默认为100ms,这个默认值dwDefaultThreadQuantum也可以在OEMInit()时自行设定。在内核源文件中,与单词Quantum有关的变量名一般是指时间片,WinCE内核定...

weixin_30421525的博客 115

WINCE 5.0 ,6.0 ,7.0 应用程序自动更新源代码

真正实现通过配置文件实现WINCE APP 自动更新的通用程序 要点: 1,UPDATELIST 文件第一行为服务器下载文件夹虚拟路径 2,UPDATELIST 文件第二行为本地APP程序 3,需要在SHSAN.EXE 所在文件夹建立temp 子文件夹

OAL时钟与内核

Jasons ScribbleOAL之系统时钟 1. 系统时钟与内核的关系 WinCE 5.0采用基于时间片的抢占式多任务的实时内核,而且每个线程可以根据需要自行设定线程时间片的大小(参考CeSetThreadQuantum函数),默认为100ms,这个默认值dwDefaultThreadQuantum也可以在OEMInit()时自行设定。在内核源文件中,与单词Qu

在水一方 1301

自己写的wince的小程序,给初学者使用学习

一个嵌入式开发的wince小程序,使用.net框架下的c#写的,可以给初学者学习使用,高手不要喷!

win ce 6.0 时钟插件

win ce 6.0 下可以运行的时钟插件

系统时钟

1. 系统时钟与内核的关系        WinCE5.0采用基于时间片的抢占式多任务的实时内核,而且每个线程可以根据需要自行设定线程时间片的大小(参考CeSetThreadQuantum函数),默认为100ms,这个默认值dwDefaultThreadQuantum也可以在OEMInit()时自行设定。在内核源文件中,与单词Quantum有关的变量名一般是指时间片,W

laura0502的专栏 3755

wince平台下的时钟

在wince平台下,用qt开发一款时钟界面

OAL点点滴滴(二)(转)

正如CE的帮助文档所言,创建OAL是一个非常复杂的任务,而通常的办法是复制原有的相同平台的OAL代码,然后修改来适应平台的特殊要求。也就是说对于没有特殊要求的平台,复制原有相同平台的OAL代码就足够了。由于OAL的复杂性在这篇文...

cuankuangzhong6373的博客 382

一个比较好用的时钟工具

用于桌面演示等工作时的时间提醒,有定时关机等功能,使用很方便,绿色版,启动设置一下就可以了

WINCE (WINCE5.0 WINCE 6.0) 简单使用的数码时钟 超大字体 导航仪废物利用做时钟

WINCE (WINCE5.0 WINCE 6.0) 简单使用的数码时钟 超大字体 导航仪废物利用做时钟 网上找了好多WINCE的时钟都不满意 后面干脆自己架设WINCE的开发环境,自己用VB编了一个简单实用的

WinCE OAL中的OEMIoControl函数

WinCE OAL中的OEMIoControl函数来自于:http://space.itpub.net/16912323/viewspace-591517作者:唐勉_itpub关于OEMIoControl函数,我在2008年1月份写过一篇blog叫“WinCE BSP中OAL层中的OEMIoControl介绍”,已经比较详细的介绍了OEMIoControl,今天在这里只是对OEMI

阶廷成长日记 803

从TM1到TM9:手把手教你用Wireshark抓包分析LTE下行调度与传输模式切换

本文详细解析了如何使用Wireshark抓包分析LTE下行调度中的传输模式切换,从TM1到TM9的动态调整过程。通过实战案例,包括小区边缘移动、高速场景和多用户调度,揭示eNodeB如何基于信道质量指标(如RSRP、SINR)动态切换传输模式,并提供关键信令解析和优化建议,助力网络工程师提升LTE网络性能。

weixin_42651748的博客 316

WinCE中OEM适配层编程点滴之创建OAL

[资料来源] :http://motion.chinaitlab.com/WINCE/30568.html不知道这篇文章的作者是谁,这些网站似乎很是不负责任,连作者的名字都不留,过分 正如CE的帮助文档所言,创建OAL是一个非常复杂的任务,而通常的办法是复制原有的相同平台的OAL代码,然后修改来适应平台的特殊要求。也就是说对于没有特殊要求的平台,复制原有相同平台的OAL代码就足够了。由

1018

从Reset到Read:深入解析Rolling Shutter曝光流水线

本文深入解析Rolling Shutter(卷帘曝光)的工作原理,重点探讨Reset和Read信号在图像传感器中的关键作用。通过Reset-Read流水线机制,详细解释了曝光控制、时序调优及运动伪影补偿等核心技术,帮助读者理解卷帘曝光在高速摄影和动态场景中的应用。

weixin_42531925的博客 255

CentOS7下通过YUM源高效部署Zabbix7 Agent指南

本文详细指导在已结束生命周期的CentOS7系统上,通过更换YUM源(如阿里云镜像)并添加Zabbix官方仓库,高效部署Zabbix7 Agent。文章涵盖从源配置、软件安装、关键参数修改到服务启动与防火墙设置的全流程,帮助用户解决依赖错误,快速建立服务器监控。

weixin_29230059的博客 270
上一篇: WinCE驱动开发问题精华集锦
下一篇: 蓝牙技术及其系统原理
普通网友
普通网友 领域专家: 编程技术技术领域 领域专家: 编程技术技术领域
博客等级 码龄25年 2837粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值