Embedded Development with .NET and Android¶
Introduction¶
Embedded development used to be a niche field dominated by experts in low-level programming languages like C and assembly. These languages required deep knowledge of the hardware, making the barrier to entry quite high. However, the advent of modern languages like Java, C#, Kotlin has democratized embedded development thanks to a new gerneration of Operating Systems that feature powerful SDK and an all new way to deal with the underneath hadrware. Tools and frameworks have been developed to support these languages on embedded platforms, broadening the field and boosting innovation by integrating a wider range of programming expertise into embedded systems. High-level languages and related SDK offer greater abstraction, enabling developers with backgrounds in more common software development to transition into embedded systems.
Despite the continued need for low-level expertise in embedded development, the clear separation of application and OS layers has transformed the field. Modern embedded operating systems provide well-defined interfaces, allowing developers to focus on application logic independently of hardware specifics. This separation streamlines development processes and enhances productivity by abstracting hardware complexities. Consequently, developers proficient in high-level languages like Java and .NET can create robust applications without deep hardware knowledge. This layered approach fosters modularity, making it easier to update and maintain systems, and encourages broader participation in embedded development, leading to more innovative and versatile embedded solutions.
Windows as Embedded Systems OS¶
Windows CE, also known as Windows Embedded Compact, was a real-time operating system developed by Microsoft for embedded systems. Introduced in 1996, it is designed for devices with minimal memory and storage, such as industrial controllers, consumer electronics, and handheld devices. Over the years, Microsoft shifted focus to other platforms such Windows Embedded Standard, and eventually to Windows 10 IoT for embedded and IoT applications. But the question for Windows .NET developers may be: do I really care about a Windows based OS running on an embedded device? Can I do use my favourite programming language, famework, IDE and worstation OS but not be locked just with Windows on the target? Despite Microsoft fans can explore IoT applications with Windows 10 IoT, using familiar environments and programming languages there is not much hardware in the market supporting Windows IoT and still there are details to address from a licensing perspective unless you are using a hobbyist type of device such as the RPi.
GNU/Linux as Embedded Systems OS¶
It is common sense that GNU/Linux, and in particular all its embedded flavors, is probably the most commonly used operating system in the embedded industry. Open-source and proprietary solutions are available for any type of market space; from aerospace, to infotaiment, to hobbyists. One interesting point, althought, is that there is no clear winner in the UX/GUI ecosystem. All the competitive UI frameworks are not included in the OS itself but come as separate add-ons and often commercially licensed. There are UX/GUI products out there that are fully open source but they may not fit modern embedded application needs in terms of look and feel and performances.
What about Android?¶
Android is a widely used operating system for mobile devices and has a reputation for being one of the most secure mobile operating systems available. There are several reasons why Android can be considered a production-ready operating system for different types of embedded systems. The Android UX and GUI framework is a cornerstone for developers creating visually appealing and functional applications. This framework offers a variety of tools and components designed to build intuitive and responsive interfaces that cater to the needs of users.
The Android Abstraction Layer (HAL) is a crucial component in the Android operating system, acting as a bridge between the hardware and the higher-level software framework. HAL defines a standard interface for hardware vendors to implement, allowing Android to interact with diverse hardware components like cameras, sensors, and audio devices without needing to know the specifics of the hardware. This abstraction ensures that applications and system services can run on different devices with varying hardware configurations seamlessly.
Android has several built-in security features, such as encryption, app sandboxing, memory management, support for a complete chain of trust, implementation of a Trusted Execution Environment (TEE), Virtual Envionments (AVF) and more. All these features came along over many years and updates in the Android Open Source Project (AOSP), and today its maturity goes way beyond the great Graphical User Interface and user interaction, which initially attracted many embedded developers.
At Kynetics we strongly believe Android is an powerful, secure and production ready operating system for embedded systems. Chip makers as NXP, Qualcomm, Mediatek, Rockchip fully support Android, ASOP and AAOS (Android Automotive OS) for their products portfolio.
Hardware and Development Kit¶
Embedded Development Kits (EDKs) have become more accessible and affordable compared to the past when they were costly and limited. Today, manufacturers offer these kits at lower prices, enabling a broader range of developers to experiment and innovate. Additionally, manufacturers are more open to collaboration with system integration partners, providing comprehensive documentation and support. As a result, developers can access to a range of Development Kits and more easily prototype and develop embedded systems application software beyond software emulators but deploying on real hardware.
Goals¶
In this technical note, we provide an overview of .NET MAUI, which is a modern implementation of the .NET platform, and we will focus on showing how to:
- Set up the development tools and environment for building an applications from Windows and deploy them on an Embedded Android Operating System.
- Set up the hardware development kit to deploy applications
- Create a simple application and deploy it on the developmetn kit.
- Building with MAUI an Android GPIO manager application featuring Kynetics' SDK Extension to monitor and set the state of GPIOs on the target development kit.
As H/W development kit we use here the Ezurio Nitrogen 8MPlus Development Kit. Kynetics as an Ezurio's Android Partner supports different Ezurio's SOMs and Single Board Computer (SBC) with our Android Evaluation BSPs available to customers.
Ezurio offers a great and cost effective range of computer-on-modules (COMs) and single-board computers (SBCs), enabling rapid prototyping for both hardware and software engineers. Their products are designed to streamline development processes, providing robust and flexible platforms that cater to various project requirements. The Nitrogen 8M Plus SoM Module, in particular, is known for its powerful performance and ease of integration, making it an ideal choice for developing advanced embedded systems efficiently. This accelerates innovation and reduces development time significantly.
Why .NET?¶
.NET is a free, cross-platform, open-source developer platform for building many kinds of applications. It can run programs written in multiple languages, with C# being the most popular. It relies on a high-performance runtime that is used in production by many high-scale apps.
The .NET platform has been designed to deliver productivity, performance, security, and reliability. It provides automatic memory management via a garbage collector (GC). It is type-safe and memory-safe, due to using a GC and strict language compilers. It offers concurrency via async/await and Task primitives. It includes a large set of libraries that have broad functionality and have been optimized for performance on multiple operating systems and chip architectures.
.NET has the following design points:
- Productivity is full-stack with runtime, libraries, language, and tools all contributing to developer user experience.
- Safe code is the primary compute model, while unsafe code enables additional manual optimizations.
- Static and dynamic code are both supported, enabling a broad set of distinct scenarios.
- Native code interop and hardware intrinsics are low cost and high-fidelity (raw API and instruction access).
- Code is portable across platforms (OS and chip architecture), while platform targeting enables specialization and optimization.
- Adaptability across programming domains (cloud, client, gaming) is enabled with specialized implementations of the general-purpose programming model.
- Industry standards like OpenTelemetry and gRPC are favored over bespoke solutions.
.NET ecosystem¶
There are multiple variants of .NET, each supporting a different type of app. The reason for multiple variants is part historical, part technical.
.NET implementations:
- .NET Framework -- The original .NET. It provides access to the broad capabilities of Windows and Windows Server. It is actively supported, in maintenance.
- Mono -- The original community and open source .NET. A cross-platform implementation of .NET Framework. Actively supported for Android, iOS, and WebAssembly.
- .NET (Core) -- Modern .NET. A cross-platform and open source implementation of .NET, rethought for the cloud age while remaining significantly compatible with .NET Framework. Actively supported on different development OS sush as Linux, macOS, and Windows.
NOTE: While you can use an IDE that includes the .NET platform on different operating systems including Linux, the latter is not supported as a target OS to install cross-compiled applications (see next section).
.NET Core and MAUI¶
.NET Multi-Platform App UI (.NET MAUI) is a framework that allows for the development of native mobile and desktop applications using C# and XAML. With .NET MAUI, you can create apps that are cross-compatible with Android, iOS, macOS, and Windows, all from one shared codebase.
.NET MAUI is an open-source framework that builds upon Xamarin.Forms, extending its reach from mobile devices to desktops. The UI controls have been completely redesigned for better performance and greater flexibility. Developers familiar with Xamarin.Forms will recognize many similarities, although there are key differences. With .NET MAUI, a single project can be used to develop cross-platform applications, while still allowing the inclusion of platform-specific code and resources. One of the main objectives of .NET MAUI is to centralize most app logic and UI design within a unified codebase.
Tools and prerequisites¶
It is possible to develop with .NET MAUI with different development IDE that run on different workstation's operating systems (Linux, Windows, Mac). For the purpose of this technical note a Windows development workstation has been used.
To develop native, cross-platform applications with .NET Multi-platform App UI (.NET MAUI), you can use one of the following IDEs:
- Visual Studio 2022 version 17.8 or higher
- Visual Studio Code equipped with the .NET MAUI extension.
- JetBrains Rider
For the sake of simplicity, and to explore the stare of the art of MAUI powerful development tools we focus here solely on the setup process for Windows OS using JetBrains Rider and Visual Studio Code.
Installing Visual Studio Code¶
- Download the latest version of Visual Studio Code from the official website and install it.
- In Visual Studio Code, navigate to the Extensions tab and search for ".NET MAUI." Install the .NET MAUI extension, which will automatically install the necessary C# Dev Kit and C# extensions required for it to function properly.
Installing JetBrains Rider¶
- Download the latest version of JetBrains Rider from the official website and install it.
- Open JetBrains Rider and navigate to the Plugins section and select the Marketplace tab. Search for "Android" and install the Rider Android Support plugin and restart the IDE.
Setting up the development environment¶
Installing the SDKs¶
- Download and install the .NET 8 SDK for Windows using the provided guide.
- Install the .NET MAUI workload by running the following command in the command line (note that this process may take some time):
$ dotnet workload install maui
-
Install the Microsoft OpenJDK 17 by downloading the latest version and following the installation instructions.
- Set the JAVA_HOME environment variable to the path where the JDK is installed.
- Also add the JavaSdkDirectory variable to the system environment variables pointing to the JDK installation.
-
Install the Android SDK via one of the following approaches:
- Download and install Android Studio and follow the installation instructions.
- Or install via Visual Studio by selecting the Android development workload during installation.
- Or install the necessary Android SDK dependencies using by following these steps:
- First, set the AndroidSdkDirectory variable in the system environment variables to the installed Android sdk directory (e.g: C:\Android\Sdk)
- Create a new project (Described in 3.1) and navigate to the project directory in command line.
- Run the following command to install the required Android SDK packages:
In the command above:
$ dotnet build -t:InstallAndroidDependencies -f:net8.0-android -p:AndroidSdkDirectory="<path-to-android-sdk>" -p:AcceptAndroidSDKLicenses=True
- AndroidSdkDirectory="
": installs or updates Android dependencies to the specified absolute path. - AcceptAndroidSDKLicenses=True: accepts the required Android licenses for development.
- Replace the
<path-to-android-sdk>
accordingly (In this case: C:\Android\Sdk )
Creating, building, deploying, and debugging a simple Android application¶
Creating a new MAUI Android project¶
You can create a new MAUI Android project in two ways:
- Using command line:
Run the following commands to create a new project and restore the dependencies:
$ dotnet new maui -n AndroidApp
$ cd AndroidApp
$ dotnet restore
- Using Jetbrains Rider:
By selecting the File
menu, then New Solution
. Choose the MAUI
template, and configure the project:
* Enter the project and solution name (e.g: AndroidApp)
* Select the solution directory
* Select **net8.0** as the target framework
* Select **Android** as target platforms
* In the Advanced Settings section:
* Enter the desired package name for android application (e.g: com.kynetics.androidApp.maui)
* Enter the desired minimum supported [Android API level](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels) (e.g: 21)
- Using VSCode:
- Press the command keys
Ctrl + Shift + P
type the.NET new project
into the search bar, hit enter, and then selectAndroid Application
options. - Select the desired directory for the project and enter the project name (e.g: AndroidApp) and select create project.
- Press the command keys
Building the project¶
- Using Jetbrains Rider:
- Right-click on the project and select
Build Solution
from the context menu. - The output APK will be stored in the
bin/Debug/net8.0-android
directory.
- Right-click on the project and select
- Using VSCode:
- Press the command keys
Ctrl + Shift + P
and select the.NET: Build
option from the list.
- Press the command keys
- Using command line:
- Run the following command to build the project:
$ dotnet build
- Run the following command to build the project:
The output APK in all cases will be stored in the bin/Debug/net8.0-android
directory.
Preparing the Development Kit¶
If you have the Ezurio Nitrogen 8MPlus Development Kit just follow the instructions here to flash the Kynetics Evaluation BSP. The procedure is independent from the specific Android OS version we support for the Nitrogen 8MPlus SoM Module.
NOTE: The Ezurio Nitrogen 8Mplus development kit comes with a LVDS display. In our set up instead we connect the The Nitrgen 8MPlus SOM and Carrier board to an HDMI display which is an equally functional configuration for the purpose of building and running a MAUI applications.
For any other Ezurio SOM or SBC you may want to use for the purpose of deployng .NET MAUI applications, make sure to have access to the Evaluation BSP and refer to the proper documentation.
Deploying the application¶
-
Using Jetbrains Rider:
- From the Run menu, select the edit configurations option.
- Create a new configuration and Select the
Android
option under the multiplatform category. - Leave all the options except the name to default and click OK.
- From the Run menu, select Run and then select the newly created configuration.
- The application will be deployed to the connected H/W development kit or eventually the emulator.
-
Using VSCode or Command line:
- Connect the Development kit via USB and run
$ adb devices
- Make sure the devices replyes with its serial number (so the device is actually connected and responsive)
- Run the following command to deploy the application:
$ adb install -r bin/Debug/net8.0-android/<application-package-name>-Signed.apk
- Connect the Development kit via USB and run
Debugging the application¶
- Using Jetbrains Rider:
- Set breakpoints in the code where you want to pause the execution. (By clicking on the left margin of the code editor)
- From the Run menu, select Debug and then select the configuration created in last section.
- The application will be deployed to the connected Android device or emulator and the debugger will pause at the breakpoints.
Building GPIO Manager MAUI App using Kynetics Android SDK Estension¶
Kynetics provides a series of Android SDK estensions to allow you control programmatically different I/O and peripherals commonly used on Embedded Systems. To know more about Android SDK Estensions refer to our product page. Using our GPIO SDK Extension you can easily control all your GPIOs from Java, Kotlin and C#.
Now that you know how to build a MAUI .NET application, we want to show how we build a more complex application like our GPIO Manager with MAUI. The GPIO Manager App is a tool, that uses our GPIO SDK Estension library to export, assign input/output roles and monitor the state of GPIOs. We include the GPIO Manager app (with other useful tools for CAN, serial 232/485, SPI, i2C, PWM and Ethernet) in all our Android Evaluation BSPs to show how manage GPIOs from an Android App. Contact us for any questions on the SDK Extension license.
- Open the project with the sources in Jetbrains Rider or Visual Studio Code.
- Copy the licensed GPIO SDK Extension library aar file to the Jars directory and rename it to
android-libgpiod.aar
. - To build the project, we follow the steps outlined in the previous sections.
This is how the app we built looks like.
Conclusion¶
MAUI .NET is a transformative tool for Android app development on embedded systems, offering a unified framework that simplifies the creation of applications for embedded by Windows C# developers. Android has matured significantly for embedded product development, offering robust tools, extensive libraries, and a versatile OS. Android's powerful SDK provides comprehensive tools for creating dynamic, user-friendly UIs, essential for kiosk applications. Coupled with its mature OS security features, Android is a reliable choice for secure, interactive kiosk solutions deployments. Overall, MAUI .NET and its combination with Android OS stands out as a powerful, efficient, and future-proof solution for modern Android embedded products. For any further information about .NET MAUI and Android, contact us.
Resources: