我尝试在内核版本为 5.0.0-38-generic 的 Linux Ubuntu 19.04 机器上从 Pleora eBUS SDK 编译一些内核模块,但出现编译错误:
error: implicit declaration of function ‘current_kernel_time’; did you mean ‘core_kernel_text’? [-Werror=implicit-function-declaration]
lTime = current_kernel_time();
Run Code Online (Sandbox Code Playgroud)
和另一个(相同的问题) function do_gettimeofday。
我注意到了这一点,current_kernel_time并且current_kernel_time64在内核 v4.15 中仍然可用(例如,我的另一台机器使用 Ubuntu 18.04),最后一次出现在linux v4.19.97 中。在我的内核版本的time.h标头中,有一个函数get_timespec64似乎在做类似的事情,但是它接受 2 个参数,对我来说似乎不正确(因为在我看到的来源中,有一个copy_from_user被调用的)传递一些未初始化const struct __kernel_timespec __user *uts为第二个参数。有人可以给我一些提示如何current_kernel_time在我的较新内核版本中替换对 的调用吗?
需要修改的示例代码:
OS_UINT64 OS_TimeGetUS( OS_VOID )
{
struct timespec64 lTime;
lTime = current_kernel_time();
return ( lTime.tv_sec * 1000000 + OS_DIV64( lTime.tv_nsec, 1000 ) );
}
Run Code Online (Sandbox Code Playgroud)
该current_kernel_time()函数被弃用并移至timekeeping32.hv4.15 ( commit ),然后在 v4.20 ( commit ) 中完全删除。v4.18 ( commit )中引入了较新的计时功能。
新导出的函数是(source):
extern void ktime_get_raw_ts64(struct timespec64 *ts);
extern void ktime_get_ts64(struct timespec64 *ts);
extern void ktime_get_real_ts64(struct timespec64 *tv);
extern void ktime_get_coarse_ts64(struct timespec64 *ts);
extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
Run Code Online (Sandbox Code Playgroud)
另请参阅相关的内核文档页面,其中指出:
不推荐使用的时间接口
[...]
Run Code Online (Sandbox Code Playgroud)struct timespec current_kernel_time(void) struct timespec64 current_kernel_time64(void) struct timespec get_monotonic_coarse(void) struct timespec64 get_monotonic_coarse64(void)这些由
ktime_get_coarse_real_ts64()和代替ktime_get_coarse_ts64()。然而,许多需要粗粒度时间的代码可以使用简单的“jiffies”来代替,而现在一些驱动程序实际上可能需要更高分辨率的访问器。
您可以将代码重写为:
OS_UINT64 OS_TimeGetUS( OS_VOID )
{
struct timespec64 lTime;
ktime_get_coarse_real_ts64(&lTime);
return (lTime.tv_sec * 1000000 + OS_DIV64( lTime.tv_nsec, 1000 ) );
}
Run Code Online (Sandbox Code Playgroud)
但是我看到您以微秒为单位返回时间。在这种情况下,您可能希望直接使用ktime_t ktime_get(void)或等效的u64 ktime_get_ns(void). 您提供的代码片段可以重写为:
OS_UINT64 OS_TimeGetUS( OS_VOID )
{
return OS_DIV64(ktime_get_ns(), 1000);
}
Run Code Online (Sandbox Code Playgroud)