如何在Linux内核模块中获取电池电量?

15
我正在尝试在Linux内核模块中获取电池电量(通过modprobe插入模块)。我希望使用内核API调用来获取电池信息。我已在网络上寻找解决方案,并探索了Linux内核源代码和Michael Meskes的"acpi"程序源代码以获得更多想法。
这些是我认为可以使用的一些技术:
  1. 读取和解析/proc/acpi/battery/BAT0/state和/proc/acpi/battery/BAT0/info。
  2. 从/sys/class/power_supply/BAT0/charge_now和charge_full中读取,无需解析。
  3. 如果我能找出如何公开接口,我可以尝试使用来自Linux内核源代码drivers/acpi/battery.c的调用。我可能需要方法acpi_battery_get_status和acpi_battery_get_info。
  4. 我还注意到,在drivers/acpi/sbs.c内部有一个方法acpi_battery_read,并且在其上面有一个注释说"Driver Interface"。如果有人知道如何使用它,这可能是另一种方法。
我认为在内核模块内部读取文件可能不是个好主意,但我不确定这些文件如何映射到内核函数调用,所以这可能是可行的。
因此,你们能给我一些建议/推荐吗?
编辑:我在下面的答案中包含了我的解决方案。

你为什么想要这样做,确切地说? - Andy Grover
@Andy,这里涉及到一些电池电量相关的功能。 - razvanlupusoru
3个回答

11

我已经找到了一个对我有效的解决方案。首先确保包含 < linux/power_supply.h >。

假设你知道电池的名称,这段代码提供了一个示例,说明如何获取当前电池容量。

char name[]= "BAT0";
int result = 0;
struct power_supply *psy = power_supply_get_by_name(name);
union power_supply_propval chargenow, chargefull;
result = psy->get_property(psy,POWER_SUPPLY_PROP_CHARGE_NOW,&chargenow);
if(!result) {
    printk(KERN_INFO "The charge level is %d\n",chargenow.intval);
}
result = psy->get_property(psy,POWER_SUPPLY_PROP_CHARGE_FULL,&chargefull);
if(!result) {
    printk(KERN_INFO "The charge level is %d\n",chargefull.intval);
}

关于"linux-headers-4.4.0-146-generic","psy->get_property"无效,需要使用"power_supply_get_property"。 - Yuriy Chernyshov

0

从battery.c和sbs.c的角度来看,我认为你可以直接在你的LKM中调用接口API(acpi_battery_read、acpi_battery_get_state)。
你到目前为止尝试过这个吗?


我尝试通过在我的模块中使用extern声明来使用那些静态方法。然而,在模块加载时它们仍然未定义。我认为静态方法不能在定义它们的文件之外使用。虽然我想补充一下,这些静态方法存在于内核符号表中(我通过/proc/kallsyms观察到)。 - razvanlupusoru

0
我有同样的困惑!:-\ 如果这是一个硬件特定的事情,你可以看看在你特定的笔记本电脑上是否可以检测到SMBus链接上的智能电池。如果可以,那么你就可以从你的LKM中进行i2c/SMBus调用。大多数新系统(除了一些富士通笔记本电脑)都与嵌入式控制器通信,最终通过SMBus配置电池(我想)...... 尝试安装“lm-sensors”,看看它是否检测到您的智能电池。如果是这样,您应该能够直接与电池通信(通常在i2c地址0xb处)。

如果这不是你要做的硬件特定的事情,那么请忽略我说的话 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接