Code Monkey home page Code Monkey logo

memfault-firmware-sdk's Introduction

CircleCI Coverage

Memfault Firmware SDK

Ship Firmware with Confidence.

More details about the Memfault platform itself, how it works, and step-by-step integration guides can be found here.

Getting Started

To start integrating in your platform today, create a Memfault cloud account.

Components

The SDK is designed as a collection of components, so you can include only what is needed for your project. The SDK has been designed to have minimal impact on code-space, bandwidth, and power consumption.

The components directory folder contains the various components of the SDK. Each component contains a README.md, source code, header files and "platform" header files.

The platform header files describe the interfaces which the component relies on that you must implement.

For some of the platform dependencies we have provided ports that can be linked into your system directly, or used as a template for further customization. You can find them in the ports folder.

For some of the popular MCUs & vendor SDKs, we have already provided a reference implementation for platform dependencies which can be found in the examples folder. These can also serve as a good example when initially setting up the SDK on your platform.

Main components

  • panics – fault handling, coredump and reboot tracking and reboot loop detection API.
  • metrics - used to monitor device health over time (i.e. connectivity, battery life, MCU resource utilization, hardware degradation, etc.)

Please refer to the README.md in each of these for more details.

Support components

  • core – common code that is used by all other components.
  • demo - common code that is used by demo apps for the various platforms.
  • http – http client API, to post coredumps and events directly to the Memfault service from devices.
  • util – various utilities.

Integrating the Memfault SDK

Add Memfault SDK to Your Repository

The Memfault SDK can be added directly into your repository. The structure typically looks like:

<YOUR_PROJECT>
├── third_party/memfault
│               ├── memfault-firmware-sdk (submodule)
│               │
│               │ # Files where port to your platform will be implemented
│               ├── memfault_platform_port.c
│               ├── memfault_platform_coredump_regions.c
│               │
│               │ # Configuration headers
│               ├── memfault_platform_config.h
│               ├── memfault_trace_reason_user_config.def
│               ├── memfault_metrics_heartbeat_config.def
│               └── memfault_platform_log_config.h

If you are using git, the Memfault SDK is typically added to a project as a submodule:

$ git submodule add https://github.com/memfault/memfault-firmware-sdk.git $YOUR_PROJECT/third_party/memfault/memfault-firmware-sdk

This makes it easy to track the history of the Memfault SDK. You should not need to make modifications to the Memfault SDK. The typical update flow is:

  • git pull the latest upstream
  • check CHANGELOG.md to see if any modifications are needed
  • update to the new submodule commit in your repo.

Alternatively, the Memfault SDK may be added to a project as a git subtree or by copying the source into a project.

Add sources to Build System

Make

If you are using make, makefiles/MemfaultWorker.mk can be used to very easily collect the source files and include paths required by the SDK.

MEMFAULT_SDK_ROOT := <The to the root of this repo from your project>
MEMFAULT_COMPONENTS := <The SDK components to be used, i.e "core util">
include $(MEMFAULT_SDK_ROOT)/makefiles/MemfaultWorker.mk
<YOUR_SRC_FILES> += $(MEMFAULT_COMPONENTS_SRCS)
<YOUR_INCLUDE_PATHS> += $(MEMFAULT_COMPONENTS_INC_FOLDERS)

Cmake

If you are using cmake, cmake/Memfault.cmake in a similar fashion to collection source files and include paths:

set(MEMFAULT_SDK_ROOT <The path to the root of the memfault-firmware-sdk repo>)
list(APPEND MEMFAULT_COMPONENTS <The SDK components to be used, i.e "core util">)
include(${MEMFAULT_SDK_ROOT}/cmake/Memfault.cmake)
memfault_library(${MEMFAULT_SDK_ROOT} MEMFAULT_COMPONENTS
 MEMFAULT_COMPONENTS_SRCS MEMFAULT_COMPONENTS_INC_FOLDERS)

# ${MEMFAULT_COMPONENTS_SRCS} contains the sources
# needed for the library and ${MEMFAULT_COMPONENTS_INC_FOLDERS} contains the include paths

Other Build Systems

If you are not using one of the above build systems, to include the SDK you need to do is:

  • Add the .c files located at components/<component>/src/*.c to your build system
  • Add components/<component>/include to the include paths you pass to the compiler

Running the unit tests

The SDK code is covered extensively by unit tests. They can be found in the tests/ folder. If you'd like to run them yourself, check out the instructions in tests/README.md.

To learn more about unit testing best practices for firmware development, check out our blog post on this topic!

The unit tests are run by CircleCI upon every commit to this repo. See badges at the top for build & test coverage status of the master branch.

FAQ

  • Why does a coredump not show up under "Issues" after uploading it?

    • Make sure to upload the symbols to the same project to which you upload coredumps. Also make sure the software type and software version reported by the device (see "Device information" in components/core/README.md) match the software type and software version that was entered when creating the Software Version and symbol artifact online. More information on Build Ids and uploading Symbol Files can be found here.
  • I'm getting error XYZ, what to do now?

License

Unless specifically indicated otherwise in a file, all memfault-firmware-sdk files are all licensed under the Memfault License. (A few files in the examples and ports directory are licensed differently based on vendor requirements.)

memfault-firmware-sdk's People

Contributors

chrisc11 avatar noahp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memfault-firmware-sdk's Issues

zephyr: z_NmiHandlerSet used in port is gone

Zephyr commit zephyrproject-rtos/zephyr@77d2490 renamed this function.

This is breaking the build at least in ports/zephyr/v2.4/memfault_fault_handler.c:

static int prv_install_nmi_handler() {
  extern void z_NmiHandlerSet(void (*pHandler)(void));
  z_NmiHandlerSet(MEMFAULT_EXC_HANDLER_NMI);
  return 0;
}

I'm not sure what the right fix is -- perhaps a new ports/zephyr/v3.4 which uses the new name, z_arm_nmi_set_handler?

zephyr: Separate connect() from prv_configure_socket()

Hi,

I'm using nRF9160 on nRF Connect SDK version 2.3.0. We have had some problems with Memfault cloud where the connecting or data sending is taking too much time and the watchdog kicks in and reboots the device.

Could the connect() function be separated from the prv_configure_socket() function? So when the socket would be opened first by calling memfault_zephyr_port_http_open_socket(), then I would be able to setup socket timeouts and then call the new function memfault_zephyr_port_http_connect().

I have some kind of proposal about this:

ports/zephyr/common/memfault_platform_http.c

static int prv_configure_socket(int fd, const char *host) {
...
  return 0;
}

int memfault_zephyr_port_http_connect(sMemfaultHttpContext *ctx) {
  if (ctx->sock_fd < 0) {
    memfault_zephyr_port_http_close_socket(ctx);
    return -1;
  }

  return connect(ctx->sock_fd, ctx->res->ai_addr, ctx->res->ai_addrlen);
}

I think this would require some other code changes too but this would be really nice to have.

zephyr: legacy include workaround

The legacy workaround kconfig (CONFIG_LEGACY_INCLUDE_PATH) has been removed with v3.4 (zephyrproject-rtos/zephyr@9b30667).

The Memfault SDK is globally undoing that change with the following lines:

# The Zephyr includes moved from /include to /include/zephyr in Zephyr 3.2:
# https://github.com/zephyrproject-rtos/zephyr/commit/53ef68d4598b2f9005c5da3fc0b860ca1999d350
# Add the old path for backwards compatibility. Note that Zephyr itself
# supports the Kconfig option 'CONFIG_LEGACY_INCLUDE_PATH' to enable the same
# compatibility behavior, but it's marked as deprecated and to be removed in
# the future, so just apply the compatibiltiy fix here.
if(${KERNEL_VERSION_MAJOR}.${KERNEL_VERSION_MINOR}.${KERNEL_PATCHLEVEL} VERSION_GREATER_EQUAL "3.1.99")
zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr)
endif()

zephyr: `memfault_fault_handler` breaks user `k_sys_fatal_error_handler`

The default memfault_fault_handler, which is called by the wrapped __wrap_z_fatal_error, reboots the device unconditionally without calling __real_z_fatal_error. z_fatal_error is responsible for calling k_sys_fatal_error_handler, which user applications can hook into to be notified of the error.

memfault_platform_fault_handler is not a sufficient solution as the fault reason has already been abstracted away to kMfltRebootReason_HardFault, and only works when CONFIG_MEMFAULT=y.

Personally, k_sys_fatal_error_handler is used to preserve the current civil time and other metadata across reboots.

Ideally there would be a CONFIG_MEMFAULT_FAULT_HANDLER_RETURN which would remove the reboot call at the end of memfault_fault_handler, with __wrap_z_fatal_error calling __real_z_fatal_error after memfault_fault_handler

Cannot use external RTC for Zephyr projects

For Zephyr ports, Memfault expects the RTC device to be node named rtc. e.g.

rtc: rtc_foo@address {
    compatible = "vendor,rtc_foo";
    reg = <address>;
    status = "okay";
};

When using an external RTC we will encounter issues in the base address validation on nrf parts, e.g.

zephyr/soc/arm/nordic_nrf/validate_base_addresses.c:218:19: error: 'NRF_RTC' undeclared here (not in a function); did you mean 'NRF_RTC0'?
  218 | CHECK_DT_REG(rtc, NRF_RTC);

I propose ( #69 ) that we add a fallback to allow using an alias if the node is not found. This should provide backwards
compatibility and support external RTCs simultaneously.


Zephyr-Sdk: 0.16.5
nrfconnect: v2.6.0
Memfault SDK: 1.6.0

zephyr: flash supported

Hi memfault maintainer

Does memfault support storing coredump information in FLASH for the Zephyr OS? I noticed that the coredump information is

currently stored in the noinit RAM region, but I'm wondering if there is support for storing it in FLASH instead.

Thanks,
Dingisoul

Zephyr legacy path fixups conflict with application/module headers

Hi,

We are using memfault SDK for our internal application that uses zephyr rtos. We followed the instructions here: https://docs.memfault.com/docs/mcu/zephyr-guide/

The zephyr RTOS version is 3.4.0, we find the following build error:

are-sdk__ports__zephyr.dir/common/memfault_platform_core.c.obj -MF modules/memfault-firmware-sdk/CMakeFiles/..__modules__lib__memfault-firmware-sdk__ports__zephyr.dir/common/memfault_platform_core.c.obj.d -o modules/memfault-firmware-sdk/CMakeFiles/..__modules__lib__memfault-firmware-sdk__ports__zephyr.dir/common/memfault_platform_core.c.obj -c /root/zephyrproject/modules/lib/memfault-firmware-sdk/ports/zephyr/common/memfault_platform_core.c
/root/zephyrproject/modules/lib/memfault-firmware-sdk/ports/zephyr/common/memfault_platform_core.c:159:22: error: expected ')' before numeric constant
  159 |          APPLICATION,
      |                      ^
      |                      )

Warnings generated in Code Composer Studio

I noticed since a recent SDK upgrade to 0.24.1 we are getting a couple of these build warnings in memfault-firmware-sdk/components/panics/src/memfault_fault_handling_arm.c:

#1585-D function declared with "noreturn" does return

I'm using CCS 10.1 and TI CC2652

image

Heap stats free not checking in_use flag

In memfault_heap_stats_free, there is not a check to make sure the heap item pointer is actually in use. It is only checking the pointer against the items in the stats pool. However, there can be multiple items with the same address in the pool (of which only one is currently in use). This free check doesn't account for that and will exit after the first entry that it sees.

Here is the simple case where this happens:

alloc() --> return address X
free(P1)
alloc() --> return address X --- Now the heap stats will have 2 entries for items at address X, one is in_use and the other is not.
free() --> The heap stats will now be incorrect as it will mark the first entry (which is already not in use) and skip the second entry.

An example of what could fix the issue:

--- a/components/core/src/memfault_heap_stats.c
+++ b/components/core/src/memfault_heap_stats.c
@@ -93,7 +93,7 @@ void memfault_heap_stats_free(const void *ptr) {
 
     // if the pointer exists in the tracked stats, mark it as freed
     for (size_t i = 0; i < MEMFAULT_ARRAY_SIZE(g_memfault_heap_stats_pool); i++) {
-      if (g_memfault_heap_stats_pool[i].ptr == ptr) {
+      if (g_memfault_heap_stats_pool[i].ptr == ptr && g_memfault_heap_stats_pool[i].info.in_use == 1) {
         g_memfault_heap_stats_pool[i].info.in_use = 0;
         break;
       }

nrf5 SDK example on nrf52840 DK unresponsive until watchdog reset

I tried out this example on the nRF52840 DK:

https://github.com/memfault/memfault-firmware-sdk/tree/master/examples/nrf5/apps/memfault_demo_app

I found that it seems to hang and get unresponsive after the first run after reset. It will hang for about 10 seconds then it gets reset by the watchdog. After that it becomes responsive and the CLI will work.

Also, I was only every able to see one entry in the core storage at 0xA1000 when reading memory with the debugger, but maybe I didn't look far enough in as I don't know how much space is reserved per core dump entry.

I don't know if I'm supposed to load the softdevice or not with this example. I don't think I had it loaded.

I built it using Ubuntu 20.04.01 LTS on WSL.
gcc-arm-none-eabi 15:9-2019-q4-0ubuntu1 (default gcc-arm on Ubuntu)

Zephyr: FLASH SUPPORT

Hi memfault maintainer,

Does memfault have support for storing coredump information in FLASH for the Zephyr OS? Currently, I see that the coredump information is stored in the noinit RAM region, but I've noticed that other ports have implemented flash support. I'm wondering if the coredump data in the noinit RAM region will be deleted if the power supply is lost. It would be great to have support for storing the coredump information in FLASH instead.

Thanks,
Dingisoul

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.