Zephyr SDK
note-zephyr is the official Zephyr SDK
for communicating with the Notecard over serial or I2C. In this article, you'll
learn how to use note-zephyr
to upgrade the Zephyr RTOS "blinky" example with
Notecard Communication!
See
note-zephyr
in action in these accelerator projects.
Overview
This example is designed to illustrate the ease of adding Notecard functionality
to an existing application, by building on the original Zephyr example,
samples/basic/blinky
.
Functionally, the modification slows down the processing loop from 1s to 10s, and submits a Note to Notehub indicating the current state of the onboard LED.
Requirements
Hardware
Software
- Docker
- Visual Studio Code (VS Code)
- VS Code "Dev Containers" Extension
- Windows/Mac Debugging OpenOCD
Cloudware
Getting Set Up
Notehub.io
Before you can utilize this example, you must set up a free account (no credit card required) on Notehub.io. Once you have created your account, then you need to create a project to serve as an endpoint for the Notes that are tracking the state of the LED.
Once you have a project, you will need to update the define
named
PROJECT_UID
in main.c
with the UID of the project you have just
created.
After the Notecard has connected to Notehub, you can look inside the project
and see a device named zephyr-blink
. The Notecard will be running in
continuous
mode, which will allow it to maintain a constant cellular
connection. continuous
mode offers the lowest latency possible for sending
messages to Notehub, but it comes at the cost of battery life. Fortunately,
this is typically not a concern while bench testing, because you are plugged
into USB power.
To learn more about the Notecard modes and API, please visit our Essential Requests Walkthrough.
Cloning the Repository
This repository contains the note-c
library as a submodule. Use the following
command to clone both repositories simultaneously.
git clone https://github.com/blues/note-zephyr.git --recursive
If you cloned without the --recursive
flag, then you can update the note-c
submodule separately, using the following two commands:
git submodule init
git submodule update
Building the Dev Container
This step is critical to ensure you correctly build the Dev Container image.
Linux:
To enable flashing and debugging from the container on Linux, you will need to provide access to the USB controller of the host machine.
Perform the following steps, in order to provide USB access:
-
Open
./.devcontainer/devcontainer.json
. -
Uncomment the
runArgs
section:// Uncomment the following section if your host machine is running Linux "runArgs": [ "--device=/dev/bus/usb/" ],
note At the time of writing, it is not possible to share the host USB from Windows and Mac computers.
Windows/Mac (x86_64):
Ensure Docker Desktop is running.
ARM 64 (aarch64):
-
Open
./.devcontainer/devcontainer.json
. -
Uncomment the
args
object in thebuild
section:// Uncomment the following section if your host machine silicon is ARM64 "args": { "HOST_ARCH":"aarch64" },
If you failed to properly update devcontainer.json
before opening the Dev
Container, you may need to purge your docker build cache before trying again.
docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N] y
Building and Running
Compiling
- Open this folder in VS Code.
- Reopen the folder in the Dev Container.
- Press the hotkey combination,
Ctrl+Shift+P
(Mac:Cmd+Shift+P
). - Select Dev Containers: Rebuild and Reopen in Container from the command palette drop-down menu.
- Press the hotkey combination,
- Build the binary using one of the following options:
- Press the hotkey combination,
Ctrl+Shift+B
(Mac:Cmd+Shift+B
). - Use the menu system:
- Select Terminal > Run Task... from the application menu.
- Select Zephyr: Build Application from the drop-down menu.
- Press the hotkey combination,
If you see the following message, then you have failed to update the product UID in the sources, and the Notecard will not be linked with your Notehub project.
/workspaces/note-zephyr/src/main.c:26:9: note: '#pragma message: PRODUCT_UID is not defined in this example. Please ensure your Notecard has a product identifier set before running this example or define it in code here. More details at https://bit.ly/product-uid'
26 | #pragma message "PRODUCT_UID is not defined in this example. Please ensure your Notecard has a product identifier set before running this example or define it in code here. More details at https://bit.ly/product-uid"
| ^~~~~~~
Flashing
Linux:
From the Dev Container, use the menu system:
- Select Terminal > Run Task... from the application menu.
- Select Zephyr: Flash Firmware (Container) from the drop-down menu.
Windows/Mac:
-
Launch Debug Server (OpenOCD)
A debugging server opens a port to receive both debug and program instructions. Then, it forwards those instructions to the target device via an in-circuit debugger and programmer, such as the STLINK-V3MINI.
Execute the following command on your host machine, OUTSIDE the container:
openocd --search /usr/share/openocd/scripts --file interface/stlink.cfg --command "transport select hla_swd" --file target/stm32l4x.cfg
-
From the Dev Container, use the menu system:
- Select Terminal > Run Task... from the application menu.
- Select Zephyr: Flash Firmware (External) from the drop-down menu.
You must flash your device using the STLINK-V3MINI; DFU is not supported.
Debugging
Collecting Serial Logs
LPUART has been assigned as the default console output of the Swan. Furthermore,
the LPUART of the Swan is exposed via the JTAG connector. This means that all
strings provided to printk()
will surface through the serial port assigned to
the STLINK-V3MINI. As long as the Swan has power (e.g. battery, VIN
, etc.),
then there is no need for an additional USB cable.
The serial port is configured at 115200 baud, 8-bits, no parity bit, and one (1) stop bit (i.e. 8-N-1).
Using Linux as an example, and assuming the STLINK is the only USB peripheral
plugged into your machine. Then you can expect to find the serial port listed
as /dev/ttyACM0
.
GDB (OpenOCD via STLINK)
Linux:
- Select the appropriate debug configuation.
- From the Run and Debug panel.
- Open the activity bar using one of the following options:
- Press the hotkey combination,
Ctrl+Shift+D
(Mac:Cmd+Shift+D
). - Select the bug and triangle icon.
- Press the hotkey combination,
- Expand the drop-down with the green triangle at the top of the
Run and Debug panel.
- Use the drop-down to confirm Swan Debug (Container) is selected.
- Open the activity bar using one of the following options:
- From the Run and Debug panel.
- Launch the debugger using one of the following options:
- Press green triangle at the top of the Run and Debug panel.
- Select Run > Start Debugging from the application menu.
- Press the function key,
F5
.
Windows/Mac:
-
Launch Debug Server (OpenOCD)
A debugging server opens a port to receive both debug and program instructions. Then, it forwards those instructions to the target device via an in-circuit debugger and programmer, such as the STLINK-V3MINI.
Execute the following command on your host machine, OUTSIDE the container:
openocd --search /usr/share/openocd/scripts --file interface/stlink.cfg --command "transport select hla_swd" --file target/stm32l4x.cfg
-
Launch Debugger (GDB)
A debugger is a piece of software that allows you to step through a binary on a line-by-line basis. When debugging an embedded device, the binary does not reside on the same machine as the debugger, so we need a server (e.g. OpenOCD) to relay the instructions to the remote binary.
- Select the appropriate debug configuation.
- From the Run and Debug panel.
- Open the activity bar using one of the following options:
- Press the hotkey combination,
Ctrl+Shift+D
(Mac:Cmd+Shift+D
). - Select the bug and triangle icon.
- Press the hotkey combination,
- Expand the drop-down with the green triangle at the top of the
Run and Debug panel.
- Use the drop-down to confirm Swan Debug (External) is selected.
- Open the activity bar using one of the following options:
- From the Run and Debug panel.
- Launch the debugger using one of the following options:
- Press green triangle at the top of the Run and Debug panel.
- Select Run > Start Debugging from the application menu.
- Press the function key,
F5
.
- Select the appropriate debug configuation.
Update Existing Zephyr App
The absolute minimum changes required to add the Notecard functionality to a pre-existing Zephyr application.
-
Clone
note-c
into a subfolder of your Zephyr application. -
Add the
note-c
,.c
files from to the Zephyr application inCMakeLists.txt
# Let Zephyr build additional 3rd party libs (e.g. `note-c`) with `app` target_sources(app PRIVATE ${NOTE_C}/n_atof.c PRIVATE ${NOTE_C}/n_b64.c PRIVATE ${NOTE_C}/n_cjson.c PRIVATE ${NOTE_C}/n_cjson_helpers.c PRIVATE ${NOTE_C}/n_const.c PRIVATE ${NOTE_C}/n_ftoa.c PRIVATE ${NOTE_C}/n_helpers.c PRIVATE ${NOTE_C}/n_hooks.c PRIVATE ${NOTE_C}/n_i2c.c PRIVATE ${NOTE_C}/n_md5.c PRIVATE ${NOTE_C}/n_printf.c PRIVATE ${NOTE_C}/n_request.c PRIVATE ${NOTE_C}/n_serial.c PRIVATE ${NOTE_C}/n_str.c PRIVATE ${NOTE_C}/n_ua.c ) target_include_directories(app PRIVATE ${NOTE_C} )
-
Visit the
note-zephyr
GitHub repository, and copy the filesnote_c_hooks.h
andnote_c_hooks.c
into thesrc
folder of your project.... └── src ├── main.c ├── note_c_hooks.c └── note_c_hooks.h
-
Add
note_c_hooks.c
toCMakeLists.txt
.# Compile Zephyr `main` target_sources(app PRIVATE ${SRC}/main.c PRIVATE ${SRC}/note_c_hooks.c )
-
Confirm
CONFIG_NEWLIB_LIBC=y
andCONFIG_I2C=y
are present inprj.conf
CONFIG_NEWLIB_LIBC
is required bynote-c
for string operations.CONFIG_I2C
is required to communicate with the Notecard over the I2C bus.
-
Add Notecard includes to
main.c
#include <note.h>
- Includes thenote-c
library, which provide myriad helper functions to communicate with the Notecard.#include "note_c_hooks.h"
- Includes the system callbacks, used bynote-c
, for the Zephyr platform.
And with that, you're all set up and ready to utilize the Notecard in your existing Zephyr application.