rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_BACKTRACE_H
#define K_BACKTRACE_H
#ifdef __cplusplus
extern "C"
{
#endif
#if (RHINO_CONFIG_BACKTRACE > 0)
/* show backtrace now */
void krhino_backtrace_now(void);
/* show backtrace for the task */
void krhino_backtrace_task(char *taskname);
#endif
#ifdef __cplusplus
}
#endif
#endif /* K_BACKTRACE_H */

View file

@ -0,0 +1,25 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_DBG_API_H
#define K_DBG_API_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include "k_api.h"
#include "k_dftdbg_config.h"
#include "k_infoget.h"
#include "k_overview.h"
#include "k_panic.h"
#include "k_backtrace.h"
#ifdef __cplusplus
}
#endif
#endif /* K_DBG_API_H */

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_DFTDBG_CONFIG_H
#define K_DFTDBG_CONFIG_H
#ifndef RHINO_CONFIG_BACKTRACE
#define RHINO_CONFIG_BACKTRACE 1
#endif
/* If AliOS task over the Exception/Fatal Error */
#ifndef RHINO_CONFIG_PANIC
#define RHINO_CONFIG_PANIC 1
#endif
#if (RHINO_CONFIG_PANIC > 0)
/* If the mcu printf depends on isr */
#ifndef RHINO_CONFIG_PANIC_PRT_INT
#define RHINO_CONFIG_PANIC_PRT_INT 1
#endif
#ifndef RHINO_CONFIG_PANIC_OVERVIEW
#define RHINO_CONFIG_PANIC_OVERVIEW 1
#endif
#endif
#ifndef RHINO_CONFIG_NORMAL_PRT
#define RHINO_CONFIG_NORMAL_PRT 1
#endif
#endif /* K_DFTDBG_CONFIG_H */

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_INFOGET_H
#define K_INFOGET_H
#ifdef __cplusplus
extern "C"
{
#endif
/**
* This function will get task handle by its name.
*/
ktask_t *krhino_task_find(char *name);
/**
* This function will return true if task is ready.
*/
int krhino_is_task_ready(ktask_t *task);
/**
* This function will return true if task is running.
*/
int krhino_task_is_running(ktask_t *task);
/**
* This function will get the bottom of task stack
* @param[in] task NULL for active task
* @return the bottom of stack
*/
void *krhino_task_stack_bottom(ktask_t *task);
#ifdef __cplusplus
}
#endif
#endif /* K_INFOGET_H */

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_OVERVIEW_H
#define K_OVERVIEW_H
#ifdef __cplusplus
extern "C"
{
#endif
/**
* convert int to ascii(HEX)
* while using format % in libc, malloc/free is involved.
* this function avoid using malloc/free. so it works when heap corrupt.
* @param[in] num number
* @param[in] str fix 8 character str
* @return str
*/
char *k_int2str(int num, char *str);
/**
* This function print the overview of heap
* @param[in] print_func function to output information, NULL for
* "printf"
*/
void krhino_mm_overview(int (*print_func)(const char *fmt, ...));
/**
* This function print the overview of tasks
* @param[in] print_func function to output information, NULL for
* "printf"
*/
void krhino_task_overview(int (*print_func)(const char *fmt, ...));
/**
* This function print the overview of buf_queues
* @param[in] print_func function to output information, NULL for
* "printf"
*/
void krhino_buf_queue_overview(int (*print_func)(const char *fmt, ...));
/**
* This function print the overview of queues
* @param[in] print_func function to output information, NULL for
* "printf"
*/
void krhino_queue_overview(int (*print_func)(const char *fmt, ...));
/**
* This function print the overview of sems
* @param[in] print_func function to output information, NULL for
* "printf"
*/
void krhino_sem_overview(int (*print_func)(const char *fmt, ...));
/**
* This function print the overview of all
* @param[in] print_func function to output information, NULL for
* "printf"
*/
void krhino_overview();
#ifdef __cplusplus
}
#endif
#endif /* K_OVERVIEW_H */

View file

@ -0,0 +1,24 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_PANIC_H
#define K_PANIC_H
#ifdef __cplusplus
extern "C"
{
#endif
#if (RHINO_CONFIG_PANIC > 0)
/* fault/exception entry
notice: this function maybe reentried by double exception */
void panicHandler(void *context);
void debug_fatal_error(kstat_t err, char *file, int line);
#endif
#ifdef __cplusplus
}
#endif
#endif /* K_PANIC_H */

View file

@ -0,0 +1,23 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "k_dbg_api.h"
#if (RHINO_CONFIG_BACKTRACE > 0)
/* follow functions should defined by arch\...\backtrace.c */
extern int backtrace_now(int (*print_func)(const char *fmt, ...));
extern int backtrace_task(char *taskname, int (*print_func)(const char *fmt, ...));
void krhino_backtrace_now()
{
backtrace_now(printf);
}
void krhino_backtrace_task(char *taskname)
{
backtrace_task(taskname, printf);
}
#endif

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "k_dbg_api.h"
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
ktask_t *krhino_task_find(char *name)
{
klist_t *listnode;
ktask_t *task;
for (listnode = g_kobj_list.task_head.next;
listnode != &g_kobj_list.task_head; listnode = listnode->next) {
task = krhino_list_entry(listnode, ktask_t, task_stats_item);
if (0 == strcmp(name, task->task_name)) {
return task;
}
}
return NULL;
}
#endif
int krhino_task_is_running(ktask_t *task)
{
if ( g_active_task[cpu_cur_get()] == task
&& g_intrpt_nested_level[cpu_cur_get()] == 0 ) {
return 1;
}
else {
return 0;
}
}
int krhino_is_task_ready(ktask_t *task)
{
return (task->task_state == K_RDY);
}
void *krhino_task_stack_bottom(ktask_t *task)
{
if (task == NULL) {
task = g_active_task[cpu_cur_get()];
}
if (task->task_state == K_DELETED) {
return NULL;
}
#if (RHINO_CONFIG_CPU_STACK_DOWN > 0)
return task->task_stack_base + task->stack_size;
#else
return task->task_stack_base;
#endif
}

View file

@ -0,0 +1,420 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "k_dbg_api.h"
/* convert int to ascii(HEX)
while using format % in libc, malloc/free is involved.
this function avoid using malloc/free. so it works when heap corrupt. */
char *k_int2str(int num, char *str)
{
char index[] = "0123456789ABCDEF";
unsigned int usnum = (unsigned int)num;
str[7] = index[usnum % 16];
usnum /= 16;
str[6] = index[usnum % 16];
usnum /= 16;
str[5] = index[usnum % 16];
usnum /= 16;
str[4] = index[usnum % 16];
usnum /= 16;
str[3] = index[usnum % 16];
usnum /= 16;
str[2] = index[usnum % 16];
usnum /= 16;
str[1] = index[usnum % 16];
usnum /= 16;
str[0] = index[usnum % 16];
usnum /= 16;
return str;
}
#if (K_MM_STATISTIC > 0)
void krhino_mm_overview(int (*print_func)(const char *fmt, ...))
{
#if (RHINO_CONFIG_MM_BLK > 0)
mblk_pool_t *mm_pool;
#endif
char s_heap_overview[] =
" | 0x | 0x | 0x | 0x |\r\n";
if (print_func == NULL) {
print_func = printf;
}
print_func(
"-----------------------------------------------------------\r\n");
print_func(
"[HEAP]| TotalSz | FreeSz | UsedSz | MinFreeSz |\r\n");
k_int2str((int)(g_kmm_head->free_size + g_kmm_head->used_size),
&s_heap_overview[10]);
k_int2str((int)g_kmm_head->free_size, &s_heap_overview[23]);
k_int2str((int)g_kmm_head->used_size, &s_heap_overview[36]);
k_int2str((int)(g_kmm_head->free_size + g_kmm_head->used_size -
g_kmm_head->maxused_size),
&s_heap_overview[49]);
print_func(s_heap_overview);
print_func(
"-----------------------------------------------------------\r\n");
#if (RHINO_CONFIG_MM_BLK > 0)
print_func(
"[POOL]| PoolSz | FreeSz | UsedSz | BlkSz |\r\n");
/* little blk, try to get from mm_pool */
if (g_kmm_head->fix_pool != NULL) {
mm_pool = (mblk_pool_t *)g_kmm_head->fix_pool;
k_int2str((int)mm_pool->blk_whole * mm_pool->blk_size,
&s_heap_overview[10]);
k_int2str((int)mm_pool->blk_avail * mm_pool->blk_size,
&s_heap_overview[23]);
k_int2str((int)(mm_pool->blk_whole - mm_pool->blk_avail) *
mm_pool->blk_size,
&s_heap_overview[36]);
k_int2str((int)mm_pool->blk_size, &s_heap_overview[49]);
print_func(s_heap_overview);
}
print_func(
"-----------------------------------------------------------\r\n");
#endif
}
#else
void krhino_mm_overview(int (*print_func)(const char *fmt, ...))
{
if (print_func == NULL) {
print_func = printf;
}
print_func("K_MM_STATISTIC in k_config.h is closed!\r\n");
}
#endif
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
void krhino_task_overview(int (*print_func)(const char *fmt, ...))
{
size_t free_size;
klist_t *listnode;
ktask_t *task;
int stat_idx;
int i;
char *cpu_stat[] = { "UNK", "RDY", "PEND", "SUS",
"PEND_SUS", "SLP", "SLP_SUS", "DEL" };
const name_t *task_name;
char s_task_overview[] = " 0x 0x "
" 0x (0x )\r\n";
if (print_func == NULL) {
print_func = printf;
}
print_func("---------------------------------------------------------------"
"-----------\r\n");
print_func("TaskName State Prio Stack StackSize "
"(MinFree)\r\n");
print_func("---------------------------------------------------------------"
"-----------\r\n");
for (listnode = g_kobj_list.task_head.next;
listnode != &g_kobj_list.task_head; listnode = listnode->next) {
task = krhino_list_entry(listnode, ktask_t, task_stats_item);
if (krhino_task_stack_min_free(task, &free_size) != RHINO_SUCCESS) {
free_size = 0;
}
free_size *= sizeof(cpu_stack_t);
/* set name */
task_name = task->task_name == NULL ? "anonym" : task->task_name;
for (i = 0; i < 20; i++) {
s_task_overview[i] = ' ';
}
for (i = 0; i < 20; i++) {
if (task_name[i] == '\0') {
break;
}
s_task_overview[i] = task_name[i];
}
/* set state */
stat_idx = task->task_state >= sizeof(cpu_stat) / sizeof(char *)
? 0
: task->task_state;
for (i = 21; i < 29; i++) {
s_task_overview[i] = ' ';
}
for (i = 21; i < 29; i++) {
if (cpu_stat[stat_idx][i - 21] == '\0') {
break;
}
s_task_overview[i] = cpu_stat[stat_idx][i - 21];
}
/* set stack priority */
k_int2str(task->prio, &s_task_overview[32]);
/* set stack info */
k_int2str((int)task->task_stack_base, &s_task_overview[43]);
k_int2str((int)task->stack_size * sizeof(cpu_stack_t),
&s_task_overview[54]);
k_int2str((int)free_size, &s_task_overview[65]);
/* print */
print_func(s_task_overview);
}
}
#else
void krhino_task_overview(int (*print_func)(const char *fmt, ...))
{
if (print_func == NULL) {
print_func = printf;
}
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
}
#endif
#if (RHINO_CONFIG_BUF_QUEUE > 0)
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
void krhino_buf_queue_overview(int (*print_func)(const char *fmt, ...))
{
int i;
klist_t *listnode;
klist_t *blk_list_head;
ktask_t *task;
kbuf_queue_t *buf_queue;
const name_t *task_name;
char s_buf_queue_overview[] = "0x 0x 0x 0x "
"0x \r\n";
if (print_func == NULL) {
print_func = printf;
}
print_func(
"------------------------------------------------------------------\r\n");
print_func(
"BufQueAddr TotalSize PeakNum CurrNum MinFreeSz TaskWaiting\r\n");
print_func(
"------------------------------------------------------------------\r\n");
for (listnode = g_kobj_list.buf_queue_head.next;
listnode != &g_kobj_list.buf_queue_head; listnode = listnode->next) {
buf_queue = krhino_list_entry(listnode, kbuf_queue_t, buf_queue_item);
if (buf_queue->blk_obj.obj_type != RHINO_BUF_QUEUE_OBJ_TYPE) {
print_func("BufQueue Type error!\r\n");
break;
}
/* set buf_queue information */
k_int2str((int)buf_queue->buf, &s_buf_queue_overview[2]);
k_int2str((int)(buf_queue->ringbuf.end - buf_queue->ringbuf.buf),
&s_buf_queue_overview[13]);
k_int2str((int)buf_queue->peak_num, &s_buf_queue_overview[24]);
k_int2str((int)buf_queue->cur_num, &s_buf_queue_overview[35]);
k_int2str((int)buf_queue->min_free_buf_size, &s_buf_queue_overview[46]);
/* set pending task name */
blk_list_head = &buf_queue->blk_obj.blk_list;
if (is_klist_empty(blk_list_head)) {
task_name = " ";
} else {
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
task_name = task->task_name == NULL ? "anonym" : task->task_name;
}
for (i = 0; i < 20; i++) {
s_buf_queue_overview[55 + i] = ' ';
}
for (i = 0; i < 20; i++) {
if (task_name[i] == '\0') {
break;
}
s_buf_queue_overview[55 + i] = task_name[i];
}
/* print */
print_func(s_buf_queue_overview);
}
}
#else
void krhino_buf_queue_overview(int (*print_func)(const char *fmt, ...))
{
if (print_func == NULL) {
print_func = printf;
}
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
}
#endif
#endif
#if (RHINO_CONFIG_QUEUE > 0)
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
void krhino_queue_overview(int (*print_func)(const char *fmt, ...))
{
int i;
klist_t *listnode;
klist_t *blk_list_head;
ktask_t *task;
kqueue_t *queue;
const name_t *task_name;
char s_queue_overview[] =
"0x 0x 0x 0x \r\n";
if (print_func == NULL) {
print_func = printf;
}
print_func("-------------------------------------------------------\r\n");
print_func("QueAddr TotalSize PeakNum CurrNum TaskWaiting\r\n");
print_func("-------------------------------------------------------\r\n");
for (listnode = g_kobj_list.queue_head.next;
listnode != &g_kobj_list.queue_head; listnode = listnode->next) {
queue = krhino_list_entry(listnode, kqueue_t, queue_item);
if (queue->blk_obj.obj_type != RHINO_QUEUE_OBJ_TYPE) {
print_func("Queue Type error!\r\n");
break;
}
/* set queue information */
k_int2str((int)queue->msg_q.queue_start, &s_queue_overview[2]);
k_int2str((int)queue->msg_q.size, &s_queue_overview[13]);
k_int2str((int)queue->msg_q.peak_num, &s_queue_overview[24]);
k_int2str((int)queue->msg_q.cur_num, &s_queue_overview[35]);
/* set pending task name */
blk_list_head = &queue->blk_obj.blk_list;
if (is_klist_empty(blk_list_head)) {
task_name = " ";
} else {
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
task_name = task->task_name == NULL ? "anonym" : task->task_name;
}
for (i = 0; i < 20; i++) {
s_queue_overview[44 + i] = ' ';
}
for (i = 0; i < 20; i++) {
if (task_name[i] == '\0') {
break;
}
s_queue_overview[44 + i] = task_name[i];
}
/* print */
print_func(s_queue_overview);
}
}
#else
void krhino_queue_overview(int (*print_func)(const char *fmt, ...))
{
if (print_func == NULL) {
print_func = printf;
}
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
}
#endif
#endif
#if (RHINO_CONFIG_SEM > 0)
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
void krhino_sem_overview(int (*print_func)(const char *fmt, ...))
{
int i;
ksem_t *sem;
ktask_t *task;
klist_t *listnode;
klist_t *blk_list_head;
const name_t *task_name;
char s_sem_overview[] =
"0x 0x 0x \r\n";
if (print_func == NULL) {
print_func = printf;
}
print_func("--------------------------------------------\r\n");
print_func("SemAddr Count PeakCount TaskWaiting\r\n");
print_func("--------------------------------------------\r\n");
for (listnode = g_kobj_list.sem_head.next;
listnode != &g_kobj_list.sem_head; listnode = listnode->next) {
sem = krhino_list_entry(listnode, ksem_t, sem_item);
if (sem->blk_obj.obj_type != RHINO_SEM_OBJ_TYPE) {
print_func("Sem Type error!\r\n");
break;
}
/* set sem information */
k_int2str((int)sem, &s_sem_overview[2]);
k_int2str((int)sem->count, &s_sem_overview[13]);
k_int2str((int)sem->peak_count, &s_sem_overview[24]);
/* set pending task name */
blk_list_head = &sem->blk_obj.blk_list;
if (is_klist_empty(blk_list_head)) {
task_name = " ";
} else {
task = krhino_list_entry(blk_list_head->next, ktask_t, task_list);
task_name = task->task_name == NULL ? "anonym" : task->task_name;
}
for (i = 0; i < 20; i++) {
s_sem_overview[33 + i] = ' ';
}
for (i = 0; i < 20; i++) {
if (task_name[i] == '\0') {
break;
}
s_sem_overview[33 + i] = task_name[i];
}
/* print */
print_func(s_sem_overview);
}
}
#else
void krhino_sem_overview(int (*print_func)(const char *fmt, ...))
{
if (print_func == NULL) {
print_func = printf;
}
print_func("RHINO_CONFIG_SYSTEM_STATS in k_config.h is closed!\r\n");
}
#endif
#endif /* RHINO_CONFIG_SEM */
void krhino_overview()
{
int (*print_func)(const char *fmt, ...);
print_func = printf;
#if (RHINO_CONFIG_MM_TLF > 0)
print_func("========== Heap Info ==========\r\n");
krhino_mm_overview(print_func);
#endif
print_func("========== Task Info ==========\r\n");
krhino_task_overview(print_func);
#if (RHINO_CONFIG_QUEUE > 0)
print_func("========== Queue Info ==========\r\n");
krhino_queue_overview(print_func);
#endif
#if (RHINO_CONFIG_BUF_QUEUE > 0)
print_func("======== Buf Queue Info ========\r\n");
krhino_buf_queue_overview(print_func);
#endif
#if (RHINO_CONFIG_SEM > 0)
print_func("=========== Sem Info ===========\r\n");
krhino_sem_overview(print_func);
#endif
}

View file

@ -0,0 +1,266 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdarg.h>
#include "k_dbg_api.h"
#include "aos/cli.h"
#include "aos/kernel.h"
#if (RHINO_CONFIG_PANIC > 0)
#include "k_compiler.h"
#endif
#define DEBUG_PANIC_STEP_MAX 32
/* ARMCC and ICCARM do not use heap when printf a string, but gcc dose*/
#if defined(__CC_ARM)
#define print_str printf
#elif defined(__ICCARM__)
#define print_str printf
#elif defined(__GNUC__)
__attribute__((weak)) int print_str(const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
ret = vprintf(fmt, args);
va_end(args);
fflush(stdout);
return ret;
}
/* on some platform, the libc printf use the heap, while the heap maybe corrupt
when panic.
Redefining a new print_str without using heap is advised on these platform.
*/
#endif
#if (RHINO_CONFIG_PANIC > 0)
/* follow functions should defined by arch\...\panic_c.c */
extern void panicShowRegs(void *context,
int (*print_func)(const char *fmt, ...));
extern void panicGetCtx(void *context, char **pPC, char **pLR, int **pSP);
extern int panicBacktraceCaller(char *PC, int *SP,
int (*print_func)(const char *fmt, ...));
extern int panicBacktraceCallee(char *PC, int *SP, char *LR,
int (*print_func)(const char *fmt, ...));
/* how many steps has finished when crash */
volatile uint32_t g_crash_steps = 0;
static void panic_goto_cli(void)
{
#if 0 /* (defined (CONFIG_AOS_CLI) && (RHINO_CONFIG_SYSTEM_STATS > 0)) */
klist_t *listnode;
ktask_t *task;
for (listnode = g_kobj_list.task_head.next;
listnode != &g_kobj_list.task_head; listnode = listnode->next) {
task = krhino_list_entry(listnode, ktask_t, task_stats_item);
if (0 != strcmp("cli", task->task_name)) {
krhino_task_suspend(task);
}
}
krhino_sched_enable();
krhino_task_overview(print_str);
/*suspend current task*/
task = g_active_task[cpu_cur_get()];
if (0 != strcmp("cli", task->task_name)) {
krhino_task_suspend(task);
}
#endif
}
/* should exeception be restored?
reture 1 YES, 0 NO*/
int panicRestoreCheck(void)
{
return 0;
}
/* fault/exception entry
notice: this function maybe reentried by double exception
first exception, input context
second exception, input NULL */
void panicHandler(void *context)
{
char prt_stack[] =
"stack(0x ): 0x 0x 0x 0x \r\n";
int x;
#if (RHINO_CONFIG_BACKTRACE > 0)
int lvl;
#endif
static int *SP = NULL;
static char *PC = NULL;
static char *LR = NULL;
CPSR_ALLOC();
krhino_sched_disable();
/* g_crash_steps++ before panicHandler */
if (g_crash_steps > 1 && g_crash_steps < DEBUG_PANIC_STEP_MAX) {
print_str("......\r\n");
}
switch (g_crash_steps) {
case 1:
print_str("!!!!!!!!!! Exception !!!!!!!!!!\r\n");
if (context != NULL) {
panicGetCtx(context, &PC, &LR, &SP);
}
panicShowRegs(context, print_str);
g_crash_steps++;
case 2:
if (SP != NULL) {
print_str("========== Stack info ==========\r\n");
for (x = 0; x < 16; x++) {
k_int2str((int)&SP[x * 4], &prt_stack[8]);
k_int2str(SP[x * 4 + 0], &prt_stack[21]);
k_int2str(SP[x * 4 + 1], &prt_stack[32]);
k_int2str(SP[x * 4 + 2], &prt_stack[43]);
k_int2str(SP[x * 4 + 3], &prt_stack[54]);
print_str(prt_stack);
}
}
g_crash_steps++;
#if (RHINO_CONFIG_BACKTRACE > 0)
/* 3 steps, 3 ways to try backtrace */
case 3:
/* Backtrace 1st try: assume ReturnAddr is saved in stack when exception */
if (SP != NULL) {
print_str("========== Call stack ==========\r\n");
lvl = panicBacktraceCaller(PC, SP, print_str);
if (lvl > 0) {
/* backtrace success, do not try other way */
g_crash_steps += 2;
}
/* else, backtrace fail, try another way */
}
g_crash_steps++;
case 4:
if (g_crash_steps == 4) {
/* Backtrace 2nd try: assume ReturnAddr is saved in LR when exception */
if (SP != NULL) {
lvl = panicBacktraceCallee(PC, SP, LR, print_str);
if (lvl > 0) {
/* backtrace success, do not try other way */
g_crash_steps += 1;
}
/* else, backtrace fail, try another way */
}
g_crash_steps++;
}
case 5:
if (g_crash_steps == 5) {
/* Backtrace 3rd try: assume PC is invalalb, backtrace from LR */
if (SP != NULL) {
(void)panicBacktraceCaller(LR, SP, print_str);
}
g_crash_steps++;
}
#else
g_crash_steps = 6;
#endif
#if (RHINO_CONFIG_PANIC_OVERVIEW > 0)
case 6:
#if (RHINO_CONFIG_MM_TLF > 0)
print_str("========== Heap Info ==========\r\n");
krhino_mm_overview(print_str);
#endif
g_crash_steps++;
case 7:
print_str("========== Task Info ==========\r\n");
krhino_task_overview(print_str);
g_crash_steps++;
case 8:
#if (RHINO_CONFIG_QUEUE > 0)
print_str("========== Queue Info ==========\r\n");
krhino_queue_overview(print_str);
#endif
g_crash_steps++;
case 9:
#if (RHINO_CONFIG_BUF_QUEUE > 0)
print_str("======== Buf Queue Info ========\r\n");
krhino_buf_queue_overview(print_str);
#endif
g_crash_steps++;
case 10:
#if (RHINO_CONFIG_SEM > 0)
print_str("=========== Sem Info ===========\r\n");
krhino_sem_overview(print_str);
#endif
g_crash_steps++;
#else
g_crash_steps = 11;
#endif
case 11:
print_str("!!!!!!!!!! dump end !!!!!!!!!!\r\n");
g_crash_steps++;
/* for debug version, last step is CLI */
case 12:
panic_goto_cli();
g_crash_steps++;
default:
break;
}
RHINO_CPU_INTRPT_DISABLE();
while (1) {
/* aos_reboot(); */
}
RHINO_CPU_INTRPT_ENABLE();
}
void debug_fatal_error(kstat_t err, char *file, int line)
{
char prt_stack[] =
"stack(0x ): 0x 0x 0x 0x \r\n";
int x;
int *SP = (int *)RHINO_GET_SP();
CPSR_ALLOC();
krhino_sched_disable();
printf("!!!!!!!!!! Fatal Error !!!!!!!!!!\r\n");
printf("errno:%d , file:%s, line:%d\r\n", err, file, line);
if ( SP != NULL ) {
print_str("========== Stack info ==========\r\n");
for (x = 0; x < 16; x++) {
k_int2str((int)&SP[x * 4], &prt_stack[8]);
k_int2str(SP[x * 4 + 0], &prt_stack[21]);
k_int2str(SP[x * 4 + 1], &prt_stack[32]);
k_int2str(SP[x * 4 + 2], &prt_stack[43]);
k_int2str(SP[x * 4 + 3], &prt_stack[54]);
print_str(prt_stack);
}
}
print_str("========== Heap Info ==========\r\n");
krhino_mm_overview(print_str);
print_str("========== Task Info ==========\r\n");
krhino_task_overview(print_str);
#if (RHINO_CONFIG_BACKTRACE > 0)
krhino_backtrace_now();
#endif
panic_goto_cli();
RHINO_CPU_INTRPT_DISABLE();
while (1) {
/* aos_reboot(); */
}
RHINO_CPU_INTRPT_ENABLE();
}
#endif