Skip to content

Commit

Permalink
sys/memfault: Add basic integration with Memfault
Browse files Browse the repository at this point in the history
  • Loading branch information
Michał Narajowski committed May 11, 2020
1 parent 180449a commit 51c8da2
Show file tree
Hide file tree
Showing 14 changed files with 477 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MEMFAULT_METRICS_KEY_DEFINE(MainTaskStackHwm, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_KEY_DEFINE(BtBytesSent, kMemfaultMetricType_Unsigned)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MEMFAULT_TRACE_REASON_DEFINE(test)
MEMFAULT_TRACE_REASON_DEFINE(MemfaultDemoCli_Error)
32 changes: 32 additions & 0 deletions apps/memfault_demo/pkg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

pkg.name: apps/memfault_demo
pkg.type: app
pkg.description:
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:

pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/hw/hal"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/memfault"
93 changes: 93 additions & 0 deletions apps/memfault_demo/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include <assert.h>
#include <string.h>

#include "bsp/bsp.h"
#include "console/console.h"
#include "hal/hal_gpio.h"
#include "os/os.h"
#include "syscfg/syscfg.h"
#include "sysinit/sysinit.h"

#include "memfault/core/debug_log.h"
#include "memfault/core/platform/device_info.h"
#include "memfault/http/http_client.h"
#include "memfault/metrics/metrics.h"

void
memfault_platform_get_device_info(sMemfaultDeviceInfo *info)
{
*info = (sMemfaultDeviceInfo) {
.device_serial = "DEMOSERIAL",
.software_type = "app",
.software_version = "0.0.1",
.hardware_version = MYNEWT_VAL(BSP_NAME),
};
}

sMfltHttpClientConfig g_mflt_http_client_config = {
.api_key = "<YOUR API KEY HERE>",
};

struct os_callout send_bytes_co;

void
bluetooth_driver_send_bytes(struct os_event *ev)
{
memfault_metrics_heartbeat_add(MEMFAULT_METRICS_KEY(BtBytesSent), 50);
// [ ... code to send bluetooth data ... ]
os_callout_reset(&send_bytes_co, os_time_ms_to_ticks32(2000));
}

static volatile int g_task1_loops;

/* For LED toggling */
int g_led_pin;

/**
* main
*
* The main task for the project. This function initializes packages,
* and then blinks the BSP LED in a loop.
*
* @return int NOTE: this function should never return!
*/
int
main(int argc, char **argv)
{
int rc;

sysinit();

os_callout_init(&send_bytes_co, os_eventq_dflt_get(),
bluetooth_driver_send_bytes, NULL);

os_callout_reset(&send_bytes_co, os_time_ms_to_ticks32(2000));

while (1) {
os_eventq_run(os_eventq_dflt_get());
}

assert(0);

return rc;
}

7 changes: 7 additions & 0 deletions apps/memfault_demo/syscfg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syscfg.vals:
SHELL_NEWTMGR: 0
SHELL_MGMT: 0
SHELL_TASK: 1
CONSOLE_UART_BAUD: 1000000
CONSOLE_UART_FLOW_CONTROL: UART_FLOW_CTL_RTS_CTS
CONSOLE_TICKS: 0
3 changes: 3 additions & 0 deletions kernel/os/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,8 @@ pkg.deps.OS_SYSVIEW:
pkg.deps.OS_CRASH_LOG:
- "@apache-mynewt-core/sys/reboot"

pkg.deps.SYS_MEMFAULT:
- "@apache-mynewt-core/sys/memfault"

pkg.init:
os_pkg_init: 'MYNEWT_VAL(OS_SYSINIT_STAGE)'
34 changes: 34 additions & 0 deletions kernel/os/src/arch/cortex_m4/os_fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
#include "reboot/log_reboot.h"
#endif

#if MYNEWT_VAL(SYS_MEMFAULT)
#include "memfault/panics/coredump.h"
#include "memfault/panics/arch/arm/cortex_m.h"
#include "memfault/panics/platform/coredump.h"
#endif

struct exception_frame {
uint32_t r0;
uint32_t r1;
Expand Down Expand Up @@ -201,6 +207,34 @@ os_default_irq(struct trap_frame *tf)
coredump_dump(&regs, sizeof(regs));
#endif

#if MYNEWT_VAL(SYS_MEMFAULT)
sMfltExceptionFrame ef = {
.r0 = tf->ef->r0,
.r1 = tf->ef->r1,
.r2 = tf->ef->r2,
.r3 = tf->ef->r3,
.r12 = tf->ef->r12,
.lr = tf->ef->lr,
.pc = tf->ef->pc,
.xpsr = tf->ef->psr,
};

sMfltRegState reg = {
.exception_frame = &ef,
.r4 = tf->r4,
.r5 = tf->r5,
.r6 = tf->r6,
.r7 = tf->r7,
.r8 = tf->r8,
.r9 = tf->r9,
.r10 = tf->r10,
.r11 = tf->r11,
.exc_return = tf->lr,
};

memfault_fault_handler(&reg, kMfltRebootReason_HardFault);
#endif

#if MYNEWT_VAL(OS_CRASH_RESTORE_REGS)
if (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) < 16) &&
hal_debugger_connected()) {
Expand Down
1 change: 1 addition & 0 deletions sys/memfault/ext
44 changes: 44 additions & 0 deletions sys/memfault/pkg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

pkg.name: sys/memfault
pkg.description:
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
pkg.type: sdk
pkg.cflags:
- "-DMEMFAULT_TRACE_REASON_USER_DEFS_FILE=\"memfault_trace_reason_user_config.def\""
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/shell"
pkg.init:
memfault_platform_core_init: 501
pkg.ign_dirs:
pkg.include_dirs:
- "ext/components/core/include"
- "ext/components/demo/include"
- "ext/components/http/include"
- "ext/components/metrics/include"
- "ext/components/panics/include"
- "ext/components/util/include"
pkg.src_dirs:
- "src"
- "ext/components/"
- "ext/ports/panics/"
1 change: 1 addition & 0 deletions sys/memfault/src/memfault_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void shell_mflt_register(void);
82 changes: 82 additions & 0 deletions sys/memfault/src/memfault_demo_cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "shell/shell.h"

#include "memfault/core/trace_event.h"
#include "memfault/demo/cli.h"
#include "memfault/metrics/metrics.h"

#include "memfault_common.h"

static int
prv_clear_core_cmd(int argc, char **argv)
{
return memfault_demo_cli_cmd_clear_core(argc, argv);
}

static int
prv_get_core_cmd(int argc, char **argv)
{
return memfault_demo_cli_cmd_get_core(argc, argv);
}

static int
prv_crash_example(int argc, char **argv)
{
return memfault_demo_cli_cmd_crash(argc, argv);
}

static int
prv_get_device_info(int argc, char **argv)
{
return memfault_demo_cli_cmd_get_device_info(argc, argv);
}

static int
prv_print_chunk_cmd(int argc, char **argv)
{
return memfault_demo_cli_cmd_print_chunk(argc, argv);
}

static int
prv_heartbeat_trigger(int argc, char **argv)
{
memfault_metrics_heartbeat_debug_trigger();
return 0;
}

static int
prv_heartbeat_print(int argc, char **argv)
{
memfault_metrics_heartbeat_debug_print();
return 0;
}

static int
prv_test_trace_event(int argc, char **argv)
{
MEMFAULT_TRACE_EVENT(test);
return 0;
}

static const struct shell_cmd os_commands[] = {
SHELL_CMD("crash", prv_crash_example, NULL),
SHELL_CMD("clear_core", prv_clear_core_cmd, NULL),
SHELL_CMD("get_core", prv_get_core_cmd, NULL),
SHELL_CMD("get_device_info", prv_get_device_info, NULL),
SHELL_CMD("print_chunk", prv_print_chunk_cmd, NULL),
SHELL_CMD("heartbeat_trigger", prv_heartbeat_trigger, NULL),
SHELL_CMD("heartbeat_print", prv_heartbeat_print, NULL),
SHELL_CMD("test_trace_event", prv_test_trace_event, NULL),
{0},
};

void
shell_mflt_register(void)
{
int rc;

rc = shell_register("mflt", os_commands);
SYSINIT_PANIC_ASSERT_MSG(
rc == 0, "Failed to register OS shell commands");

shell_register_default_module("mflt");
}
Loading

0 comments on commit 51c8da2

Please sign in to comment.