前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zephyr笔记 2.2.1 内核时钟

zephyr笔记 2.2.1 内核时钟

作者头像
twowinter
发布2020-04-17 10:46:26
9180
发布2020-04-17 10:46:26
举报
文章被收录于专栏:twowinter

1 前言

我正在学习 Zephyr,一个很可能会用到很多物联网设备上的操作系统,如果你也感兴趣,可点此查看帖子zephyr学习笔记汇总

2 概念

内核支持两个不同的时钟。

  • 32位硬件时钟是一个高精度计数器,可以跟踪若干个周期时间,但这个周期不能指定单位。一个周期的持续时间取决于内核使用的电路板硬件,通常以纳秒为单位进行测量。
  • 64位系统时钟是一个计数器,用于跟踪自内核初始化以来已经过的tick数。tick的持续时间是可配置的,通常范围从1毫秒到100毫秒。

内核还提供了许多变量,可用于将时钟使用的时间单位转换为标准时间单位(例如秒,毫秒,纳秒等),并在两种时钟时间单位之间进行转换。

大多数内核基于时间的服务都使用系统时钟,包括内核计时器对象和其他内核对象类型支持的超时。 为方便起见,内核的API允许以毫秒为单位指定持续时间,并自动将它们转换为相应的tick数。

硬件时钟可用于高精度的测量事务,因为它比内核系统时钟的精度更高。

2.1 时钟限制

系统时钟的tick计数来自硬件时钟的周期计数。内核计算出tick频率需要多少个硬件时钟周期,然后编程在多个硬件时钟周期后产生中断; 每个中断对应于一个tick。

代码语言:javascript
复制
注意:配置较小的时间间隔允许更细粒度的时序,但也会增加内核处理时钟中断所需的工作量,因为它们会更频繁地发生。 将滴答持续时间设置为零将禁用内核时钟及其相关服务。

使用内核API进行任何毫秒级别间隔的请求,都将发生最小延迟,实际上可能会比所请求的时间长的时间。

例如,当占用信号量时,要进行100 ms的占用请求,意味着内核不会在 100 ms过去之前终止操作以及报告故障。 但是,操作可能需要超过100毫秒才能完成,并且可能在附加时间内成功完成或者失败。

内核对象操作期间会产生附件时间,发生的附加时间量取决于以下因素。

  • 从毫秒转换为tick时,通过四舍五入指定的时间间隔引入附加时间。 例如,如果使用10毫秒的时间间隔,则25毫秒的指定延迟将四舍五入至30毫秒。
  • 延迟时,只有等到下一个有效中断到来时才能开始进行有效地追踪,这样便引入了延迟。例如,如果正在使用 10 ms 的tick间隔,则 20 ms 的指定延迟要求内核等待3个时间片发生(而不是仅仅发生2个时间片),因为第一个tick可能发生在 0-10 ms之间,只有等第一个tick发生后,内核才能知道接下来的2个 tick 消耗 20ms。

3 操作

3.1 用正常精度测量时间

此代码使用系统时钟来确定两个时间点之间经过的时间。

代码语言:javascript
复制
s64_t time_stamp;
s64_t milliseconds_spent;

/* capture initial time stamp */
time_stamp = k_uptime_get();

/* do work for some (extended) period of time */
...

/* compute how long the work took (also updates the time stamp) */
milliseconds_spent = k_uptime_delta(&time_stamp);

3.2 高精度测量时间

此代码使用硬件时钟来确定两个时间点之间经过的时间。

代码语言:javascript
复制
u32_t start_time;
u32_t stop_time;
u32_t cycles_spent;
u32_t nanoseconds_spent;

/* capture initial time stamp */
start_time = k_cycle_get_32();

/* do work for some (short) period of time */
...

/* capture final time stamp */
stop_time = k_cycle_get_32();

/* compute how long the work took (assumes no counter rollover) */
cycles_spent = stop_time - start_time;
nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(cycles_spent);

4 建议用法

使用基于系统时钟的服务进行基于时间的处理,不需要高精度,如定时器对象或线程睡眠

使用基于硬件时钟的服务进行基于时间的处理,这需要比系统时钟提供的精度更高的精度,例如忙等待)或细粒度时间测量。

代码语言:javascript
复制
注意:硬件时钟的高频率与32位数的大小紧密相关,意味着在进行长时间高精度测量时必须考虑计数器翻转的情况。

5 配置选项

代码语言:javascript
复制
CONFIG_SYS_CLOCK_TICKS_PER_SEC

6 API

下列时钟API,都在 kernel.h 中提供了:

代码语言:javascript
复制
k_uptime_get()
k_uptime_get_32()
k_uptime_delta()
k_uptime_delta_32()
k_cycle_get_32()
SYS_CLOCK_HW_CYCLES_TO_NS
K_NO_WAIT
K_MSEC
K_SECONDS
K_MINUTES
K_HOURS
K_FOREVER

End

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 前言
  • 2 概念
    • 2.1 时钟限制
    • 3 操作
      • 3.1 用正常精度测量时间
        • 3.2 高精度测量时间
        • 4 建议用法
        • 5 配置选项
        • 6 API
        • End
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档