2011-02-01 34 views
13

Estoy tratando de obtener el nivel de la batería dentro de un módulo kernel de Linux (el módulo se inserta a través de modprobe). Idealmente, me gustaría usar una llamada API de kernel para obtener la información de la batería. He buscado soluciones en la web y también he explorado la fuente Linux Kernel y la fuente del programa "acpi" de Michael Meskes para obtener ideas.¿Cómo puedo obtener el nivel de batería dentro de un módulo kernel de Linux?

Estas son algunas de las técnicas que creo que puedo usar:

  1. leer y analizar /proc/acpi/battery/BAT0/state y /proc/acpi/battery/BAT0/info
  2. Leer de /sys/class/power_supply/BAT0/charge_now y charge_full sin análisis en cuestión.
  3. Podría intentar usar las llamadas de los controladores fuente de kernel de Linux/acpi/battery.c si pudiera descubrir cómo exponer la interfaz. Probablemente necesitaría los métodos acpi_battery_get_status y acpi_battery_get_info
  4. También noté que dentro de los drivers/acpi/sbs.c hay un método acpi_battery_read y justo encima hay un comentario que dice "Driver Interface". Esta podría ser otra forma si alguien sabe cómo usar esto.

Supongo que probablemente sea una mala idea leer archivos mientras estoy dentro de un módulo kernel, pero no estoy muy seguro de cómo esos archivos se asignan a las llamadas a función kernel, por lo que podría estar bien.

¿Pueden darme algunas sugerencias/recomendaciones?

Editar: He incluido mi solución en una respuesta a continuación.

+0

¿Por qué quieres hacer esto, exactamente? –

+0

@Andy Hay alguna funcionalidad dependiente del nivel de batería. – razvanlupusoru

Respuesta

10

He encontrado una solución que funciona para mí. Primero asegúrese de #include < linux/power_supply.h>

Suponiendo que conoce el nombre de la batería, este código proporciona un ejemplo de cómo obtener la capacidad actual de la batería.

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

En cuanto a battery.c, sbs.c, creo que puede llamar directamente a la interfaz API (acpi_battery_read, acpi_battery_get_state) en su LKM.
¿Lo has intentado hasta ahora?

+0

Intenté usar esos métodos estáticos al declararlos en mi módulo con un extern. Sin embargo, en el tiempo de carga del módulo permanecieron indefinidos. No creo que los métodos estáticos puedan usarse fuera de un archivo donde están definidos. Aunque quiero agregar que los métodos estáticos existen en la Tabla de símbolos del núcleo (observé a través de/proc/kallsyms) – razvanlupusoru

0

¡Tengo el mismo dilema! : - \ Si esto es algo específico de hardware que está haciendo, podría ver si en su computadora portátil particular puede detectar la batería inteligente en el enlace SMBus o no. Si puede, puede hacer llamadas i2c/SMBus desde su LKM. La mayoría de los sistemas nuevos (excepto algunas laptops Fujitsu) hablan con un controlador integrado, que termina configurando la batería (a través de SMBus, supongo) .... Intenta instalar "lm-sensors" y verifica si detecta tu batería inteligente. Si es así, debería poder hablar directamente con la batería (generalmente en la dirección i2c 0xb).

Si esto no es una cosa específica de hardware que está haciendo, a continuación, pasar por alto lo que he dicho :)

Cuestiones relacionadas