This folder contains an example integration of the Memfault SDK using the port
provided in ports/zephyr
The demo was tested using the STM32L4 Discovery kit.
However, the example application can be compiled for any other ARM Cortex-M
board supported by Zephyr such as the nRF52840 (--board=nrf52840dk_nrf52840
).
For the purposes of this demo we will be using the v2.5 release of Zephyr.
Make sure you have read the instructions in the README.md
in the root of the
SDK and performed the installation steps that are mentioned there.
We assume you already have a working Zephyr toolchain installed locally. Step-by-step instructions can be found in the Zephyr Documentation.
- Clone the repo
$ git clone git@github.com:zephyrproject-rtos/zephyr.git --branch v2.5-branch zephyr
- Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate
pip install -r zephyr/scripts/requirements.txt
- Initialize a new build environment:
$ west init -l zephyr/
$ west update
- When using the STM32L4 discovery board, the following patch is also needed due to bugs in the stack:
diff --git a/drivers/wifi/eswifi/Kconfig.eswifi b/drivers/wifi/eswifi/Kconfig.eswifi
index 6468b98113..5f80c918cd 100644
--- a/drivers/wifi/eswifi/Kconfig.eswifi
+++ b/drivers/wifi/eswifi/Kconfig.eswifi
@@ -9,7 +9,7 @@ menuconfig WIFI_ESWIFI
select WIFI_OFFLOAD
select NET_OFFLOAD
select NET_SOCKETS
- select NET_SOCKETS_OFFLOAD
+ imply NET_SOCKETS_OFFLOAD
select GPIO
if WIFI_ESWIFI
diff --git a/drivers/wifi/eswifi/eswifi_socket.c b/drivers/wifi/eswifi/eswifi_socket.c
index e31ca0eecd..119f55778d 100644
--- a/drivers/wifi/eswifi/eswifi_socket.c
+++ b/drivers/wifi/eswifi/eswifi_socket.c
@@ -301,6 +301,6 @@ int __eswifi_socket_new(struct eswifi_dev *eswifi, int family, int type,
k_delayed_work_init(&socket->read_work, eswifi_off_read_work);
socket->usage = 1;
LOG_DBG("Socket index %d", socket->index);
-
+ net_context_set_state(socket->context, NET_CONTEXT_CONNECTED);
return socket->index;
}
An API key will need to be baked into the demo app
to enable it to communicate with Memfault's web services. Go to
https://app.memfault.com/, navigate to the project you want to use and select
'Settings'. Copy the 'Project Key' and paste it into
$MEMFAULT_SDK/examples/zephyr/apps/memfault_demo_app/src/main.c
, replacing
<YOUR PROJECT KEY HERE>
with your Project Key.
$ cd $MEMFAULT_SDK/examples/zephyr/
$ west build -b disco_l475_iot1 apps/memfault_demo_app
[...]
[271/271] Linking C executable zephyr/zephyr.elf
The build can be flashed on the development board using west flash
( See
Zephyr
"Building, Flashing, & Debugging" documentation)
Or, alternatively, if you are using a SEGGER JLink:
- In one terminal, start a GDB Server
$ JLinkGDBServer -if swd -device STM32L475VG
- In another terminal, load
zephyr.elf
with GDB:
arm-none-eabi-gdb-py --eval-command="target remote localhost:2331" --ex="mon reset" --ex="load"
--ex="mon reset" --se=build/zephyr/zephyr.elf
At this point, the application should be running and you can open a console:
$ miniterm.py /dev/cu.usbmodem* 115200 --raw
*** Booting Zephyr OS build zephyr-v2.5.0-56-gec0aa8331a65 ***
<inf> <mflt>: GNU Build ID: c20cef04e29e3ae7784002c3650d48f3a0b7b07d
<inf> <mflt>: S/N: DEMOSERIAL
<inf> <mflt>: SW type: zephyr-app
<inf> <mflt>: SW version: 1.0.0+c20cef
<inf> <mflt>: HW version: disco_l475_iot1
[00:00:00.578,000] <inf> mflt: Memfault Demo App! Board disco_l475_iot1
uart:~$
uart:~$ mflt help
mflt - Memfault Test Commands
Subcommands:
reboot :trigger a reboot and record it using memfault
get_core :gets the core
clear_core :clear the core
crash :trigger a crash
hang :trigger a hang to test watchdog functionality
export :dump chunks collected by Memfault SDK using
https://mflt.io/chunk-data-export
trace :Capture an example trace event
get_device_info :display device information
post_chunks :Post Memfault data to cloud
trigger_heartbeat :Trigger an immediate capture of all heartbeat metrics
get_latest_release :checks to see if new ota payload is available
Command mflt crash 1
will trigger a hard fault due to a bad instruction fetch
at a non-existing address, 0xbadcafe
:
uart:~$ mflt crash 1
... etc ...
Upon crashing, a coredump will be written to noinit RAM.
To check whether the coredump has been captured, try running the get_core
command after the device reboots:
uart:~$ mflt get_core
<inf> <mflt>: Has coredump with size: 580
This confirms that a coredump of 580 bytes has been captured.
Memfault needs the symbols for the firmware in order to analyze the coredump.
The ELF is located at build/zephyr/zephyr.elf
. This .elf contains the symbols
(debug information) amongst other things.
More information on creating Software Versions and uploading symbols can be found here.
Before we can send the coredump, we need to make sure WiFi is connected to the
internet. Type wifi connect <SSID> <SSID_STRLEN> 0 <PASSWORD>
in the console.
You should see something like:
Connection requested
Connected
uart:~$
Once connected, type mflt post_msg
and press enter. You should see:
uart:~$ mflt post_msg
<dbg> <mflt>: Memfault Message Post Complete: Parse Status 0 HTTP Status 202!
<dbg> <mflt>: Body: Accepted
<dbg> <mflt>: Memfault Message Post Complete: Parse Status 0 HTTP Status 202!
<dbg> <mflt>: Body: Accepted
<dbg> <mflt>: No more data to send
A coredump is now being processed by Memfault's services and will show up
shortly under Issues. If it does not, take a look at the FAQ in the README.md
in the root of the SDK.
The network stack dependencies can also be disabled completely by using the
CONFIG_MEMFAULT_HTTP_SUPPORT
Kconfig option.
When using a board that does not have a network stack enabled or for debug
purposes, the messages to push to the Memfault cloud can also be dumped from the
CLI using the mflt export
command:
uart:~$ mflt export
<inf> <mflt>: MC:CAKmAgIDAQpqemVwaHlyLWFwcAlsMS4wLjArYzIwY2VmBm9kaXNjb19sNDc1X2lvdDEEogECBQD8Fw==:
You can then copy and paste the output into the "Chunks Debug" view in the Memfault UI for your project https://app.memfault.com/