Giter Site home page Giter Site logo

surban / openemc Goto Github PK

View Code? Open in Web Editor NEW
15.0 3.0 2.0 744 KB

OpenEMC: open embedded management controller

Rust 73.86% RPC 0.05% Makefile 0.05% C 25.50% Shell 0.54%
embedded-controller linux rust adc bootloader firmware gpio rtc stm32 watchdog

openemc's Introduction

OpenEMC

OpenEMC is an open-source firmware implementing an embedded management controller (EMC) on an STM32F1 microcontroller. It consists of a bootloader and firmware (both written in Rust) and Linux kernel driver modules (written in C).

Build

Features

The following features are implemented:

  • communication with the host over I2C and one interrupt line
  • field-upgradable firmware
  • full logging to host over I2C in production system
  • power control: system on/off, restart, optional power on when external power supplied
  • watchdog
  • real-time clock (RTC) with alarm and system wake-up
  • GPIO with interrupts
  • pin control
  • analog digital converter (ADC)
  • fully customizable board communication (read, write, ioctl) with Linux userspace via device file
  • battery charger (BQ25713)
  • external power supply with USB PD (STUSB4500) and USB charger detector (MAX14636)
  • charging mode with system power off
  • Linux pstore (persistent storage) integration for kernel panic logs
  • configuration storage in flash memory
  • full devicetree integration

Due to its open-source nature, modular design and usage of the Rust programming language, OpenEMC is easy to extend and adapt to a wide variety of boards and applications.

Evaluation and development

The easiest method to evaluate and hack on OpenEMC is to get an STM32F103 Nucleo-64 board (NUCLEO-F103RB) and connect its I2C bus (SCL, SDA) and D12 pin (IRQ) to a Raspberry Pi or similar board.

Bootloader flashing can be performed using the STLink embedded on the board and requires no additional hardware.

Linux drivers have been tested with Linux v5.19.

Building

Requirements

For building the firmware your machine must have the following things installed:

  • a recent enough stable Rust toolchain (install from https://rustup.rs),
  • Rust target thumbv7m-none-eabi (rustup target add thumbv7m-none-eabi),
  • Rust LLVM utils (rustup component add llvm-tools-preview),
  • on Rust nightly: Rust source (rustup component add rust-src)
  • Cargo binutils (cargo install cargo-binutils),
  • STLINK tools (from https://github.com/stlink-org/stlink or your Linux distribution),
  • for development: probe-run (cargo install probe-run).

For building the Linux kernel drivers the kernel headers and gcc are required. The kernel must have support for devicetree enabled.

Building the firmware image

To build both the bootloader and main firmware, run:

cargo xtask <BOARD_NAME>

They will be placed into the image directory. Here <BOARD_NAME> specifies the name of the board; see openemc-bootloader/src/boards for a list of supported boards. If no board is specified a generic board image will be generated.

This crates four files:

  • openemc_bootloader_*.bin is the bootloader image and should be flashed onto the device,
  • openemc_*.emc is the main firmware and should be placed into the /lib/firmware directory on the target device, where it will be picked up by the driver and sent to the device,
  • *.elf are ELF images of the firmware and used for formatting of log messages; they should be placed in /lib/firmware on the target device if logging is used.

Flashing the bootloader image

Connect the STM32 to your computer using an (integrated) STLink USB adapter. Use st-flash from STLINK tools to flash the bootloader image:

st-flash --connect-under-reset write image/openemc_bootloader_*.bin 0x8000000

Building the kernel driver

Run scripts/driver-build.sh to build the drivers as kernel modules. You can install them using scripts/driver-install.sh.

Logging

Reading logs over I2C and forwarding to syslog is done by openemc-log, which should be built for and placed on the target device. Example files for systemd integration are located in the systemd directory.

Devicetree

The driver will only be loaded if it is referenced in the system's devicetree. Examples are provided in the devicetree directory. Use scripts/devicetree-build.sh to build them and scripts/devicetree-load.sh to dynamically load a devicetree overlay into a running system.

Firmware size considerations

When using a nightly Rust toolchain the core crate is built along with the firmware and optimized for small size. This saves about 2 kBytes of flash memory space.

Development and testing

For development and testing, both the bootloader and main firmware can be flashed and executed directly by invoking

OPENEMC_BOARD=<BOARD_NAME> DEFMT_LOG=info cargo run --release -- --connect-under-reset

from the respective directory. Set the environment variable DEFMT_LOG your desired log level.

Board IO and ioctl

OpenEMC allows direct communication between Linux userspace and board-specific code. For this purpose the device /dev/openemc is provided, which supports reading, writing, polling and ioctls. Corresponding to these operations the board-specific functions Board::io_read, Board::io_write and Board::ioctl are called. An example is provided in the board file stm_nucleo_f103rb.rs together with the host-side code in board-io-test.

License

The OpenEMC firmware is released under the GNU GPL version 3, meaning that you must release the full source code of your modifications if you adapt OpenEMC to your application and/or board.

The OpenEMC drivers are released under the GNU GPL version 2 or later, following the standard license of the Linux kernel. This also requires you to publish all changes you make to the OpenEMC drivers.

Commercial licensing options without these restrictions are available. Please contact us for licensing details..

openemc's People

Contributors

surban avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

grand151 wlksos

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.