zoukankan      html  css  js  c++  java
  • liteos时间管理(九)

    1. 时间管理

    1.1 概述

    1.1.1 概念

    时间管理以系统时钟为基础。时间管理提供给应用程序所有和时间有关的服务。

    系统时钟是由定时/计数器产生的输出脉冲触发中断而产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。一个Tick的时长可以静态配置。

    用户是以秒、毫秒为单位计时,而芯片CPU的计时是以Tick为单位的,当用户需要对系统操作时,例如任务挂起、延时等,输入秒为单位的数值,此时需要时间管理模块对二者进行转换。

    Tick与秒之间的对应关系可以配置。

    Huawei LiteOS的时间管理模块提供时间转换、统计、延迟功能以满足用户对时间相关需求的实现。

    1.1.2 相关概念

    • Cycle

    系统最小的计时单位。 Cycle的时长由系统主频决定,系统主频就是每秒钟的Cycle数。

    • Tick
      Tick是操作系统的基本时间单位,对应的时长由系统主频及每秒Tick数决定,由用户配置。

    2. 开发指导

    2.1 使用场景

    用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系等。

    2.2 功能

    Huawei LiteOS系统中的时间管理主要提供以下两种功能:

    • 时间转换:根据主频实现CPU Tick数到毫秒、微秒的转换。
    • 时间统计:获取系统Tick数。
    功能分类 接口名 描述
    时间转换 LOS_MS2Tick 毫秒转换成Tick
    - LOS_Tick2MS Tick转化为毫秒
    时间统计 LOS_CyclePerTickGet 每个Tick多少Cycle数
    - LOS_TickCountGet 获取当前的Tick数

    2.3 时间管理错误码

    时间转换存在出错的可能性,需要返回对应的错误码,以便快速定位错误原因。

    序 号 定义 实际数值 描述 参考解决方案
    1 LOS_ERRNO_SYS_PTR_NULL 0x02000010 入参指针为空 检查入参,传入非空入参
    2 LOS_ERRNO_SYS_CLOCK_INVAILD 0x02000011 无效的系统时钟配置 在los_config.h配置有效的时钟
    3 LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVAILD 0x02000012 错误码暂时没有使用 错误码暂时没有使用
    4 LOS_ERRNO_SYS_PERIERRCOREID 0x02000013 错误码暂时没有使用 错误码暂时没有使用
    5 LOS_ERRNO_SYS_HOOK_IS_FULL 0x02000014 错误码暂时没有使用 错误码暂时没有使用

    2.4 开发流程

    时间管理的典型开发流程:

    1. 确认配置项LOSCFG_BASE_CORE_TICK_HW_TIME为YES开启状态。
      • 在los_config.h中配置每秒的Tick数LOSCFG_BASE_CORE_TICK_PER_SECOND;
    2. 调用时钟转换接口。
    3. 获取系统Tick数完成时间统计。
      • 通过LOS_TickCountGet获取全局g_ullTickCount。

    3. 注意事项

    • 获取系统Tick数需要在系统时钟使能之后。
    • 时间管理不是单独的功能模块,依赖于los_config.h中的OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。
    • 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间计算。

    4. 编程实例

    4.1 实例描述

    在下面的例子中,介绍了时间管理的基本方法,包括:

    1. 时间转换:将毫秒数转换为Tick数,或将Tick数转换为毫秒数。
    2. 时间统计和时间延迟:统计每秒的Cycle数、 Tick数和延迟后的Tick数。

    4.2 编程示例

    前提条件:

    • 配好LOSCFG_BASE_CORE_TICK_PER_SECOND每秒的Tick数。
    • 配好OS_SYS_CLOCK 系统时钟,单位: Hz。

    时间转换:

    VOID Example_TransformTime(VOID)
    {
        UINT32 uwMs;
        UINT32 uwTick;
        uwTick = LOS_MS2Tick(10000);//10000 ms数转换为Tick数
        printf("uwTick = %d 
    ",uwTick);
        uwMs= LOS_Tick2MS(100);//100 Tick数转换为ms数
        printf("uwMs = %d 
    ",uwMs);
    }
    

    时间统计和时间延迟:

    VOID Example_GetTime(VOID)
    {
        UINT32 uwcyclePerTick;
        UINT64 uwTickCount;
        uwcyclePerTick = LOS_CyclePerTickGet();//每个Tick多少Cycle数
        if(0 != uwcyclePerTick)
        {
             dprintf("LOS_CyclePerTickGet = %d 
    ", uwcyclePerTick);
        }
        uwTickCount = LOS_TickCountGet();//获取Tick数
        if(0 != uwTickCount)
        {
            dprintf("LOS_TickCountGet = %d 
    ", (UINT32)uwTickCount);
        }
        LOS_TaskDelay(200);//延迟200 Tick
        uwTickCount = LOS_TickCountGet();
        if(0 != uwTickCount)
        {
            dprintf("LOS_TickCountGet after delay = %d 
    ", (UINT32)uwTickCount);
        }
    }
    

    4.4 结果验证

    编译运行得到的结果为:

    时间转换:

    tick = 1000
    uwMs = 1000
    

    时间统计和时间延迟:

    LOS_CyclePerTickGet = 495000
    LOS_TickCountGet = 1
    LOS_TickCountGet after delay = 201
    
  • 相关阅读:
    MySQL创建数据库简单命令
    工作的本质是解决问题
    使用消息中间件时,如何保证消息仅仅被消费一次?
    缓存穿透了怎么办?
    MySQL 数据库的提速器-写缓存(Change Buffer)
    删库了,我们一定要跑路吗?
    做好一件事的三要素
    一分钟简单了解 JSON Web Token
    聊一聊 MySQL 中的数据编辑过程中涉及的两阶段提交
    聊一聊 MySQL 数据库中的那些锁
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/10960224.html
Copyright © 2011-2022 走看看