Vortrag auf der Internet of Things Conference 2015
Speaker: Alexander Dahmen, Dominik Helleberg, inovex GmbH
Das Potenzial der Android-Plattform geht weit über den populärsten Einsatzbereich auf Smartphones und Tablets hinaus. Im IoT-Kontext bietet Android dem Benutzer ein attraktives GUI, um die vernetzte Welt zu steuern und zu kontrollieren. Um die Rolle einer Schaltzentrale zu übernehmen, sollte die Plattform offen für die Integration von externer Hardware und Protokollen sein. Hier punktet Android mit einer sauberen Architektur von der Integration der Treiber sowie Permissions und Java-APIs bis hin zum Bereitstellen eigener SDK-Komponenten für externe Entwickler. Anhand eines externen Displays zeigen wir vom Kernel bis zum Java-SDK alle notwendigen Schritte und Schichten.
Mehr Vorträge von uns: https://www.inovex.de/de/content-pool/vortraege/
11. Android Embedded
Vorteile - HAL / Service Architektur
SystemService
Application Applikations-Logik
Java API / SDK / Dokumentation
Greift über RPC Call auf den Service zu
Manager
Interface
Binder Interface für den Service (AIDL)
Manager
Service
libhardware
Logik, Security Checks, Native JNI Aufrufe
Native “interface” (header file)
driver.so
/dev/foo
device depenedent driver
kernel / module
13. Android Embedded
Beispiel: Display
driver.so
/dev/foo
● Grove 16x2 Display mit I2C
○ LCD-Modul
○ RGB-Modul
● Der Befehlssatz des LCDs wird vom Hersteller bereitgestellt.
● MarS Board mit Android 4.0.4 (BSP)
● Das LCD wird per I2C an das Mars Board angeschlossen
○ LCD 0x3e
○ RGB 0x62
15. Android Embedded
Beispiel: Display
driver.so
/dev/foo
● Der Android Kernel basiert auf einem Linux Kernel mit
einigen Android spezifischen Anpassungen
● Der Linux Kernel stellt bereits einen I2C-Core-Treiber zur
Verfügung.
○ Dieser übernimmt die Kommunikation mit den am Bus
angeschlossenen Geräten.
● Für das LCD-Modul und das RGB-Modul wird jeweils ein I2C-
Client Treiber benötigt.
18. Android Embedded
Beispiel: Display
driver.so
/dev/foo
● Der Client-Treiber kann über die I2C-Funktionen des Core-
Treibers mit dem LCD kommunizieren.
○ i2c_smbus_write_byte_data (client, u8 command, u8 value);
○ i2c_smbus_read_byte_data (client, u8 command);
19. Android Embedded
Beispiel: Display
driver.so
/dev/foo
● Anforderung:
○ Die Treiber sollen beim Systemstart geladen und das Display
initialisiert werden.
● Wie findet die Verknüpfung zwischen LCD-/RGB-Modul und
dem jeweiligen Treiber statt?
● board-mx6q_marsboard.c
○ unter /arch/arm/mach-mx6
24. Android Embedded
Beispiel: Display
● Zugriff auf die Treiber über eine HAL-Bibliothek (Userspace)
● HAL-Bibliothek greift über System-Call-Interface auf die
Gerätedateien zu (/dev/lcd1313M1 u. /dev/rgb1313M1)
● Kann auch unter eine proprietäre Lizenz gestellt werden
(Treiber muss unter die GPL gestellt werden, daher werden
diese oft einfach gehalten)
libhardware
25. Android Embedded
Beispiel: Display
● Die HAL-Bibliothek besteht aus zwei Komponenten
○ Implementierung unter:
■ /device/fsl/marsboard_6q/lcd1313M1
○ Headerdatei unter:
■ /hardware/libhardware/include/hardware
● Der Zugriff auf die HAL-Bibliothek findet über die
Headerdatei statt
libhardware
28. Android Embedded
Beispiel: Display
● Damit ein open(...) auf /dev/lcd1313M1 erfolgreich ist,
müssen die Rechte stimmen
● /system/core/rootdir/ueventd.rc erweitern:
○ /dev/lcd1313M1 0660 system system
○ /dev/rgb1313M1 0660 system system
● HAL-Bibliothek läuft im system-Kontext
libhardware
30. Android Embedded
Beispiel: Display
● Der Manager Service besteht aus zwei Teilen:
○ den nativen Methoden in
com_android_server_LCDService.cpp
○ LCDService.java
● com_android_server_LCDService.cpp bindet die
Headerdatei der HAL-Bibliothek ein und lädt die Bibliothek
● LCDService.java ruft die nativen Methoden über das JNI
auf
Manager
Service
32. Android Embedded
Beispiel: Display
public class LCDService extends ILCDService.Stub {
private int mNativePointer;
public LCDService(Context context) {
super();
mNativePointer = init_native();
}
public int setText(String mString)
{
checkPermission(android.Manifest.permission.LCD_SERVICE);
synchronized (mLock) {
byte[] buffer = mString.getBytes();
return setText_native(mNativePointer, buffer); }
}
private static native int init_native();
SystemService
33. Android Embedded
Beispiel: Display
● Android Permission für das LCD
○ android.Manifest.permission.LCD_SERVICE
● Eine App, die den Service/Hardware verwenden möchte,
muss diese Permission in der Manifest-Datei angeben
○ <uses-permission>
Manager
Service
35. Android Embedded
Beispiel: Display
● Für den LCDService muss eine zugehörige ILCDService.
aidl Datei erstellt werden.
● Diese beinhaltet die Deklarierung der Funktionen, die vom
Binder aufrufbar sein sollen.
● Aus der .aidl Datei wird ein Binder-Interface für den Java-
Dienst generiert (ILCDService.java)
Manager
Interface
38. Android Embedded
Beispiel: Display
public class LCDManager
{
public static LCDManager getLCDManager()
{
IBinder b = ServiceManager.getService("lcd1313M1");
ILCDService service = ILCDService.Stub.asInterface(b);
return new LCDManager(service);
}
public int setText(String mString) {
try {
return mService.setText(mString);
} catch (RemoteException e) {
return -1;
}
}
SystemService
39. Android Embedded
Beispiel: Display
● Anpassung des System Servers damit beim Systemstart
der neue LCDService gestartet wird
public void run() {
//...
try {
ServiceManager.addService("lcd1313M1", new LCDService(context));
} catch ( Throwable e ) {
reportWtf("starting LCD service",e) ;
}
}
SystemService