概述
系统tick变量
SylixOS中对心跳中断计数的是一个64位原子量变量,心跳周期一般是1到10毫秒,64位计数可以认为永远不会溢出。
类型定义
#ifdef __GNUC__
typedef struct {
volatile INT64 __attribute__((aligned(8))) counter;
} atomic64_t;
#else
typedef struct {
volatile INT64 counter;
} atomic64_t;
#endif
变量定义
位于libsylixosSylixOSkernelincludek_globalvar.h文件中
_KERNEL_EXT atomic64_t _K_atomic64KernelTime; /* 系统时间计数器 */
内核宏接口
更新接口
每调用一次TICK_UPDATE宏接口,心跳计数加一。
#if LW_CFG_CPU_ATOMIC64_EN > 0
#define TICK_UPDATE()
do {
__LW_ATOMIC64_INC(&_K_atomic64KernelTime);
} while (0)
#else /* LW_CFG_CPU_ATOMIC64_EN */
#define TICK_UPDATE()
do {
_K_atomic64KernelTime.counter++;
} while (0)
#endif
读取接口:
__KERNEL_TIME_GET_NO_SPINLOCK(time, type) //无SPINLOCK保护
__KERNEL_TIME_GET(time, type) //带保护的实现
系统当前tick计数是通过一个64位原子量记录的,这两个宏都是要获取这个数值。
如果目标CPU支持64位原子量操作,则之间通过原子量接口获取,两个接口的实现是完全一样的,都能保证数据的完整性。
如果目标CPU不支持64位原子量操作,__KERNEL_TIME_GET_NO_SPINLOCK是直接赋值的不保证数据的完整性,__KERNEL_TIME_GET则是通过自旋锁保护实现的,能保证数据的完整性。
实现源码如下:
#if LW_CFG_CPU_ATOMIC64_EN > 0
#define __KERNEL_TIME_GET_NO_SPINLOCK(time, type)
{
time = (type)__LW_ATOMIC64_GET(&_K_atomic64KernelTime);
}
#define __KERNEL_TIME_GET(time, type)
__KERNEL_TIME_GET_NO_SPINLOCK(time, type)
#else /* LW_CFG_CPU_ATOMIC64_EN */
#define __KERNEL_TIME_GET_NO_SPINLOCK(time, type)
{
time = (type)_K_atomic64KernelTime.counter;
}
#define __KERNEL_TIME_GET(time, type)
{
INTREG iregInterLevel;
LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
time = (type)_K_atomic64KernelTime.counter;
LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
}
#endif
系统当前tick计数_K_atomic64KernelTime.counter是单调递增的,只可能在tick中断中增加,其他地方都是读取。对于tick计数的读取,内核大部分是调用的__KERNEL_TIME_GET_NO_SPINLOCK接口,个别会直接读取_K_atomic64KernelTime.counter,少数会调用__KERNEL_TIME_GET接口。
心跳频率接口
初始化定时器,计算时间,或时间类型转换都要用到心跳频率,系统提供了一个接口LW_TICK_HZ,其本质是个变量,该值会被系统同启动参数中的hz
选项初始化为相应的值。
#define LW_TICK_HZ _K_timingKernel.TIMING_ulTickHz
内核函数接口
- API_TimeGetFrequency:获取心跳中断频率,基于LW_TICK_HZ宏实现。
- API_TimeGet:获取当前心跳计数,基于__KERNEL_TIME_GET宏实现。
- API_TimeGet64:以64位形式获取当前心跳计数,,基于__KERNEL_TIME_GET宏实现。
- API_TimeSet:设置心跳计数值。心跳计数是单调递增的,不允许修改,该函数固定返回错误。
宏定义别名接口:
#define Lw_Time_Set API_TimeSet
#define Lw_Time_Get API_TimeGet
#define Lw_Time_Get64 API_TimeGet64
#define Lw_Time_GetFrequency API_TimeGetFrequency
实现源码位于libsylixosSylixOSkernelinterfaceTimeGet.c文件中,如下:
/*********************************************************************************************************
** 函数名称: API_TimeGetFrequency
** 功能描述: 获得系统时间频率
** 输 入 :
** 输 出 : 系统时间频率
*********************************************************************************************************/
LW_API ULONG API_TimeGetFrequency (VOID)
{
return (LW_TICK_HZ);
}
/*********************************************************************************************************
** 函数名称: API_TimeGet
** 功能描述: 获得系统时间
** 输 入 :
** 输 出 : 系统时间
*********************************************************************************************************/
LW_API ULONG API_TimeGet (VOID)
{
ULONG ulTime;
__KERNEL_TIME_GET(ulTime, ULONG);
return (ulTime);
}
/*********************************************************************************************************
** 函数名称: API_TimeGet64
** 功能描述: 获得系统时间
** 输 入 :
** 输 出 : 系统时间
*********************************************************************************************************/
LW_API INT64 API_TimeGet64 (VOID)
{
INT64 i64Time;
__KERNEL_TIME_GET(i64Time, INT64);
return (i64Time);
}
/*********************************************************************************************************
** 函数名称: API_TimeSet
** 功能描述: 设置系统时间
** 输 入 : ulKernenlTime 系统时间
** 输 出 :
*********************************************************************************************************/
LW_API VOID API_TimeSet (ULONG ulKernenlTime)
{
_ErrorHandle(ERROR_KERNEL_RUNNING);
return;
}
下面的例子通过以上函数获取系统已经运行了多长时间。
#include <SylixOS.h>
int main (int argc, char *argv[])
{
ULONG ulUsecPerTick;
ULONG ulMsecTotal;
ulUsecPerTick = 1000000 / Lw_Time_GetFrequency();
ulMsecTotal = Lw_Time_Get () * ulUsecPerTick / 1000;
printf("system has run for %lu ms.n", ulMsecTotal);
return (0);
}
最后
以上就是优雅牛排为你收集整理的SylixOS里的时间【1】--- 系统tick接口系统tick变量内核宏接口内核函数接口的全部内容,希望文章能够帮你解决SylixOS里的时间【1】--- 系统tick接口系统tick变量内核宏接口内核函数接口所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复