Developing for Nordic, LooUQ’s Journey
Every journey starts somewhere; this one starts here. LooUQ has been developing firmware and embedded hardware since 2016. We do build our integration cloud, LQcloud, and some consulting too. But this is a story about how we became a follower of Nordic Semiconductor and melded it into our world. Even after developing for Microchip, NXP, ST, and Espressif, I have found that Nordic has some twists that one needs to follow closely. The goal of this series is to publish quick, concise articles about something learnt the hard way; hoping our challenge solved can help one of you.
Each of the follow-on posts will cover one, maybe two topics, that require more digging than one would hope and now it is internal knowledge for our team. The goal of this post series… make theses topics external knowledge that is useful to your team.
Throughout the series most topics came from our development around the nRF91 series, mostly the nrf9151, the examples will use either the nRF9151 DK or our MTC2-N9151 modem and Breakout shown here. The Nordic tools are extensions installed into VS Code.
LooUQ MTC2-N9151 Modem and MTC2-Breakout board
First off, go do some things to make this all work out…
Get a Nordic DK board of your desired flavor, they are readily available and reasonably priced.
Go to the Nordic Developer Academy and start learning.
Invest in a Segger J-Link, you can get new ones from DigiKey, Mouser, or other distributors. Check out eBay for a used one, I got one on there for a great price that has been working here for 5 years.
If you have time, funds and interest consider purchasing the LooUQ N9151 cellular modem.
All of the topics and examples in the series will be using the
Using Segger RTT
Segger J-Link software comes with an utility called RTT, Real-Time Terminal. RTT is fast, low impact on your project’s MCU and has a great outboard viewer shown below.
Recently I found myself throwing #include statements in source and CONFIG statements at my proj.conf file to get various debugging print statements to work. I was in a hurry and simply needed to test something not related to printing diagnostic messages.
In summary there are two basic facilities for outputting messages to an RTT viewer from your code.
Console output
LOG system output
The main.c file below shows both, plus a common Zephyr approach: printk.
main.c
#include <stdio.h> // required to build in printf and its variants #include <zephyr/logging/log.h> // required to use LOG_ facilities LOG_MODULE_REGISTER(main); // MACRO to setup this compilation unit for log support // Generally you want to register a different name for every file/facility int main(void) { printf("Hello World! %s\n", CONFIG_BOARD_TARGET); LOG_INF("LOG can say Hello World too."); printk("It is also possible to use printk... Hello world!"); return 0; }
proj.conf
# to use Segger RTT in any capacity CONFIG_USE_SEGGER_RTT=y # setup CONSOLE behavior CONFIG_CONSOLE=y CONFIG_RTT_CONSOLE=y CONFIG_UART_CONSOLE=n # setup LOG facility behavior CONFIG_LOG=y CONFIG_LOG_PRINTK=y CONFIG_LOG_MODE_IMMEDIATE=y
Using RTT
Add CONFIG_USE_SEGGER_RTT to add the necessary code to your build. No RTT functionality is present without this config option.
Console
Console supports use of the printf() family of code statements and the Zephyr printk() function. It is worth noting that the printk() function by default outputs to the console, however the console is configured.
To use console output…
Add include for stdio.h in your source
Add CONFIG_CONSOLE to your proj.conf and specify the destination
Add printf() or printk() when you want to send information to RTT
LOG
The LOG output apparently is a completely independent stream of content. It even looks different on the output in RTT Viewer.
To use the LOG subsystem…
Add #include <zephyr/logging/log.h> in your source
Register the name for this source file’s log stream
Use LOG_INF or other variants (LOG_WARN, LOG_ERR) to output
Note that WARN and ERR options color code the output in RTT for Terminal 0
To have LOG statement appear immediately in the RTT viewer use the CONFIG_LOG_MODE_IMMEDIATE=y option in your proj.conf.