Red de conocimiento informático - Material del sitio web - Cómo encender un LED en el análisis del flujo de trabajo Android de la plataforma Qualcomm

Cómo encender un LED en el análisis del flujo de trabajo Android de la plataforma Qualcomm

1.Análisis de código de capa FW

BatteryService.java

public Led(Contextcontext, LightsManager luces) {

mBatteryLight =luces. getLight(LightsManager.LIGHT_ID_BATTERY);

mBatteryLowARGB =context.getResources().getInteger(

com.android.internal.R.integer.config_notificationsBatteryLowARGB);

mBatteryMediumARGB =context.getResources().getInteger(

com.android.internal.R.integer.config_notificationsBatteryMediumARGB);

mBatteryFullARGB =context.getResources().getInteger(

p>

com.android.internal.R.integer.config_notificationsBatteryFullARGB);

mBatteryLedOn =context.getResources().getInteger(

com.android .internal.R integer.config_notificationsBatteryLedOn);

mBatteryLedOff =context.getResources().getInteger(

com.android.internal.R.integer.config_notificationsBatteryLedOff);

}

public void updateLightsLocked() {

nivel int final =mBatteryProps.batteryLevel;

estado int final =mBatteryProps.batteryStatus;

if (level

if (status ==BatteryManager.BATTERY_STATUS_CHARGING) {

// Rojo fijo cuando la batería se está cargando

mBatteryLight.setColor( mBatteryLowARGB);

} else {

// Parpadea en rojo cuando la batería está baja y no se carga

mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED,

mBatteryLedOn,mBatteryLedOff);

}

} else if (status ==BatteryManager.BATTERY_STATUS_CHARGING

|| status ==BatteryManager.BATTERY_STATUS_FULL) {

if ( status ==BatteryManager.BATTERY_STATUS_FULL || nivel >= 90) {

// Verde fijo cuando está lleno o cargando y casi lleno

mBatteryLight.setColor(mBatteryFullARGB);

} else {

if (isHvdcpPresent()) {

// Naranja intermitente si cargador HVDCP

mBatteryLight.setFlashing(mBatteryMediumARGB, Light.LIGHT_FLASH_TIMED,

mBatteryLedOn,mBatteryLedOn);

} else {

// Naranja fijo cuando se carga y está medio lleno

mBatteryLight.setColor(mBatteryMediumARGB

}

}

} else {

// No hay luces si no se está cargando y no está bajo

mBatteryLight .turnOff();

}

}

LightsService.java

public voidsetColor(int color) {

sincronizado (este) {

setLightLocked(color, LIGHT_FLASH_NONE,0, 0, 0);

}

}

vacío privado setLightLocked(int color, int modo, int onMS, int offMS,int brightMode) {

if (color != mColor || mode !=mMode || onMS != mOnMS || offMS != mOffMS) {

if (DEBUG) Slog.v("jyf","setLight #" + mId + ": color=#"

+Integer.toHexString(color));

mColor = color; p>

mMode = modo;

mOnMS = onMS;

mOffMS = offMS;

Trace.traceBegin(Trace.TRACE_TAG_POWER,"setLight (" + mId + ", 0x"

+Integer.toHexString(color) + ")");

prueba {

setLight_native(mNativePointer, mId , color , modo, onMS, offMS,brightnessMode);

} finalmente {

Trace.traceEnd(Trace.TRACE_TAG_POWER);

}

}

2.Interfaz nativa Java JNI

Permite que el código Java que se ejecuta dentro de la máquina virtual Java interactúe con aplicaciones y bibliotecas escritas en otros lenguajes de programación. Por lo tanto, en Android, la capa Java llama a la biblioteca de funciones C/C++ subyacente y debe implementarse a través de JNI de Java. Este proceso requiere cinco pasos:

a. Escribir una aplicación Java

En el programa Java, el archivo de la biblioteca debe cargarse y declararse a través de System.LoadLibrary("library"); nativo para declarar métodos locales.

b Genere el archivo de encabezado de la biblioteca compartida:

javac FileName.java FileName.class

Javah Filename package_FileName.h

< p. >La convención de nomenclatura de la función correspondiente en el archivo de encabezado JNI:

Java_packagename_classname_interface nombre.

c. Escriba un archivo C que implemente el método local

Cree un nuevo paquete_FileName.c e implemente el método local de acuerdo con el archivo de encabezado

d. Compile y genere la biblioteca so

p>

Utilice NDK-BUILD para compilar el archivo .c en el paso 3) para generar un archivo de biblioteca .so. Y escribe el makefile correspondiente.

incluye $(CLEAR_VARS): borra algunas variables del sistema anteriores

LOCAL_MODULE: el objeto de destino generado por la compilación

LOCAL_SRC_FILES: el archivo fuente compilado

LOCAL_C_INCLUDES: directorio de archivos de encabezado que deben incluirse

LOCAL_SHARED_LIBRARIES: bibliotecas externas necesarias para la vinculación

LOCAL_PRELINK_MODULE: si se requiere procesamiento previo de vinculación

incluir $ (BUILD_SHARED_LIBRARY): indica que se compilará en una biblioteca dinámica

3.Makefile

Android.mk es un archivo MAKE proporcionado por Android, que se utiliza para especificar este tipo de cosas. como el nombre de la biblioteca compilada y los encabezados de archivos a los que se hace referencia, archivos .c/.cpp y archivos de biblioteca estática .a que deben compilarse, etc.

El propósito de Android.mk:

Habrá uno o más archivos Android.mk en un subproyecto de Android

un solo Android. archivo mk

Consulte directamente el proyecto hello-jni en el directorio de muestra de NDK. En este proyecto, solo hay un archivo Android.mk

b y varios archivos Android.mk.

Si hay muchos módulos que deben compilarse, podemos colocar los módulos correspondientes en los directorios correspondientes. De esta manera, podemos definir los archivos Android.mk correspondientes en cada directorio (similar a lo anterior). escribiendo),

Finalmente, coloque un archivo Android.mk en el directorio raíz con el siguiente contenido:

include $(call all-subdir-makefiles)

>Solo se necesita esta línea, su función es incluir archivos Android.mk en todos los subdirectorios

c Utilice un Android.mk para múltiples módulos

Este archivo le permite convertir el código fuente. archivos Organizado en módulos, este módulo contiene:

- Biblioteca estática (archivo .a)

- Biblioteca dinámica (archivo .so)

Solo *** La biblioteca compartida se puede instalar/copiar en el paquete de software de su aplicación (APK)

incluye $(BUILD_STATIC_LIBRARY), la biblioteca compilada es una biblioteca estática

incluye $(BUILD_SHARED_LIBRARY), compilada La salida es una biblioteca dinámica

4. Variables personalizadas

La siguiente es una lista de variables que dependen o están definidas en Android.mk. Puede definir otras variables para su propio uso. , pero el sistema de compilación NDK Los siguientes nombres de variables están reservados:

- nombres que comienzan con LOCAL_ (por ejemplo, LOCAL_MODULE)

- nombres que comienzan con PRIVATE_, NDK_ o APP_ (para uso interno)

nombre en minúscula (usado internamente, como 'my-dir')

Si desea definir cómodamente sus propias variables en Android.mk, se recomienda utilizar MY_ prefijo, un pequeño ejemplo:

MY_SOURCES := foo.c

ifneq ($(MY_CONFIG_BAR),)

MY_SOURCES += bar.c

endif

LOCAL_SRC_FILES += $(MY_SOURCES)

Nota: ':=' significa asignación; '+=' significa agregar '$' significa hacer referencia al valor de una variable.

5. Variables del sistema GNU Make

Estas variables de GNU Make son definidas por el sistema de compilación antes de que se analice su archivo Android.mk. Tenga en cuenta que en algunos casos, el NDK puede analizar Android.mk varias veces y cada vez la definición de algunas variables será diferente.

a.CLEAR_VARS: apunta a un script compilado, casi todas las variables LOCAL_XXX no definidas se enumeran en la sección "Descripción del módulo". Este script debe incluirse antes de iniciar un nuevo módulo: include$(CLEAR_VARS), que se utiliza para restablecer todas las variables de la serie LOCAL_XXX excepto la variable LOCAL_PATH.

b.BUILD_SHARED_LIBRARY: apunta al script de compilación, que compila los archivos de código fuente enumerados en una biblioteca compartida basada en todas las variables LOCAL_XXX.

Tenga en cuenta que se deben definir al menos LOCAL_MODULE y LOCAL_SRC_FILES antes de incluir este archivo.

c.BUILD_STATIC_LIBRARY: Se utiliza una variable BUILD_SHARED_LIBRARY para compilar una biblioteca estática. La biblioteca estática no se copiará en el paquete APK, pero se puede utilizar para compilar la biblioteca compartida.

Ejemplo: incluir $(BUILD_STATIC_LIBRARY)

Tenga en cuenta que esto generará un archivo llamado lib$(LOCAL_MODULE).a

d.TARGET_ARCH: El nombre de la plataforma de CPU de destino

e.TARGET_PLATFORM: cuando se analiza Android.mk, el nombre de la plataforma de Android de destino

f.TARGET_ARCH_ABI: actualmente solo admite dos valores, armeabi y armeabi- v7a. .

g.TARGET_ABI: La combinación de plataforma de destino y ABI.

6. Variables de descripción del módulo

Las siguientes variables se utilizan para describir su módulo en el sistema de compilación. Debe definirse entre 'incluir $(CLEAR_VARS)' e 'incluir $(BUILD_XXXXX)'. $(CLEAR_VARS) es un script que borra todas estas variables.

a.LOCAL_PATH: Esta variable se utiliza para dar la ruta del archivo actual.

Debe definirse al principio de Android.mk. Se puede usar así: LOCAL_PATH := $(call my-dir)

Si hay un nombre de carpeta src. en el directorio actual, puede escribir $(call src) de esta manera, luego obtendrá la ruta completa del directorio src

Esta variable no será borrada por $(CLEAR_VARS), por lo que cada Android. mk solo necesita definirse una vez (incluso en un archivo cuando se definen varios módulos en él).

b.LOCAL_MODULE: Este es el nombre del módulo. Debe ser único y no puede contener espacios.

Esto debe definirse antes de incluir cualquier script $(BUILD_XXXX). El nombre del módulo determina el nombre del archivo generado.

c.LOCAL_SRC_FILES: Esta es una lista de archivos de código fuente que se compilarán.

Simplemente enumere los archivos que se pasarán al compilador, ya que el sistema de compilación calcula automáticamente las dependencias. Tenga en cuenta que los nombres de los archivos del código fuente son relativos a LOCAL_PATH, puede usar la parte de la ruta, por ejemplo:

LOCAL_SRC_FILES := foo.c toto/bar.c\

Hello.c

Los archivos se pueden separar mediante espacios o la tecla Tab. Utilice "\" para saltos de línea

Si va a adjuntar archivos de código fuente, utilice LOCAL_SRC_FILES +=

Nota: Puede incluir todos los archivos java en el directorio local_path en el formato LOCAL_SRC_FILES := $(llamar a todos-subdir-java-files).

e.LOCAL_C_INCLUDES: Variable opcional que indica la ruta de búsqueda de archivos de cabecera.

La ruta de búsqueda predeterminada para archivos de encabezado es el directorio LOCAL_PATH.

f.LOCAL_STATIC_LIBRARIES: Indica qué bibliotecas estáticas necesita usar el módulo para poder vincularse en tiempo de compilación.

g.LOCAL_SHARED_LIBRARIES: Indica la biblioteca compartida (biblioteca dinámica) de la que depende el módulo en tiempo de ejecución, la cual es requerida en el momento del enlace para poder incrustar su información correspondiente al generar archivos.

Nota: No agregará los módulos enumerados al gráfico de compilación, es decir, aún deberá agregarlos en Application.mk a los módulos requeridos por el programa.

h.LOCAL_LDLIBS: Opciones de enlazador adicionales para usar al compilar el módulo. Esto es útil para pasar el nombre de una biblioteca específica usando el prefijo '-l'.

Por ejemplo, LOCAL_LDLIBS := -lz le dice al vinculador que el módulo generado debe vincularse a /system/lib/libz.so en el momento de la carga.

Ver docs/STABLE-APIS TXT Obtiene una lista de bibliotecas del sistema abiertas a las que se puede vincular mediante la distribución NDK.

i.LOCAL_MODULE_PATH y LOCAL_UNSTRIPPED_PATH

En el archivo Android.mk, también puede usar LOCAL_MODULE_PATH y LOCAL_UNSTRIPPED_PATH para especificar la ruta de instalación de destino final

Archivo diferente. sistemas La ruta se selecciona mediante la siguiente macro:

TARGET_ROOT_OUT: Indica el sistema de archivos raíz.

TARGET_OUT: Representa el sistema de archivos del sistema.

TARGET_OUT_DATA: Representa el sistema de archivos de datos.

Usos como: LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT)

En cuanto a la diferencia entre LOCAL_MODULE_PATH y LOCAL_UNSTRIPPED_PATH, aún no está clara.

j.LOCAL_JNI_SHARED_LIBRARIES: Define el nombre del archivo de biblioteca que se incluirá. Si el programa no usa jni, no es necesario LOCAL_JNI_SHARED_LIBRARIES:= libxxx. empaquete automáticamente este libxxx en apk; colóquelo en el directorio youapk/lib/

7. CAPA DE ABSTRACCIÓN DE HARDWORE

Figura 2 Estructura del marco HAL

Luces. c

static int set_speaker_light_locked(struct light_device_t* dev,

struct light_state_t const* state)

{

int rojo, verde, azul;

int parpadeo;

int onMS, offMS;

unsigned int colorRGB;

ALOGE("liuyonglin set_speaker_light_locked ingresa a la prueba" );

if(!dev) {

ALOGE("liuyonglin, light HAL dev es nulo");

return -1;

}

cambiar (estado->flashMode) {

caso LIGHT_FLASH_TIMED:

onMS = estado->flashOnMS;

offMS = estado->flashOffMS;

descanso;

caso LIGHT_FLASH_NONE:

valor predeterminado:

onMS = 0;

offMS = 0;

descanso;

}

colorRGB = estado->color;

ALOGE("liuyonglin set_speaker_light_locked modo %d, colorRGB=%08X, onMS=%d, offMS=%d\n",

estado->flashMode, colorRGB, onMS, offMS);

rojo = (colorRGB >> 16) & 0xFF ;

verde = (colorRGB >> 8) & 0xFF;

azul = colorRGB & 0xFF;

if (onMS > 0 && offMS > 0) {

/*

* si tiempo ON == tiempo OFF

* usar modo parpadeo 2

* más

* usar el modo de parpadeo 1

*/

if (onMS == offMS)

parpadeo = 2;

else

parpadear = 1;

} else {

parpadear = 0;

}

si (parpadear) {

if (rojo) {

if (write_int(RED_BLINK_FILE, parpadear))

write_int(RED_LED_FILE, 0);

}

if (verde) {

if (write_int(GREEN_BLINK_FILE, parpadea))

write_int(GREEN_LED_FILE, 0);

}

if (azul) {

if (write_int(BLUE_BLINK_FILE, parpadea))

write_int(BLUE_LED_FILE, 0);

}

} else {

write_int(RED_LED_FILE, rojo);

write_int(GREEN_LED_FILE, verde);

write_int(BLUE_LED_FILE, azul) ;

ALOGE("liuyonglin, write_int rojo verde azul");

}

devuelve 0;

}