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

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

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

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

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

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

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


person razvanlupusoru    schedule 01.02.2011    source источник
comment
Почему вы именно это хотите?   -  person Andy Grover    schedule 11.02.2011
comment
@Andy Есть некоторые функции, зависящие от уровня заряда батареи.   -  person razvanlupusoru    schedule 16.02.2011


Ответы (3)


Я нашел решение, которое мне подходит. Прежде всего убедитесь, что #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);
}
person razvanlupusoru    schedule 05.03.2011
comment
Что касается linux-headers-4.4.0-146-generic, psy- ›get_property недействителен, необходимо использовать power_supply_get_property - person Yuriy Chernyshov; 03.05.2019

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

person TheCottonSilk    schedule 01.02.2011
comment
Я попытался использовать эти статические методы, объявив их в моем модуле с помощью extern. Однако во время загрузки модуля они оставались неопределенными. Я не думаю, что статические методы можно использовать вне файла, в котором они определены. Хотя я хочу добавить, что статические методы существуют в таблице символов ядра (я наблюдал через / proc / kallsyms) - person razvanlupusoru; 16.02.2011

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

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

person none    schedule 06.02.2011