Как я могу получить уровень заряда батареи внутри модуля ядра 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).
Если это не аппаратная особенность, которую вы делаете, то игнорируйте то, что я сказал:)