How can I obtain battery level inside a Linux kernel module?

戏子无情 提交于 2019-11-29 17:09:53

问题


I am trying to get the battery level inside a Linux kernel module (the module is inserted via modprobe). I would ideally like to use a kernel API call to get the battery information. I have searched on the web for solutions, and I have also explored Linux kernel source and the source of program "acpi" by Michael Meskes for ideas.

These are some of the techniques I think I can use:

  1. Read and parse /proc/acpi/battery/BAT0/state and /proc/acpi/battery/BAT0/info
  2. Read from /sys/class/power_supply/BAT0/charge_now and charge_full with no parsing involved.
  3. I could try using the calls from Linux kernel source drivers/acpi/battery.c if I could figure out how to expose the interface. I would probably need the methods acpi_battery_get_status and acpi_battery_get_info
  4. I also noticed that inside drivers/acpi/sbs.c there's a method acpi_battery_read and right above it there is a comment saying "Driver Interface". This might be another way if anyone knows how to use this.

I assume that it is probably a bad idea to read files while inside a kernel module, but I am not exactly sure how those files map to kernel function calls, so it might be okay.

So, can you guys give me some suggestions/recommendations?

Edit: I included my solution in an answer below.


回答1:


I have found a solution that works for me. First of all make sure to #include < linux/power_supply.h >

Assuming you know the name of the battery, this code gives an example of how to get current battery capacity.

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



回答2:


Looking at the battery.c, sbs.c, I think you can call the interface API (acpi_battery_read, acpi_battery_get_state) in your LKM directly.
Did you try that so far?




回答3:


I have the same dilemma! :-\ If this is a hardware specific thing you'r doing, you could see if on your particular laptop you can detect the smart battery on the SMBus link or not. If you can, then you can just do i2c/SMBus calls from within your LKM. Most new systems (except some Fujitsu laptops) talk to an embedded controller instead, which ends up configuring the battery (through SMBus i suppose).... Try installing "lm-sensors" and see if it detects your smart battery. If so you should be able to talk directly to the battery (usually at i2c address 0xb).

If this isn't a hardware specific thing you're doing, then ignore what i said :)



来源:https://stackoverflow.com/questions/4858657/how-can-i-obtain-battery-level-inside-a-linux-kernel-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!