kernel: add k_panic() and k_oops() APIs
Unlike assertions, these APIs are active at all times. The kernel will treat these errors in the same way as fatal CPU exceptions. Ultimately, the policy of what to do with these errors is implemented in _SysFatalErrorHandler. If the archtecture supports it, a real CPU exception can be triggered which will provide a complete register dump and PC value when the problem occurs. This will provide more helpful information than a fake exception stack frame (_default_esf) passed to the arch-specific exception handling code. Issue: ZEP-843 Change-Id: I8f136905c05bb84772e1c5ed53b8e920d24eb6fd Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
dc91536855
commit
cdb94d6425
19 changed files with 192 additions and 81 deletions
|
@ -16,13 +16,7 @@
|
|||
#include <offsets_short.h>
|
||||
#include <toolchain.h>
|
||||
#include <arch/cpu.h>
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
#include <misc/printk.h>
|
||||
#define PR_EXC(...) printk(__VA_ARGS__)
|
||||
#else
|
||||
#define PR_EXC(...)
|
||||
#endif /* CONFIG_PRINTK */
|
||||
|
||||
const NANO_ESF _default_esf = {
|
||||
0xdeaddead, /* placeholder */
|
||||
|
@ -48,24 +42,32 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
{
|
||||
switch (reason) {
|
||||
case _NANO_ERR_INVALID_TASK_EXIT:
|
||||
PR_EXC("***** Invalid Exit Software Error! *****\n");
|
||||
printk("***** Invalid Exit Software Error! *****\n");
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_STACK_CANARIES)
|
||||
case _NANO_ERR_STACK_CHK_FAIL:
|
||||
PR_EXC("***** Stack Check Fail! *****\n");
|
||||
printk("***** Stack Check Fail! *****\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case _NANO_ERR_ALLOCATION_FAIL:
|
||||
PR_EXC("**** Kernel Allocation Failure! ****\n");
|
||||
printk("**** Kernel Allocation Failure! ****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_OOPS:
|
||||
printk("***** Kernel OOPS! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_PANIC:
|
||||
printk("***** Kernel Panic! *****\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_EXC("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
printk("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
break;
|
||||
}
|
||||
PR_EXC("Current thread ID = %p\n"
|
||||
printk("Current thread ID = %p\n"
|
||||
"Faulting instruction address = 0x%lx\n",
|
||||
k_current_get(),
|
||||
_arc_v2_aux_reg_read(_ARC_V2_ERET));
|
||||
|
|
|
@ -40,23 +40,27 @@
|
|||
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
||||
const NANO_ESF *pEsf)
|
||||
{
|
||||
ARG_UNUSED(reason);
|
||||
ARG_UNUSED(pEsf);
|
||||
|
||||
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
|
||||
if (reason == _NANO_ERR_KERNEL_PANIC) {
|
||||
goto hang_system;
|
||||
}
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
printk("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
for (;;)
|
||||
; /* spin forever */
|
||||
goto hang_system;
|
||||
}
|
||||
printk("Fatal fault in thread %p! Aborting.\n", _current);
|
||||
k_thread_abort(_current);
|
||||
|
||||
hang_system:
|
||||
#else
|
||||
ARG_UNUSED(reason);
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
#endif
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
|
|
@ -17,13 +17,7 @@
|
|||
|
||||
#include <kernel.h>
|
||||
#include <kernel_structs.h>
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
#include <misc/printk.h>
|
||||
#define PR_EXC(...) printk(__VA_ARGS__)
|
||||
#else
|
||||
#define PR_EXC(...)
|
||||
#endif /* CONFIG_PRINTK */
|
||||
|
||||
/*
|
||||
* Define a default ESF for use with _NanoFatalErrorHandler() in the event
|
||||
|
@ -75,24 +69,32 @@ void _NanoFatalErrorHandler(unsigned int reason,
|
|||
{
|
||||
switch (reason) {
|
||||
case _NANO_ERR_INVALID_TASK_EXIT:
|
||||
PR_EXC("***** Invalid Exit Software Error! *****\n");
|
||||
printk("***** Invalid Exit Software Error! *****\n");
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_STACK_CANARIES)
|
||||
case _NANO_ERR_STACK_CHK_FAIL:
|
||||
PR_EXC("***** Stack Check Fail! *****\n");
|
||||
printk("***** Stack Check Fail! *****\n");
|
||||
break;
|
||||
#endif /* CONFIG_STACK_CANARIES */
|
||||
|
||||
case _NANO_ERR_ALLOCATION_FAIL:
|
||||
PR_EXC("**** Kernel Allocation Failure! ****\n");
|
||||
printk("**** Kernel Allocation Failure! ****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_OOPS:
|
||||
printk("***** Kernel OOPS! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_PANIC:
|
||||
printk("***** Kernel Panic! *****\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_EXC("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
printk("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
break;
|
||||
}
|
||||
PR_EXC("Current thread ID = %p\n"
|
||||
printk("Current thread ID = %p\n"
|
||||
"Faulting instruction address = 0x%x\n",
|
||||
k_current_get(), pEsf->pc);
|
||||
|
||||
|
|
|
@ -41,21 +41,28 @@
|
|||
void _SysFatalErrorHandler(unsigned int reason,
|
||||
const NANO_ESF *pEsf)
|
||||
{
|
||||
ARG_UNUSED(reason);
|
||||
ARG_UNUSED(pEsf);
|
||||
|
||||
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
|
||||
if (reason == _NANO_ERR_KERNEL_PANIC) {
|
||||
goto hang_system;
|
||||
}
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
printk("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
for (;;)
|
||||
; /* spin forever */
|
||||
goto hang_system;
|
||||
}
|
||||
printk("Fatal fault in thread %p! Aborting.\n", _current);
|
||||
k_thread_abort(_current);
|
||||
return;
|
||||
|
||||
hang_system:
|
||||
#else
|
||||
ARG_UNUSED(reason);
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
#endif
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,14 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
printk("**** Kernel Allocation Failure! ****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_OOPS:
|
||||
printk("***** Kernel OOPS! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_PANIC:
|
||||
printk("***** Kernel Panic! *****\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("**** Unknown Fatal Error %u! ****\n", reason);
|
||||
break;
|
||||
|
@ -210,26 +218,30 @@ FUNC_NORETURN void _Fault(const NANO_ESF *esf)
|
|||
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
||||
const NANO_ESF *pEsf)
|
||||
{
|
||||
ARG_UNUSED(reason);
|
||||
ARG_UNUSED(pEsf);
|
||||
|
||||
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
|
||||
if (reason == _NANO_ERR_KERNEL_PANIC) {
|
||||
goto hang_system;
|
||||
}
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
printk("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
#ifdef ALT_CPU_HAS_DEBUG_STUB
|
||||
_nios2_break();
|
||||
#endif
|
||||
for (;;)
|
||||
; /* spin forever */
|
||||
goto hang_system;
|
||||
}
|
||||
printk("Fatal fault in thread %p! Aborting.\n", _current);
|
||||
k_thread_abort(_current);
|
||||
|
||||
hang_system:
|
||||
#else
|
||||
ARG_UNUSED(reason);
|
||||
#endif
|
||||
|
||||
#ifdef ALT_CPU_HAS_DEBUG_STUB
|
||||
_nios2_break();
|
||||
#endif
|
||||
for (;;) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
#endif
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,7 @@
|
|||
#include <kernel.h>
|
||||
#include <kernel_structs.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
#include <misc/printk.h>
|
||||
#define PRINTK(...) printk(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTK(...)
|
||||
#endif
|
||||
|
||||
const NANO_ESF _default_esf = {
|
||||
0xdeadbaad,
|
||||
|
@ -72,25 +66,33 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
break;
|
||||
|
||||
case _NANO_ERR_INVALID_TASK_EXIT:
|
||||
PRINTK("***** Invalid Exit Software Error! *****\n");
|
||||
printk("***** Invalid Exit Software Error! *****\n");
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_STACK_CANARIES)
|
||||
case _NANO_ERR_STACK_CHK_FAIL:
|
||||
PRINTK("***** Stack Check Fail! *****\n");
|
||||
printk("***** Stack Check Fail! *****\n");
|
||||
break;
|
||||
#endif /* CONFIG_STACK_CANARIES */
|
||||
|
||||
case _NANO_ERR_ALLOCATION_FAIL:
|
||||
PRINTK("**** Kernel Allocation Failure! ****\n");
|
||||
printk("**** Kernel Allocation Failure! ****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_OOPS:
|
||||
printk("***** Kernel OOPS! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_PANIC:
|
||||
printk("***** Kernel Panic! *****\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTK("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
printk("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
break;
|
||||
}
|
||||
|
||||
PRINTK("Current thread ID = %p\n"
|
||||
printk("Current thread ID = %p\n"
|
||||
"Faulting instruction address = 0x%x\n"
|
||||
" ra: 0x%x gp: 0x%x tp: 0x%x t0: 0x%x\n"
|
||||
" t1: 0x%x t2: 0x%x t3: 0x%x t4: 0x%x\n"
|
||||
|
@ -134,27 +136,28 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
*/
|
||||
void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *esf)
|
||||
{
|
||||
ARG_UNUSED(reason);
|
||||
ARG_UNUSED(esf);
|
||||
|
||||
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
PRINTK("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
/* spin forever */
|
||||
for (;;)
|
||||
__asm__ volatile("nop");
|
||||
if (reason == _NANO_ERR_KERNEL_PANIC) {
|
||||
goto hang_system;
|
||||
}
|
||||
PRINTK("Fatal fault in thread! Aborting.\n");
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
printk("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
goto hang_system;
|
||||
}
|
||||
printk("Fatal fault in thread %p! Aborting.\n", _current);
|
||||
k_thread_abort(_current);
|
||||
|
||||
hang_system:
|
||||
#else
|
||||
ARG_UNUSED(reason);
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
||||
|
@ -190,7 +193,7 @@ FUNC_NORETURN void _Fault(const NANO_ESF *esf)
|
|||
|
||||
mcause &= SOC_MCAUSE_EXP_MASK;
|
||||
|
||||
PRINTK("Exception cause %s (%d)\n", cause_str(mcause), (int)mcause);
|
||||
printk("Exception cause %s (%d)\n", cause_str(mcause), (int)mcause);
|
||||
|
||||
_NanoFatalErrorHandler(_NANO_ERR_CPU_EXCEPTION, esf);
|
||||
}
|
||||
|
|
|
@ -92,6 +92,13 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
break;
|
||||
#endif /* CONFIG_STACK_CANARIES */
|
||||
|
||||
case _NANO_ERR_KERNEL_OOPS:
|
||||
printk("***** Kernel OOPS! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_PANIC:
|
||||
printk("***** Kernel Panic! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_ALLOCATION_FAIL:
|
||||
printk("**** Kernel Allocation Failure! ****\n");
|
||||
|
|
|
@ -41,23 +41,27 @@
|
|||
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
||||
const NANO_ESF *pEsf)
|
||||
{
|
||||
ARG_UNUSED(reason);
|
||||
ARG_UNUSED(pEsf);
|
||||
|
||||
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
|
||||
if (reason == _NANO_ERR_KERNEL_PANIC) {
|
||||
goto hang_system;
|
||||
}
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
printk("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
for (;;)
|
||||
; /* spin forever */
|
||||
goto hang_system;
|
||||
}
|
||||
printk("Fatal fault in thread %p! Aborting.\n", _current);
|
||||
k_thread_abort(_current);
|
||||
|
||||
hang_system:
|
||||
#else
|
||||
ARG_UNUSED(reason);
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
#endif
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,15 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
case _NANO_ERR_ALLOCATION_FAIL:
|
||||
printk("**** Kernel Allocation Failure! ****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_OOPS:
|
||||
printk("***** Kernel OOPS! *****\n");
|
||||
break;
|
||||
|
||||
case _NANO_ERR_KERNEL_PANIC:
|
||||
printk("***** Kernel Panic! *****\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("**** Unknown Fatal Error %d! ****\n", reason);
|
||||
break;
|
||||
|
@ -215,28 +224,32 @@ extern FUNC_NORETURN void exit(int exit_code);
|
|||
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
||||
const NANO_ESF *pEsf)
|
||||
{
|
||||
ARG_UNUSED(reason);
|
||||
ARG_UNUSED(pEsf);
|
||||
|
||||
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
|
||||
if (reason == _NANO_ERR_KERNEL_PANIC) {
|
||||
goto hang_system;
|
||||
}
|
||||
if (k_is_in_isr() || _is_thread_essential()) {
|
||||
printk("Fatal fault in %s! Spinning...\n",
|
||||
k_is_in_isr() ? "ISR" : "essential thread");
|
||||
#ifdef XT_SIMULATOR
|
||||
exit(255 - reason);
|
||||
#else
|
||||
for (;;)
|
||||
; /* spin forever */
|
||||
#endif
|
||||
goto hang_system;
|
||||
}
|
||||
printk("Fatal fault in thread %p! Aborting.\n", _current);
|
||||
k_thread_abort(_current);
|
||||
|
||||
hang_system:
|
||||
#else
|
||||
ARG_UNUSED(reason);
|
||||
#endif
|
||||
|
||||
#ifdef XT_SIMULATOR
|
||||
exit(255 - reason);
|
||||
#else
|
||||
for (;;) {
|
||||
k_cpu_idle();
|
||||
}
|
||||
#endif
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ extern void _SysFatalErrorHandler(unsigned int cause, const NANO_ESF *esf);
|
|||
#define _NANO_ERR_INVALID_TASK_EXIT (1) /* Invalid task exit */
|
||||
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
|
||||
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
|
||||
#define _NANO_ERR_KERNEL_OOPS (4) /* Kernel oops (fatal to thread) */
|
||||
#define _NANO_ERR_KERNEL_PANIC (5) /* Kernel panic (fatal to system) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ extern void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *esf);
|
|||
#define _NANO_ERR_INVALID_TASK_EXIT (1) /* Invalid task exit */
|
||||
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
|
||||
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
|
||||
#define _NANO_ERR_KERNEL_OOPS (4) /* Kernel oops (fatal to thread) */
|
||||
#define _NANO_ERR_KERNEL_PANIC (5) /* Kernel panic (fatal to system) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ extern "C" {
|
|||
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
|
||||
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
|
||||
#define _NANO_ERR_SPURIOUS_INT (4) /* Spurious interrupt */
|
||||
#define _NANO_ERR_KERNEL_OOPS (5) /* Kernel oops (fatal to thread) */
|
||||
#define _NANO_ERR_KERNEL_PANIC (6) /* Kernel panic (fatal to system) */
|
||||
|
||||
/* APIs need to support non-byte addressable architectures */
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ extern void _SysFatalErrorHandler(unsigned int reason,
|
|||
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
|
||||
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
|
||||
#define _NANO_ERR_SPURIOUS_INT (4) /* Spurious interrupt */
|
||||
#define _NANO_ERR_KERNEL_OOPS (5) /* Kernel oops (fatal to thread) */
|
||||
#define _NANO_ERR_KERNEL_PANIC (6) /* Kernel panic (fatal to system) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -339,6 +339,10 @@ typedef struct nanoIsf {
|
|||
#define _NANO_ERR_ALLOCATION_FAIL (5)
|
||||
/** Unhandled exception */
|
||||
#define _NANO_ERR_CPU_EXCEPTION (6)
|
||||
/** Kernel oops (fatal to thread) */
|
||||
#define _NANO_ERR_KERNEL_OOPS (7)
|
||||
/** Kernel panic (fatal to system) */
|
||||
#define _NANO_ERR_KERNEL_PANIC (8)
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ extern "C" {
|
|||
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
|
||||
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
|
||||
#define _NANO_ERR_RESERVED_IRQ (4) /* Reserved interrupt */
|
||||
#define _NANO_ERR_KERNEL_OOPS (5) /* Kernel oops (fatal to thread) */
|
||||
#define _NANO_ERR_KERNEL_PANIC (6) /* Kernel panic (fatal to system) */
|
||||
|
||||
/* Xtensa GPRs are often designated by two different names */
|
||||
#define sys_define_gpr_with_alias(name1, name2) union { u32_t name1, name2; }
|
||||
|
|
|
@ -85,7 +85,7 @@ static inline __printf_like(1, 2) void _bt_log_dummy(const char *fmt, ...) {};
|
|||
|
||||
#define BT_ASSERT(cond) if (!(cond)) { \
|
||||
BT_ERR("assert: '" #cond "' failed"); \
|
||||
_SysFatalErrorHandler(0, NULL); \
|
||||
k_oops(); \
|
||||
}
|
||||
|
||||
#define BT_STACK(name, size) \
|
||||
|
|
|
@ -3554,6 +3554,51 @@ extern void _sys_power_save_idle_exit(s32_t ticks);
|
|||
|
||||
#include <arch/cpu.h>
|
||||
|
||||
#ifdef _ARCH_EXCEPT
|
||||
/* This archtecture has direct support for triggering a CPU exception */
|
||||
#define _k_except_reason(reason) _ARCH_EXCEPT(reason)
|
||||
#else
|
||||
|
||||
#include <misc/printk.h>
|
||||
|
||||
/* NOTE: This is the implementation for arches that do not implement
|
||||
* _ARCH_EXCEPT() to generate a real CPU exception.
|
||||
*
|
||||
* We won't have a real exception frame to determine the PC value when
|
||||
* the oops occurred, so print file and line number before we jump into
|
||||
* the fatal error handler.
|
||||
*/
|
||||
#define _k_except_reason(reason) do { \
|
||||
printk("@ %s:%d:\n", __FILE__, __LINE__); \
|
||||
_NanoFatalErrorHandler(reason, &_default_esf); \
|
||||
CODE_UNREACHABLE; \
|
||||
} while (0)
|
||||
|
||||
#endif /* _ARCH__EXCEPT */
|
||||
|
||||
/**
|
||||
* @brief Fatally terminate a thread
|
||||
*
|
||||
* This should be called when a thread has encountered an unrecoverable
|
||||
* runtime condition and needs to terminate. What this ultimately
|
||||
* means is determined by the _fatal_error_handler() implementation, which
|
||||
* will be called will reason code _NANO_ERR_KERNEL_OOPS.
|
||||
*
|
||||
* If this is called from ISR context, the default system fatal error handler
|
||||
* will treat it as an unrecoverable system error, just like k_panic().
|
||||
*/
|
||||
#define k_oops() _k_except_reason(_NANO_ERR_KERNEL_OOPS)
|
||||
|
||||
/**
|
||||
* @brief Fatally terminate the system
|
||||
*
|
||||
* This should be called when the Zephyr kernel has encountered an
|
||||
* unrecoverable runtime condition and needs to terminate. What this ultimately
|
||||
* means is determined by the _fatal_error_handler() implementation, which
|
||||
* will be called will reason code _NANO_ERR_KERNEL_PANIC.
|
||||
*/
|
||||
#define k_panic() _k_except_reason(_NANO_ERR_KERNEL_PANIC)
|
||||
|
||||
/*
|
||||
* private APIs that are utilized by one or more public APIs
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <kernel_structs.h>
|
||||
#include <toolchain.h>
|
||||
#include <sections.h>
|
||||
#include <kernel.h>
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -34,9 +35,7 @@ void FUNC_NORETURN _StackCheckHandler(void)
|
|||
{
|
||||
/* Stack canary error is a software fatal condition; treat it as such.
|
||||
*/
|
||||
|
||||
_NanoFatalErrorHandler(_NANO_ERR_STACK_CHK_FAIL, &_default_esf);
|
||||
CODE_UNREACHABLE;
|
||||
_k_except_reason(_NANO_ERR_STACK_CHK_FAIL);
|
||||
}
|
||||
|
||||
/* Global variable */
|
||||
|
|
|
@ -142,8 +142,7 @@ FUNC_NORETURN void _thread_entry(void (*entry)(void *, void *, void *),
|
|||
|
||||
#ifdef CONFIG_MULTITHREADING
|
||||
if (_is_thread_essential()) {
|
||||
_NanoFatalErrorHandler(_NANO_ERR_INVALID_TASK_EXIT,
|
||||
&_default_esf);
|
||||
_k_except_reason(_NANO_ERR_INVALID_TASK_EXIT);
|
||||
}
|
||||
|
||||
k_thread_abort(_current);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue