Base Nerves system configuration for the BeagleBone-based boards
Clone or download
Permalink
Failed to load latest commit information.
.circleci Bump Docker container on CI and Elixir version Sep 20, 2018
assets/images Update readme with more information about image May 12, 2016
fwup_include Remove empty line Sep 10, 2018
linux Remove sw watchdog since the OMAP watchdog works Mar 19, 2018
rootfs_overlay Add provisioning.conf and include it in fwup.conf Aug 20, 2018
test Update to nerves 1.3 and bump deps Sep 20, 2018
uboot Bump u-boot to 2017.09 Oct 26, 2017
.formatter.exs mix format Mar 14, 2018
.gitignore Sync .gitignore with other systems Mar 17, 2018
CHANGELOG.md v1.4.0 Aug 28, 2018
CODE_OF_CONDUCT.md Add links to contribution guides Aug 28, 2018
CONTRIBUTING.md Add links to contribution guides Aug 28, 2018
ISSUE_TEMPLATE.md Add links to contribution guides Aug 28, 2018
LICENSE updated license and package info for hex Apr 3, 2016
README.md Add provisioning.conf and include it in fwup.conf Aug 20, 2018
VERSION v1.4.0 Aug 28, 2018
busybox.fragment Switch to busybox fragment for easier maintainance Aug 8, 2018
fwup-revert.conf Pull in the latest revert updates and nerves_system_br Jan 7, 2018
fwup.conf Add provisioning.conf and include it in fwup.conf Aug 20, 2018
mix.exs Bump nerves requirement to 1.3.0 Sep 10, 2018
mix.lock Update to nerves 1.3 and bump deps Sep 20, 2018
nerves_defconfig rng-tools is now enabled by default Sep 20, 2018
post-build.sh Add provisioning.conf and include it in fwup.conf Aug 20, 2018
post-createfs.sh Buildroot 2016.11.1 BR2_EXTERNAL update Jan 18, 2017
uboot-script.cmd Move uboot patches out of nerves_system_br Aug 8, 2016

README.md

Generic BeagleBone Support

CircleCI Hex version

This is the base Nerves System configuration for the BeagleBone Black, BeagleBone Green, BeagleBone Green Wireless, and PocketBeagle.

BeagleBone Black image
Image credit

Feature Description
CPU 1 GHz ARM Cortex-A8
Memory 512 MB DRAM
Storage 4 GB eMMC Flash and MicroSD
Linux kernel 4.4 w/ BBB patches
IEx terminal ttyGS0 via the USB
GPIO, I2C, SPI Yes - Elixir ALE
ADC Yes
PWM Yes, but no Elixir support
UART ttyS0 + more via device tree overlay
Camera None
Ethernet Yes
WiFi Beaglebone Green Wireless (wl18xx driver). Other requires USB WiFi dongle/driver

Using

The most common way of using this Nerves System is create a project with mix nerves.new and to export MIX_TARGET=bbb. See the Getting started guide for more information.

If you need custom modifications to this system for your device, clone this repository and update as described in Making custom systems

If you're new to Nerves, check out the nerves_init_gadget project for creating a starter project. It will get you started with the basics like bringing up networking, initializing the writable application data partition, and enabling ssh-based firmware updates. It's easiest to begin by using the wired Ethernet interface 'eth0' and DHCP.

Preparing your BeagleBone

If your BeagleBone has eMMC (the PocketBeagle doesn't), it will be configured to try the eMMC first when looking for software on boot. If you haven't reprogrammed it, it will boot to Debian even if a MicroSD card is inserted with good software. To boot from the MicroSD card, hold down the USER button and apply power.

When starting with Nerves, you will find that booting from a MicroSD card is convenient since you can easily recover from broken software images. Holding down the USER button will get old. To force the BeagleBone to boot from the MicroSD card, simply corrupt the image on the eMMC memory. Don't worry, the BeagleBone website has instructions for restoring Debian.

From Debian:

debian@beaglebone:~$ sudo dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 5.72098 s, 18.3 MB/s
debian@beaglebone:~$ sudo reboot

When it reboots, it will boot from the MicroSD slot. If a MicroSD card hasn't been inserted or if there are errors reading it, you will see the letter C printed repeatedly on the console port.

Console access

The console is configured to output to ttyGS0 by default. This is output through a USB cable connected to the BeagleBone's OTG USB port. It will show up on the connected computer as a virtual serial port.

It is also possible to configure the IEx prompt through the 6 pin header on the BeagleBone that's labeled J1. A 3.3V FTDI cable is needed to access the output. To use this output, override the default erlinit.config and specify that the output should go to ttyS0.

The HDMI output has been disabled via device tree to free up pins on the GPIO header. If you would like console access via HDMI, you will need to enable HDMI support in the Linux kernel, remove the HDMI disable argument in the uboot script providing kernel arguments, and change erlinit.conf to output to tty1.

Provisioning devices

This system supports storing provisioning information in a small key-value store outside of any filesystem. Provisioning is an optional step and reasonable defaults are provided if this is missing.

Provisioning information can be queried using the Nerves.Runtime KV store's Nerves.Runtime.KV.get/1 function.

Keys used by this system are:

Key Example Value Description
nerves_serial_number "1234578"` By default, this string is used to create unique hostnames and Erlang node names. If unset, it defaults to part of the BBB's serial number.

The normal procedure would be to set these keys once in manufacturing or before deployment and then leave them alone.

For example, to provision a serial number on a running device, run the following and reboot:

iex> cmd("fw_setenv nerves_serial_number 1234")

This system supports setting the serial number offline. To do this, set the NERVES_SERIAL_NUMBER environment variable when burning the firmware. If you're programming MicroSD cards using fwup, the commandline is:

sudo NERVES_SERIAL_NUMBER=1234 fwup path_to_firmware.fw

Serial numbers are stored on the MicroSD card so if the MicroSD card is replaced, the serial number will need to be reprogrammed. The numbers are stored in a U-boot environment block. This is a special region that is separate from the application partition so reformatting the application partition will not lose the serial number or any other data stored in this block.

Additional key value pairs can be provisioned by overriding the default provisioning.conf file location by setting the environment variable NERVES_PROVISIONING=/path/to/provisioning.conf. The default provisioning.conf will set the nerves_serial_number, if you override the location to this file, you will be responsible for setting this yourself.

Linux versions

The BeagleBone Black has many options for Linux that vary by kernel version and patch set. Nerves tracks those maintained by Robert Nelson at eewiki.net. His patch sets have -rt and -ti/-bone options. The -rt for real-time actually refers to CONFIG_PREEMPT and a couple other real-time options being configured in the Linux kernel. Nerves uses those options as well. Nerves follows the -ti patch set. See nerves_system_br/boards/bbb for the actual patches.

Be aware that if you have been using Linux kernel 3.8 on the BeagleBone, that there have been device tree overlay and PRU updates. File paths have changed for inserting device tree overlays.

Device tree overlays

Most pins on the BBB's headers are configurable via the device tree. Configuration can be done at runtime via the Universal I/O device tree overlays. These overlays are included in the kernel configuration for Nerves so you do not need to compile that project. Additionally, the config-pin script is available in /usr/bin on the target. It has minor modifications to run on Nerves.

Universal I/O

The universal I/O overlays can be loaded manually or by using the config-pin shell script:

iex(demo@nerves-0099)> :os.cmd('config-pin overlay cape-universaln')
'Loading cape-universaln overlay\n'
iex(demo@nerves-0099)> :os.cmd('config-pin -i P9_16') |> IO.puts
Pin name: P9_16
Function if no cape loaded: gpio
Function if cape loaded: default gpio gpio_pu gpio_pd pwm
Function information: gpio1_19 default gpio1_19 gpio1_19 gpio1_19 ehrpwm1B
Cape: cape-universala cape-universal cape-universaln
Kernel GPIO id: 51
PRU GPIO id: 83

:ok
iex(demo@nerves-0099)> :os.cmd('config-pin P9_16 pwm')

ADCs

The following example shows how to read values from the 7 ADC inputs in Elixir.

iex(demo@nerves-0099)> File.write("/sys/devices/platform/bone_capemgr/slots","BB-ADC")
:ok
iex(demo@nerves-0099)> ls "/sys/bus/iio/devices/iio:device0"
buffer              dev                 in_voltage0_raw     in_voltage1_raw
in_voltage2_raw     in_voltage3_raw     in_voltage4_raw     in_voltage5_raw
in_voltage6_raw     name                of_node             power
scan_elements       subsystem           uevent
iex(demo@nerves-0099)> File.read("/sys/bus/iio/devices/iio:device0/in_voltage0_raw")
{:ok, "3891\n"}
iex(demo@nerves-0099)> File.read("/sys/bus/iio/devices/iio:device0/in_voltage0_raw")
{:ok, "3890\n"}
iex(demo@nerves-0099)> File.read("/sys/bus/iio/devices/iio:device0/in_voltage0_raw")
{:ok, "3891\n"}

SPI

The following examples shows how to get SPI0 functional in Elixir.

Load the overlay, configure the pins, and load the device drivers:

Note: The order of the above stops is important. The overlay must be loaded and the pins configured before writing "BB-SPIDEV0".

iex(demo@nerves-0099)1> :os.cmd('config-pin overlay cape-universaln')
'Loading cape-universaln overlay\n'
iex(demo@nerves-0099)2> [17,18,21,22] |> Enum.each(&(:os.cmd('config-pin -a  P9_#{&1} spi')))
:ok
iex(demo@nerves-0099)3> File.write("/sys/devices/platform/bone_capemgr/slots","BB-SPIDEV0")
{:error, :eexist}

Verify that the device drivers are loaded and read spi0 transfers:

iex(demo@nerves-0099)4> ls "/dev"
  ...
        spidev1.0              spidev1.1              spidev2.0              spidev2.1
  ...
iex(demo@nerves-0099)5> File.read "/sys/bus/spi/devices/spi1.0/statistics/transfers"
{:ok, "0"}

Verify that the pins are configured:

iex(demo@nerves-0099)6> [17,18,21,22] |> Enum.map(&(:os.cmd('config-pin -q  P9_#{&1} spi')))
['P9_17 Mode: spi\n', 'P9_18 Mode: spi\n', 'P9_21 Mode: spi\n', 'P9_22 Mode: spi\n']

If you have included ElixirAle as a dependency, you can start it now and test a transfer:

The example below should work without any additional hardware connected to the BBB. If you have SPI hardware connected to the BBB, your returned binary might be different.

iex(demo@nerves-0099)7> Spi.start_link "spidev1.0", [], name: :spi0
{:ok, #PID<0.181.0>}
iex(demo@nerves-0099)8> Spi.transfer :spi0, <<1,2,3,4>>
<<255, 255, 255, 255>>

Note: If you get back all 0's, then you have likely have not configured the overlay pins correctly.

Supported USB WiFi devices

The base image includes drivers and firmware for the TI WiLink8 (wl18xx), Ralink RT53xx (rt2800usb driver) and RealTek RTL8712U (r8712u driver) devices. All WiFi drivers are compiled as modules. Currently, Nerves doesn't autoload the drivers, so you'll need to load them at the beginning of your application. For example, run :os.cmd('modprobe wl18xx') if you're using a BeagleBone Green Wireless.

We are still working out which subset of all possible WiFi dongles to support in our images. At some point, we may have the option to support all dongles and selectively install modules at packaging time, but until then, these drivers and their associated firmware blobs add significantly to Nerves release images.

If you are unsure what driver your WiFi dongle requires, run Raspbian and configure WiFi for your device. At a shell prompt, run lsmod to see which drivers are loaded. Running dmesg may also give a clue. When using dmesg, reinsert the USB dongle to generate new log messages if you don't see them.

Beaglebone Green WiFi

Initial support for the BBGW's onboard wireless module is available. To try it out, run (assuming you have Nerves.InterimWiFi in your image):

:os.cmd('modprobe wl18xx')
:os.cmd('modprobe wlcore-sdio')
Nerves.InterimWiFi.setup "wlan0", ssid: "xxx", key_mgmt: :"WPA-PSK", psk: "yyy"

Be aware that this Nerves system does not configure the MAC address. The result is that only one BBGW may exist on the WiFi network at a time.

Installation

If you're new to Nerves, check out the nerves_init_gadget project for creating a starter project for the Beaglebone boards. The instructions are basically the same for the Raspberry Pi Zero or Zero W except you should export MIX_TARGET=bbb so that the appropriate mix targets get run. It will get you started with the basics like bringing up the virtual Ethernet interface, initializing the application partition, and enabling ssh-based firmware updates.

Image credit: This image is from the Fritzing parts library.