第19篇 zephyr 时钟之Kernel Clocks

目录

摘要

1 概念

2 应用

2.1 以正常的精度测量时间(基于tick的)

2.2 高精度测量时间

3 参考链接


本学笔记基于zephyr 工程版本 2.2.99,主机环境为ubuntu18.04,开发平台 nrf52840dk_nrf52840

摘要

内核的时钟是所有基于时间的服务的基础。

1 概念

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

  • 32位硬件时钟是一个高精度的计数器,它以未指定的单位(称为周期)跟踪时间。周期的持续时间由内核使用的板级硬件决定,通常以纳秒为单位。
  • 64位系统时钟是一个计数器,它记录了内核初始化后经过的节拍数。节拍的持续时间是可配置的,通常从1毫秒到100毫秒不等。学过操作系统原理的应该都理解这个tick时钟,他是整个系统的心跳。

内核还提供了一些变量,可用于将时钟使用的时间单位转换为标准时间单位(例如秒、毫秒、纳秒等),并在两种类型之间可以相互转换。

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

硬件时钟可以比基于系统时钟的内核服务提供的时间测量精度更高。

系统时钟的滴答计数来自硬件时钟的周期计数。内核确定有多少个时钟周期对应于所需的时钟频率,然后对硬件时钟进行编程,在多个周期之后生成一个中断;每个中断对应一个tick。

配置更小的tick持续时间允许更细粒度的定时,但是也增加了内核处理tick中断的工作量,因为这些中断发生得更频繁。将时钟周期设置为零将禁用内核时钟及其相关服务。

2 应用

2.1 以正常的精度测量时间(基于tick的)

下面的代码,使用系统时钟(tick)来确定两个时间点之间经过了多少时间:

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);

2.2 高精度测量时间

下面的代码使用硬件时钟来确定两个时间点之间的时间间隔:

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 = (u32_t)k_cyc_to_ns_floor64(cycles_spent);

3 参考链接

https://docs.zephyrproject.org/latest/reference/kernel/timing/clocks.html

你可能感兴趣的:(zephyr,zephyr,物联网,BLE,NRF52840,内核时钟)