Как я могу получить уровень заряда батареи внутри модуля ядра Linux?

Я пытаюсь получить уровень заряда батареи внутри модуля ядра Linux (модуль вставляется через modprobe). В идеале я бы хотел использовать вызов API ядра для получения информации о батарее. Я искал в Интернете решения, и я также изучил источник ядра Linux и источник программы "acpi" Майкла Мескеса для идей.

Вот некоторые из тех методов, которые я могу использовать:

  • Прочитайте и проанализируйте /proc/acpi/battery/BAT0/state и /proc/acpi/battery/BAT0/info
  • Чтение из /sys/class/power_supply/BAT0/charge_now и charge_full без участия синтаксического анализа.
  • Я мог бы попытаться использовать вызовы из исходных драйверов ядра Linux/acpi/battery.c, если бы мог выяснить, как разоблачить интерфейс. Мне, вероятно, понадобятся методы acpi_battery_get_status и acpi_battery_get_info
  • Я также заметил, что внутри драйверов /acpi/sbs.c есть метод acpi_battery_read, и прямо над ним есть комментарий, говорящий "Интерфейс драйвера". Это может быть другим способом, если кто-то знает, как использовать это.

Я предполагаю, что, вероятно, плохая идея читать файлы во внутреннем модуле ядра, но я не совсем уверен, как эти файлы сопоставляются с функциями ядра, так что это может быть хорошо.

Итак, можете ли вы, ребята, дать мне несколько советов/рекомендаций?

Изменить: я включил свое решение в ответ ниже.

Ответы

Ответ 1

Я нашел решение, которое работает для меня. Прежде всего убедитесь, что #include < 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);
}

Ответ 2

Глядя на battery.c, sbs.c, я думаю, вы можете напрямую вызвать интерфейс API (acpi_battery_read, acpi_battery_get_state) в своем LKM.
Вы пробовали это до сих пор?

Ответ 3

У меня та же дилемма!: - \ Если это конкретная аппаратная особенность, которую вы делаете, вы можете увидеть, может ли на вашем конкретном ноутбуке обнаруживать смарт-батарею по ссылке SMBus или нет. Если вы можете, вы можете просто совершать звонки i2c/SMBus из своего LKM. Большинство новых систем (кроме некоторых ноутбуков Fujitsu) вместо этого используют встроенный контроллер, который в конечном итоге настраивает батарею (через SMBus, я полагаю).... Попробуйте установить "lm-sensors" и посмотреть, обнаруживает ли он ваш смарт-аккумулятор. Если это так, вы должны иметь возможность разговаривать непосредственно с батареей (обычно с адресом i2c 0xb).

Если это не аппаратная особенность, которую вы делаете, то игнорируйте то, что я сказал:)