Skip to content

Embedded Android CAN SDK Extension

Android Embedded SDK Extensions: CAN Bus

i.MX7 ULP setup.jpg

Introduction

CAN Bus (Controller Area Network Bus) is a robust communication system widely used in automotive and industrial applications for real-time data exchange between microcontrollers and devices. Developed by Bosch in the 1980s, it enables multiple electronic control units (ECUs) to communicate on a single network without a host computer. The system uses a twisted pair of wires for differential signaling, which enhances noise immunity and reliability. CAN Bus is highly efficient, allowing for the transmission of critical data, such as engine performance and safety features, with low latency. It supports speeds up to 1 Mbps and is essential in modern vehicle electronics. In vehicles, examples include the Engine Control Unit (ECU), which monitors and controls engine performance, the Anti-lock Braking System (ABS) module that prevents wheel lockup during braking, and the Transmission Control Unit (TCU) responsible for gear shifting. Additionally, body control modules manage interior functions like lighting and power windows. In industrial applications, CAN Bus devices include sensors and actuators in automation systems, such as temperature sensors and motor controllers, ensuring coordinated operations and efficient data exchange across complex machinery.

Linux offers robust support for CAN Bus through various tools and drivers, making it a popular choice for developing and deploying CAN-based systems. The SocketCAN framework, integrated into the Linux kernel, provides a unified API for accessing CAN interfaces, allowing developers to interact with CAN devices as standard network interfaces. Tools like can-utils offer utilities for sending, receiving, and analyzing CAN messages. Additionally, various open-source libraries support CAN Bus development, enabling integration with user-space applications. This support makes Linux an ideal platform for automotive diagnostics, industrial control, and embedded systems utilizing CAN Bus communication.

Android SDK limitations for Embedded Systems

Android's API is designed to abstract the complexity of the underlying hardware, providing a consistent and simplified interface for developers. This abstraction allows developers to build applications without needing to understand the intricate details of the hardware on which their apps run. Android achieves this by offering high-level APIs that handle interactions with the device's camera, sensors, networking components, and other hardware features. These APIs ensure that applications work across different devices with varying hardware configurations, creating a seamless user experience.

However, Android natively lacks APIs for certain specialized embedded protocols like CAN Bus, RS485, or for controlling GPIO (General Purpose Input/Output) pins. These protocols are commonly used in automotive, industrial, and embedded systems for communication and hardware control, but they are not part of the standard Android ecosystem. This omission stems from Android's primary focus on consumer devices, such as smartphones and tablets, where such low-level hardware interactions are less common.

To work with CAN Bus, RS485, or GPIO on Android, developers typically need to rely on custom drivers, external libraries, or use the Android NDK (Native Development Kit) to interact directly with the hardware. This approach requires a deeper understanding of the underlying hardware and more complex development processes, contrasting with Android's usual ease of use.

Embedded Android SDK Extensions

Kynetics addresses the limitations of the standard Android SDK by developing the Embedded Android SDK Extensions, which provide bindings between native libraries and ART (Android Runtime Environment). These extensions enable developers to interact with embedded hardware protocols, such as CAN Bus, RS485, and GPIO, directly from Android applications using familiar languages like Java, Kotlin, and C#. Take a look to the supoprted busses and protocols here.

The Embedded Android SDK Extensions bridge the gap between Android's Standard APIs and the low-level hardware interactions necessary for embedded systems. Kynetics achieves this by creating custom native bindings to native libraries and Android Kernel drivers (and API) that interface with the hardware. These native bindings allow for seamless communication between the native code and the Android JVM, ensuring that developers can control embedded devices from their Android Studio Project. Very bad practices and workarounds to interact with not supported H/W abstractions is to wrap Android shell commands with exec() funtions. This practice is very insecure, difficult to debug with very poor error handling

Embedded Android SDK Extensions enable developers to build robust embedded applications within the Android ecosystem, utilizing standard Android development practices while still gaining access to specialized hardware protocols. By providing these extensions, Kynetics significantly reduces the development time and complexity associated with integrating embedded systems into Android, making it easier to deploy Android-based solutions in automotive, industrial, and IoT environments.

Setup your CAN Testing Environment with Kynetics Android

Kynetics provides custom Android Operating System, for development and production puposes, compatible with various popular application processors and embedded development kit. Visit Kynetics' website for more details

Kynetics' Android BSP that supports CAN bus includes a CAN Test application (developed with the CAN Embedded SDK) which is very instrumentsl for preliminary testing before writing your CAN code using the Emnedded SDK. Make sure also that your H/W supports CAN interface. Popular development kits in such regard are the Ezurio Nitrogen 8MPlus Development Kit or Toradex Verdin Development Kit or Technexion EDM-G-Wizard. Also other families of i.MX processors suports CAN such as i.MX8MMini Development Kit and the legacy i.MX6. Refer to NXP website for more details.

Once you identify your can bus connector on the board, for the purpose of testing it we need to have our host PC on the other end. The CANable USB to CAN adapter can be used to connect this bus to a Linux host PC using a USB port. canable.

Alternatively you can use the Use an MKS Canable Pro v1.0 USB to CAN adapter flashed with the candlelight firmware.

After booting Kynetics Android, the can0 interface must be configured usind ADB abd the Android shell:

$ adb root
$ adb shell
nitrogen6x:/ # ip link set can0 type can bitrate 125000
nitrogen6x:/ # ip link set can0 up

On your Linux Host the CAN interface must configured as well

$ ip link set can0 type can bitrate 125000
$ ip link set can0 up

The CAN Testing Android App

Open now the CAN Testing App from the Android Launcher. When the application is launched, the user can select the CAN interface to be tested from the dropdown menu listing all CAN interfaces on the device (CAN0 is your choice)

can_app

Once the CAN interface is configured, there are two TABS: Sender and Reveiver

The sender UI is composed of three sections:

can_app

  • Configuration

    • Loopback: enable loopback
    • Receive Own Messages: receive the sent frames
  • Socket Raw

    • BIND/UNBIND button: create/destroy and bind/unbind the CAN socket associated with the sender. A socket for sending frames on the CAN bus is automatically created and bound when the application is launched.
  • Frame

    • Data/RTR/Error box: configure the type of CAN frame to be sent
    • ID: specifies the CAN frame ID
    • DATA: data to be sent

Once configuration is complete, the user can send the CAN frame on the bus using the send button on the bottom right side of the screen.

NOTE: Only RAW sockets are currently supported.

The receiver UI allows to receive and display messages from the selected interface

can_app

The UI is composed of three sections:

  • Socket Raw

    • BIND/UNBIND button: create/destroy and bind/unbind the CAN socket associated with the receiver. A socket for receiving frames on the CAN bus is automatically created and bound when the application is launched.
  • Data Acquisition

    • START/STOP button: start/stop receiving CAN frames
    • Can Messages: displays data received on the CAN bus

NOTE: Only RAW sockets are currently supported.

Send a string from the HOST to the Android board

Now we are ready to send a string from the Host PC to the Android Board. Let take for this test the 'kynetics' string that in HEX is

6b796e6574696373
To send the string from the Linux Host, input the command
$ cansend can0 123#6b796e6574696373
On the CAN testing app, enable the data acquisition and in the RECEIVER view (with DATA ACQUISITION enabled) you get: can_app

the data frame [107,121,110,101,1167,105,99,115] that in ASCII is: kynetics

Send a string from the Android board ot the Host

To send the string from Android board to the host PC, from the SENDER view of CAN Test application write the 'kynetics' string you want as DATA FRAME in the DATA text field. can_app_send

On the Linux host:

$ candump can0                   
can0  001   [8]  6B 79 6E 65 74 69 63 73
and you will get the HEX of the data frame.

Testing a Logic Analyzer

Let's do another test but this time instead of a Linux Host we use a logic analizer. In this setup we are using the NXP i.MX8MMini developent kit.

  • Connect the Canable Pro v1.0 to the Android board via a USB-C adapter. The Canable device is exposed directly as a CAN interface.
  • The CAN adapter output is connected to a Saleae analyzer to capture and print the CAN data. (GRD and CAN_L)

The CAN adapter output is connected to a Saleae analyzer to capture and print the CAN data. (GRD and CAN_L)

can_app

  1. Open a root shell on the board and run the following commands to enable and configure the CAN interface:
     board:/ $ ip link set can0 type can bitrate 125000
     board:/ $ ip link set can0 up
    
  2. Check if the CAN interface is active. The output should be like:
    # ip link
     1: lo: <LOOPBACK,UP,LOWER_UP> ...
     ...
     18: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
     link/can 
    
  3. Configure the Saleae analyzer via Logic Pro software to analyze a CAN protocol.
  4. Launch the CAN Handler application, select the CAN interface (can0 in this case), and prepare a simple frame to send. can_app
  5. Start recording the signal from the Logic software and send the CAN frame via app. The CAN frame data and both analog and digital signals appear on the Logic Pro screen. can_app

Compile your project with Android Studio adding a licensed SDK Estension

The Android SDK Extension provides a set libraries to add to your Android Studio Project. The SDK Extensions artifacts includes:

  • armeabi-v7a 32 bit native libraries
  • arm64-v8a 64 bit native libraries
  • JAR or AAR libraries

To import the necessary artifacts in your Android Studio Project

  1. Import the library as module: File -> New -> New Module -> Import .JAR/.AAR Package
  2. Add the module as dependency of the main app module: right-click on your Application Module -> Open Module Settings -> select Dependencies Tab -> Click the “+” green button -> Module dependency
  3. Sync the project
  4. Build the project

Compile your project with MAUI adding a licensed SDK Estension

To load the SDK extension library into a MAUI application, you can use one of the following approaches:

Auto Loading the Library File:

  1. For projects targeting .NET 6 or later, the ImplicitUsings property is enabled by default, which automatically loads all .jar/.aar files in the project. To ensure this property is enabled, add the following line to the .csproj file inside the first PropertyGroup tag:

        <ImplicitUsings>enable</ImplicitUsings>
    

  2. After this, simply copy the .aar or .jar file into any directory in the project (or the root). The system will automatically load the library file into the project.

Manually Configuring the .csproj File to Load the Library:

  1. Copy the .jar or .aar file into the desired directory within the project.

  2. Add the following lines at the end of the .csproj file, inside the Project tag. Replace <lib-directory> with the directory name where the library file is located and <lib-name> with the full name of the library archive file (e.g., can-sdk.aar).

<ItemGroup>
   <AndroidAarLibrary Include="<lib-directory>\<lib-name>" />
</ItemGroup>

<ItemGroup>
   <AndroidLibrary Update="<lib-directory>\<lib-name>">
   <Bind>true</Bind>
   <Pack>true</Pack>
   </AndroidLibrary>
</ItemGroup>

This will ensure the library is loaded correctly into the project.

Conclusions

The standard Android SDK lacks support for embedded features like CAN Bus, RS232-485, and GPIO control, as it primarily targets consumer devices like smartphones and tablets. Developers working with embedded systems need to implement custom drivers or use external libraries to access these low-level hardware functionalities.

Kynetics' Embedded Android SDK Extensions enable developers to build robust embedded applications within the Android ecosystem, utilizing standard Android development practices while still gaining access to specialized hardware protocols.

In particular, with Kynetics' Android Embedded SDK Extensions for CAN bus, Android developers can now easily access the CAN Bus programmatically. These extensions provide native bindings that integrate seamlessly with the Android framework, allowing developers to interact with CAN Bus using Java, Kotlin or C#.

To support the integration progess, Kynetics has developed a CAN Bus testing app, enabling users to test CAN Bus communication effortlessly before writing their own code using the extended APIs. The application is also released to Kynetics public repository to provide an effective code reference.