diff --git a/kernel/os/include/os/arch/common.h b/kernel/os/include/os/arch/common.h index ce80fbb32e..c5f09f3a7e 100644 --- a/kernel/os/include/os/arch/common.h +++ b/kernel/os/include/os/arch/common.h @@ -71,6 +71,7 @@ void os_set_env(os_stack_t *); void os_arch_init_task_stack(os_stack_t *sf); void os_default_irq_asm(void); void os_assert_cb(void); +void os_coredump_cb(void *tf); #ifdef __cplusplus } diff --git a/kernel/os/include/os/os_fault.h b/kernel/os/include/os/os_fault.h index e830e7afe6..098bf74900 100644 --- a/kernel/os/include/os/os_fault.h +++ b/kernel/os/include/os/os_fault.h @@ -32,6 +32,10 @@ extern "C" { void __assert_func(const char *file, int line, const char *func, const char *e) __attribute((noreturn)); +#if MYNEWT_VAL(OS_COREDUMP_CB) +typedef void (*coredump_cb_t)(void *tf); +#endif + #if MYNEWT_VAL(OS_CRASH_FILE_LINE) #define OS_CRASH() (HAL_DEBUG_BREAK(), __assert_func(__FILE__, __LINE__, NULL, NULL)) #else diff --git a/kernel/os/src/arch/cortex_m33/os_fault.c b/kernel/os/src/arch/cortex_m33/os_fault.c index bd4716eb86..15b5f242f8 100644 --- a/kernel/os/src/arch/cortex_m33/os_fault.c +++ b/kernel/os/src/arch/cortex_m33/os_fault.c @@ -77,7 +77,7 @@ struct coredump_regs { uint32_t psr; }; -#if MYNEWT_VAL(OS_COREDUMP) +#if MYNEWT_VAL(OS_COREDUMP) && !MYNEWT_VAL(OS_COREDUMP_CB) static void trap_to_coredump(struct trap_frame *tf, struct coredump_regs *regs) { @@ -204,7 +204,7 @@ os_default_irq(struct trap_frame *tf) #if MYNEWT_VAL(OS_CRASH_LOG) struct log_reboot_info lri; #endif -#if MYNEWT_VAL(OS_COREDUMP) +#if MYNEWT_VAL(OS_COREDUMP) && !MYNEWT_VAL(OS_COREDUMP_CB) struct coredump_regs regs; #endif #if MYNEWT_VAL(OS_CRASH_RESTORE_REGS) @@ -243,9 +243,13 @@ os_default_irq(struct trap_frame *tf) #if MYNEWT_VAL(OS_COREDUMP) hal_watchdog_tickle(); +#if MYNEWT_VAL(OS_COREDUMP_CB) + os_coredump_cb(tf); +#else trap_to_coredump(tf, ®s); coredump_dump(®s, sizeof(regs)); #endif +#endif #if MYNEWT_VAL(OS_CRASH_RESTORE_REGS) if (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) < 16) && diff --git a/kernel/os/src/arch/cortex_m4/os_fault.c b/kernel/os/src/arch/cortex_m4/os_fault.c index 16069ae6c7..7928d8a786 100644 --- a/kernel/os/src/arch/cortex_m4/os_fault.c +++ b/kernel/os/src/arch/cortex_m4/os_fault.c @@ -76,7 +76,7 @@ struct coredump_regs { uint32_t psr; }; -#if MYNEWT_VAL(OS_COREDUMP) +#if MYNEWT_VAL(OS_COREDUMP) && !MYNEWT_VAL(OS_COREDUMP_CB) static void trap_to_coredump(struct trap_frame *tf, struct coredump_regs *regs) { @@ -161,7 +161,7 @@ os_default_irq(struct trap_frame *tf) #if MYNEWT_VAL(OS_CRASH_LOG) struct log_reboot_info lri; #endif -#if MYNEWT_VAL(OS_COREDUMP) +#if MYNEWT_VAL(OS_COREDUMP) && !MYNEWT_VAL(OS_COREDUMP_CB) struct coredump_regs regs; #endif #if MYNEWT_VAL(OS_CRASH_RESTORE_REGS) @@ -196,9 +196,13 @@ os_default_irq(struct trap_frame *tf) #endif #if MYNEWT_VAL(OS_COREDUMP) +#if MYNEWT_VAL(OS_COREDUMP_CB) + os_coredump_cb(tf); +#else trap_to_coredump(tf, ®s); coredump_dump(®s, sizeof(regs)); #endif +#endif #if MYNEWT_VAL(OS_CRASH_RESTORE_REGS) if (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) < 16) && diff --git a/kernel/os/syscfg.yml b/kernel/os/syscfg.yml index 8ee620f533..d67bead087 100644 --- a/kernel/os/syscfg.yml +++ b/kernel/os/syscfg.yml @@ -32,6 +32,11 @@ syscfg.defs: OS_COREDUMP: description: 'Attempt to dump corefile when system crashes' value: 0 + OS_COREDUMP_CB: + description: 'Calls a custom OS coredump callback function' + value: 0 + restriction: + - 'OS_COREDUMP if 1' OS_CRASH_STACKTRACE: description: 'Attempt to print stack trace when system crashes.' value: 0 diff --git a/util/memfault_sdk/README.md b/util/memfault_sdk/README.md new file mode 100644 index 0000000000..3e8b8eeaee --- /dev/null +++ b/util/memfault_sdk/README.md @@ -0,0 +1,92 @@ + +## Overview + +To use the memfault-firmware-sdk with mynewt add following lines to +**project.yml**. + +```yaml +repository.memfault-firmware-sdk: + type: github + vers: 0.0.0 + user: memfault + repo: memfault-firmware-sdk +``` + +Adding this dependency will allow you to pull in Memfault features + +```yaml +pkg.deps: + - "@memfault-firmware-sdk/ports/mynewt" +``` + +You will also need to enable the following options in the **syscfg.vals:** +section of your `syscfg.yml` file: + +```yaml +syscfg.vals: + [...] + MEMFAULT_ASSERT_CB: 1 + MEMFAULT_COREDUMP_CB: 1 + MEMFAULT_ENABLE: 1 + OS_COREDUMP: 1 + OS_COREDUMP_CB: 1 + OS_ASSERT_CB: 1 +``` + +Other syscfgs you can configure can be found in [syscfg.yml](syscfg.yml) + +Finally, on boot up initialize the Memfault subsystem from your `main` routine: + +```c +#include "memfault/components.h" +int +main(int argc, char **argv) +{ +// ... + memfault_platform_boot(); +// ... +} +``` + +## Using the GNU Build Id for Indexing + +We recommend enabling the generation of a unique identifier for your project. +See https://mflt.io/symbol-file-build-ids for more details. + +To enable, add the following compilation flags to your `pkg.yml`: + +``` +pkg.lflags: + - -Wl,--build-id +pkg.cflags: + - -DMEMFAULT_USE_GNU_BUILD_ID=1 +``` + +And add the following **after** the `.text` in your targets linker script: + +``` + .note.gnu.build-id : + { + __start_gnu_build_id_start = .; + KEEP(*(.note.gnu.build-id)) + } > FLASH +``` \ No newline at end of file diff --git a/util/memfault_sdk/include/memfault_sdk/memfault_sdk.h b/util/memfault_sdk/include/memfault_sdk/memfault_sdk.h new file mode 100644 index 0000000000..8097cab3fe --- /dev/null +++ b/util/memfault_sdk/include/memfault_sdk/memfault_sdk.h @@ -0,0 +1,22 @@ +/* + * 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. + */ + +#pragma once + +#include "os/mynewt.h" \ No newline at end of file diff --git a/util/memfault_sdk/pkg.yml b/util/memfault_sdk/pkg.yml new file mode 100644 index 0000000000..45cc0fd019 --- /dev/null +++ b/util/memfault_sdk/pkg.yml @@ -0,0 +1,28 @@ +# 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: util/memfault_sdk +pkg.description: "Memfault SDK package" +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/kernel/os" + +pkg.deps.MEMFAULT_ENABLE: + - "@memfault-firmware-sdk/ports/mynewt" diff --git a/util/memfault_sdk/src/memfault_sdk.c b/util/memfault_sdk/src/memfault_sdk.c new file mode 100644 index 0000000000..f158f50017 --- /dev/null +++ b/util/memfault_sdk/src/memfault_sdk.c @@ -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. + */ + +#include "memfault_sdk/memfault_sdk.h" + +#if MYNEWT_VAL(MEMFAULT_ENABLE) +#include "memfault/panics/coredump.h" +#include "memfault/panics/arch/arm/cortex_m.h" +#include "memfault/panics/platform/coredump.h" +#endif + +#if MYNEWT_VAL(MEMFAULT_ENABLE) +#if MYNEWT_VAL(MEMFAULT_COREDUMP_CB) + +eMemfaultRebootReason reboot_reason = kMfltRebootReason_HardFault; + +#if MYNEWT_VAL(MEMFAULT_ASSERT_CB) +void os_assert_cb(void) +{ + reboot_reason = kMfltRebootReason_Assert; +} +#endif + +void os_coredump_cb(void *tf) { + memfault_fault_handler((sMfltRegState *)tf, reboot_reason); +} +#endif +#endif \ No newline at end of file diff --git a/util/memfault_sdk/syscfg.yml b/util/memfault_sdk/syscfg.yml new file mode 100644 index 0000000000..14eebe1e91 --- /dev/null +++ b/util/memfault_sdk/syscfg.yml @@ -0,0 +1,37 @@ +# 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. +# + +syscfg.defs: + MEMFAULT_ENABLE: + description: 'Enables Memfault SDK features' + value: 0 + + MEMFAULT_COREDUMP_CB: + description: 'Enable custom memfault coredump handling cb' + value: 0 + restriction: + - 'MEMFAULT_ENABLE if 1' + - 'OS_COREDUMP_CB if 1' + + MEMFAULT_ASSERT_CB: + description: 'Enable custom memfault coredump handling cb' + value: 0 + restriction: + - 'MEMFAULT_ENABLE if 1' + - 'MEMFAULT_COREDUMP_CB if 1' + - 'OS_ASSERT_CB if 1'