English 中文(简体)
How can I obtain battery level inside a Linux kernel module?
原标题:

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.

最佳回答

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
",chargenow.intval);
}
result = psy->get_property(psy,POWER_SUPPLY_PROP_CHARGE_FULL,&chargefull);
if(!result) {
    printk(KERN_INFO "The charge level is %d
",chargefull.intval);
}
问题回答

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?

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





相关问题
Signed executables under Linux

For security reasons, it is desirable to check the integrity of code before execution, avoiding tampered software by an attacker. So, my question is How to sign executable code and run only trusted ...

Relation between USB and PCI

I m bit confused by the following statement in linux device drivers book. http://www.linuxdriver.co.il/ldd3/ 13.2. USB and Sysfs To help understand what this long device path means, we describe ...

Configuring kernel

After create a new system call, how to update the kernel? I tried these lines, make-kpkg clean fakeroot make-kpkg -initrd -append-to-version=-custom kernel_image kernel_headers But Ubuntu asked me ...

热门标签