如何在Linux内核驱动中使用ARM全局计时器读取计数值?
读取ARM全局计时器计数值的实现方法
你提到的_gt_counter_read()和gt_counter_read()都是静态函数,仅在arm_global_timer.c文件内部可见,且未通过EXPORT_SYMBOL系列宏导出,内核模块无法直接调用这类私有函数。正确的做法是通过Linux内核的clocksource框架来访问全局计时器的读取接口,具体实现如下:
核心思路
ARM全局计时器驱动会向内核注册一个clocksource结构体实例,其中的read成员函数就是封装了底层计数值读取逻辑的官方接口。我们只需要找到这个实例,就能调用它的read方法获取计数值。
具体代码实现
#include <linux/clocksource.h> #include <linux/module.h> #include <linux/init.h> static struct clocksource *arm_gt_cs; static int __init arm_gt_read_init(void) { struct clocksource *cs; // 遍历系统中所有注册的clocksource,匹配ARM全局计时器 list_for_each_entry(cs, &clocksource_list, list) { if (!strcmp(cs->name, "arm_global_timer")) { arm_gt_cs = cs; break; } } if (!arm_gt_cs) { pr_err("Failed to locate ARM global timer clocksource\n"); return -ENODEV; } // 读取并打印计数值 u64 counter = arm_gt_cs->read(arm_gt_cs); pr_info("ARM global timer counter: %llu\n", counter); return 0; } static void __exit arm_gt_read_exit(void) { arm_gt_cs = NULL; } module_init(arm_gt_read_init); module_exit(arm_gt_read_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ARM Global Timer Counter Reader"); MODULE_AUTHOR("Your Name");
关键细节说明
clocksource_list是内核维护的全局链表,存储了所有已注册的clocksource实例,遍历它即可找到目标计时器。- 对于ARM全局计时器来说,
clocksource的read方法内部就是调用了你提到的gt_counter_read()函数,效果完全等价于直接调用私有静态函数。 - 在4.19版本内核中,
clocksource_list是全局可见的,可以直接遍历;若后续内核版本对其访问做了限制,可能需要调整,但你的目标版本无需担心。
编译与加载注意事项
- 编译模块时需使用对应4.19内核的头文件和配置参数。
- 加载模块需要root权限,且系统内核已开启
CONFIG_ARM_GLOBAL_TIMER配置(即ARM全局计时器驱动已启用)。
内容的提问来源于stack exchange,提问作者dczanella
相关产品推荐
相关产品推荐

