Getting Started

The reference hardware platform for Basic MAC is the B-L072Z-LRWAN1 STM32 LoRa™ Discovery kit.

The shell variable $MACREPO is used below to refer to your local Basic MAC directory.

Prerequisites

Toolchain

It is recommended to use a recent Linux distribution as build host. To build a Basic MAC project, you must have an appropriate cross-compile toolchain installed.

We use Ubuntu 19.04 (Disco Dingo) with gcc-arm-embedded.

Python 3.6 or newer

The build environment uses a number of tools that are written in Python. An environment with a Python 3.6 interpreter or newer is required. Further, the following Python packages must be installed (e.g. using pip3 install):

  • Click
  • intelhex
  • PyYAML

Further, to use the simulation environment, the following packages are also required:

  • colorama
  • intervaltree
  • numpy
  • pycryptodome
  • unicorn

OpenOCD

To load firmware onto actual hardware, a tool such as OpenOCD must be used. On Ubuntu, you can install it using sudo apt install openocd.

Cloning the Repository

Clone the repository from GitHub:

$ git clone https://github.com/lorabasics/basicmac.git $MAC_REPO

Basic MAC contains Git submodules that must be initialized:

$ cd $MAC_REPO
$ git submodule update --init

Build Process

Building the Bootloaders

The Basic MAC HAL for STM32 employs a bootloader, Basic Loader, to load and start the actual firmware. This bootloader also applies any firmware updates and verifies the integrity of the current firmware before calling the firmware’s entrypoint.

To build Basic Loader, change to the basicloader directory and type make:

$ cd $MAC_REPO/basicloader
$ make

The output of the build process for each supported platform is a file named bootloader.hex.

Building a Project

Projects are built from their respective subfolder in the projects directory. A simple example project is the Join Example project in $MAC_REPO/projects/ex-join.

Build settings, such as target platform, compile time and configuration options are specified in the project’s Makefile.

To build a project, simply change into the project’s directory and run make:

$ cd $MAC_REPO/projects/ex-join
$ make

Multiple variants of a project can be built, such as versions for different regions, or platforms. The Join Example project builds four variants: eu868, us915, hybrid (supports both EU868 and US915), and simul (for use with the simulation environment).

The output files of the build process are stored in the project’s build-<variant> folders, with the firmware hex file having the same name as the project with a .hex extension; in this case ex-join.hex.

Loading a Project

After a project is built, it can be loaded onto a device. Note that both the bootloader and the firmware must be loaded, although since the bootloader rarely changes, it is generally only loaded once.

Note

You may need to install udev rules to grant permissions to regular users for accessing the ST-LINK device. You can install these using the tar file provided in the Basic MAC repository with following command:

$ sudo tar xzvf $MAC_REPO/tools/openocd/stlink-rules.tgz -C /etc/udev/rules.d/

To load the bootloader and the firmware, respectively, use the loadbl and load make targets:

$ make loadbl       # if not already done previously
$ make load

If multiple variants are present, this will load the default variant, which is generally the first variant specified in the project’s Makefile.

Personalization

The HAL for STM32 stores personalization information such as EUIs and keys for LoRaWAN operation in EEPROM.

If no valid personalization information is found in EEPROM, the HAL will create a device EUI from the MCU’s Unique ID registers, and use a fixed Join EUI and test key:

  • Device EUI: FF-FF-FF-AA-xx-xx-xx-xx
  • Join EUI: FF-FF-FF-BB-00-00-00-00
  • Device Key: 404142434445464748494A4B4C4D4E4F

Viewing Debug Output

On the B-L072Z-LRWAN1, the firmware prints debug information to the UART that is connected via the ST-LINK to the host computer. On Linux, this device usually shows up as /dev/ttyACM0. Use a serial terminal application to connect to that port, using 115200/8-N-1; for example using miniterm.py:

$ miniterm.py /dev/ttyACM0 115200

--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

============== DEBUG STARTED ==============
id: FF-FF-FF-AA-2B-05-01-41 | sn:  | hw: 0x000 | flash: 192K
bl: v256 | fw: ex-join eu868 0x00000000 0x8B27E203 | boot: normal
Hello World!
switching mode: normal
lwm: JOINING
lwm: TXSTART
TX[freq=868.1,sf=7,bw=125,len=23]: 0000000000BBFFFFFF4101052BAAFFFFFFECF2B6412021
lwm: TXDONE

...

Simulation

The Join Example has support for running the LoRaWAN Certification test suite within the device simulation using the test make target of the simul variant:

$ VARIANT=simul make test

PYTHONPATH=${PYTHONPATH}:../../tools/pylora:../../unicorn/simul \
           ../../unicorn/simul/lwtest.py \
           -r EU868 \
           -v -d -t \
            \
           ../../basicloader/build/boards/simul-unicorn/bootloader.hex \
           build-simul/ex-join.hex
15 test cases collected
_________________________________________________________
Running LWTest.enter_testmode...

============== DEBUG STARTED ==============
id: FF-FF-FF-AA-DE-AD-BE-EF | sn:  | hw: 0x000 | flash: 128K
bl: v256 | fw: ex-join simul 0x00000000 0xFA1C2F89 | boot: normal
Hello World!
switching mode: normal
lwm: JOINING
lwm: TXSTART
D->N: xbeg=5.802368, xend=5.864064, freq=868100000, sf=7, bw=125000, data=0000000000bbffffffefbeaddeaaffffff0000395a3849 -- JREQ(rfu=0, mjr=0) deveui=FF-FF-FF-AA-DE-AD-BE-EF joineui=FF-FF-FF-BB-00-00-00-00 devnonce=0 mic=1228429881

...
...

D->N: xbeg=1523.687683, xend=1523.734019, freq=868100000, sf=7, bw=125000, data=4002c3d452802601e035ed669dcbe5 -- DAUP(rfu=0, mjr=0) addr=0x52d4c302 fctrl=ADR fcnt=294 fport=224 plen=2 data=0002 mic=-439640730:ok
_________________________________________________________
Real time:      000d 00:00:39.593
Simulated time: 000d 01:16:42.585
_________________________________________________________
Results:

  1 LWTest.enter_testmode .......................... pass
  2 LWTest.app_functionality ....................... pass
  3 LWTest.otaa .................................... pass
  4 LWTest.rx2_per ................................. pass
  5 LWTest.crypto .................................. pass
  6 LWTest.dl_timing ............................... pass
  7 LWTest.frame_seqno ............................. pass
  8 LWTest.dev_status_req .......................... pass
  9 LWTest.mcmd_invalid ............................ pass
 10 LWTest.new_channel_req ......................... pass
 11 LWTest.dl_channel_req .......................... pass
 12 LWTest.conf_packets ............................ pass
 13 LWTest.rx_param_setup_req ...................... pass
 14 LWTest.rx_timing_setup_req ..................... pass
 15 LWTest.link_adr_req ............................ pass
_________________________________________________________
15/15 tests passed.