1# 时间管理 2 3 4## 基本概念 5 6时间管理以系统时钟为基础,给应用程序提供所有和时间有关的服务。 7 8系统时钟是由定时器/计数器产生的输出脉冲触发中断产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。 9 10用户以秒、毫秒为单位计时,而操作系统以Tick为单位计时,当用户需要对系统进行操作时,例如任务挂起、延时等,此时需要时间管理模块对Tick和秒/毫秒进行转换。 11 12OpenHarmony LiteOS-M内核时间管理模块提供时间转换、统计功能。 13 14 15## 时间单位 16 17- Cycle 18 系统最小的计时单位。Cycle的时长由系统主时钟频率决定,系统主时钟频率就是每秒钟的Cycle数。 19 20- Tick 21 Tick是操作系统的基本时间单位,由用户配置的每秒Tick数决定。 22 23 24## 接口说明 25 26OpenHarmony LiteOS-M内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 27 28 **表1** 时间转换 29 30| 接口名 | 描述 | 31| -------- | -------- | 32| LOS_MS2Tick | 毫秒转换成Tick。 | 33| LOS_Tick2MS | Tick转化为毫秒。 | 34| OsCpuTick2MS | Cycle数目转化为毫秒,使用2个UINT32类型的数值分别表示结果数值的高、低32位。 | 35| OsCpuTick2US | Cycle数目转化为微秒,使用2个UINT32类型的数值分别表示结果数值的高、低32位。 | 36 37 **表2** 时间统计 38 39| 接口名 | 描述 | 40| -------- | -------- | 41| LOS_SysClockGet | 获取系统时钟。 | 42| LOS_TickCountGet | 获取自系统启动以来的Tick数。 | 43| LOS_CyclePerTickGet | 获取每个Tick多少Cycle数。 | 44| LOS_CurrNanosec | 获取当前的时间,单位纳秒。 | 45 46 **表3** 时间注册 47 48| 接口名 | 描述 | 49| --------------------- | ---------------------------------------------- | 50| LOS_TickTimerRegister | 重新注册系统时钟的定时器和对应的中断处理函数。 | 51 52 **表4** 延时 53 54| 接口名 | 描述 | 55| ---------- | ------------------------ | 56| LOS_MDelay | 延时函数,延时单位毫秒。 | 57| LOS_UDelay | 延时函数,延时单位微秒。 | 58 59## 开发流程 60 61时间管理的典型开发流程: 62 631. 根据实际需求,完成板级配置适配,并配置系统主时钟频率OS_SYS_CLOCK(单位Hz)和LOSCFG_BASE_CORE_TICK_PER_SECOND。OS_SYS_CLOCK的默认值基于硬件平台配置。 64 652. 调用时钟转换/统计接口。 66 67> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** 68> - 时间管理不是单独的功能模块,依赖于OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。 69> 70> - 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。 71> 72> - 上文描述的配置选项维护在开发板工程 target_config.h 中,部分配置项未定义的缺省值定义在内核 los_config.h中。 73 74 75## 编程实例 76 77 78### 实例描述 79 80在下面的例子中,介绍了时间管理的基本方法,包括: 81 821. 时间转换:将毫秒数转换为Tick数,或将Tick数转换为毫秒数。 83 842. 时间统计:每Tick的Cycle数、自系统启动以来的Tick数和延迟后的Tick数。 85 86 87### 示例代码 88 89前提条件: 90 91- 使用每秒的Tick数LOSCFG_BASE_CORE_TICK_PER_SECOND的默认值100。 92 93- 配好OS_SYS_CLOCK系统主时钟频率。 94 95时间转换: 96 97本演示代码在 ./kernel/liteos_m/testsuites/src/osTest.c 中编译验证,在TestTaskEntry中调用验证入口函数ExampleTransformTime和ExampleGetTime。 98 99 100``` 101VOID ExampleTransformTime(VOID) 102{ 103 UINT32 ms; 104 UINT32 tick; 105 106 /* 10000ms转换为tick */ 107 tick = LOS_MS2Tick(10000); 108 printf("tick = %d \n", tick); 109 110 /* 100tick转换为ms */ 111 ms = LOS_Tick2MS(100); 112 printf("ms = %d \n", ms); 113} 114``` 115 116时间统计和时间延迟: 117 118 119``` 120VOID ExampleGetTime(VOID) 121{ 122 UINT32 cyclePerTick; 123 UINT64 tickCountBefore; 124 UINT64 tickCountAfter; 125 126 cyclePerTick = LOS_CyclePerTickGet(); 127 if (0 != cyclePerTick) { 128 printf("LOS_CyclePerTickGet = %d \n", cyclePerTick); 129 } 130 131 tickCountBefore = LOS_TickCountGet(); 132 LOS_TaskDelay(200); 133 tickCountAfter = LOS_TickCountGet(); 134 printf("LOS_TickCountGet after delay rising = %d \n", (UINT32)(tickCountAfter - tickCountBefore)); 135} 136``` 137 138 139### 结果验证 140 141编译运行得到的结果为: 142 143时间转换: 144 145 146``` 147tick = 1000 148ms = 1000 149``` 150 151时间统计和时间延迟: 152 153 154``` 155LOS_CyclePerTickGet = 250000 (根据实际运行环境,数据会有差异) 156LOS_TickCountGet after delay rising = 200 157``` 158