|
@@ -5,6 +5,7 @@
|
|
|
#include "exception.h"
|
|
|
#include "system.h"
|
|
|
#include "bsp_time.h"
|
|
|
+#include "bsp_wdt.h"
|
|
|
#include "hal_led.h"
|
|
|
#include "hal_ble_client.h"
|
|
|
#include "hal_ble_host.h"
|
|
@@ -23,6 +24,7 @@
|
|
|
#define EXCEPT_LED_TOGGLE_TIME 200 //异常灯翻转周期,ms为单位
|
|
|
#define EXCEPT_LED_DISPLAY_TIME 10000 //异常灯显示时长,ms为单位
|
|
|
#define UNKOWN_RESET_INFO_SEND_CYCLE 100 //未知重启异常信息发送线程周期,ms为单位
|
|
|
+#define EXCEPT_NO_INIT_DATA_CHANGE_FLAG 0x01 //被更改标志位,每次修改结构体,都要加1
|
|
|
#define __NO_INIT__ __attribute__((at(0x2000FFA0)))
|
|
|
|
|
|
/*STRUCTION ----------------------------------------------------*/
|
|
@@ -41,6 +43,25 @@ typedef struct
|
|
|
uint32_t xPSR;
|
|
|
}STACK_DATA_TYPE;
|
|
|
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ uint32_t wdt_remain_tim; //距离上次喂狗剩余时间,单位ms
|
|
|
+ uint32_t thread_start_tim;
|
|
|
+ uint32_t thread_end_tim;
|
|
|
+}WDT_INFO_TYPE;
|
|
|
+
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ char buff[28];
|
|
|
+}APP_ERROR_CHECK_INFO_TYPE;
|
|
|
+
|
|
|
+typedef struct _process_info
|
|
|
+{
|
|
|
+ STACK_DATA_TYPE stack;
|
|
|
+ WDT_INFO_TYPE wdt_info;
|
|
|
+ APP_ERROR_CHECK_INFO_TYPE app_error_check_info;
|
|
|
+}Process_Info_t;
|
|
|
+
|
|
|
typedef enum{
|
|
|
EXCEPT_LED_ON, //异常灯 - 开
|
|
|
EXCEPT_LED_OFF, //异常灯 - 关
|
|
@@ -52,22 +73,25 @@ typedef enum{
|
|
|
|
|
|
EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT, //异常——未知重启触发原因——跑飞
|
|
|
|
|
|
+ EXCEPT_UNKOWN_RESET_TRIGGER_APP_ERROR_CHECK, //异常——APP_ERROR_CHECK
|
|
|
+
|
|
|
EXCEPT_UNKOWN_RESET_TRIGGER_NUMS, //异常——未知重启触发原因——数量
|
|
|
|
|
|
} EXCEPT_UNKOWN_RESET_TRIGGER_e;
|
|
|
|
|
|
typedef struct _except_unkown_reset_info
|
|
|
{
|
|
|
- STACK_DATA_TYPE stack; //堆栈信息
|
|
|
+ Process_Info_t process_info; //线程信息(堆栈信息和看门狗信息)
|
|
|
+ uint32_t trigger; //导致未知重启触发的类型
|
|
|
uint32_t cur_process_id; //当前正在处理的进程号
|
|
|
- EXCEPT_UNKOWN_RESET_TRIGGER_e trigger; //导致未知重启触发的类型
|
|
|
- bool is_upload; //是否正在上传
|
|
|
-
|
|
|
+ uint32_t end_process_id; //处理完的进程号
|
|
|
+ uint8_t is_upload; //是否正在上传
|
|
|
} Except_Unkown_Reset_Info_t;
|
|
|
|
|
|
typedef struct no_init
|
|
|
{
|
|
|
- Except_Unkown_Reset_Info_t unkown_reset_info[EXCEPT_UNKOWN_RESET_TRIGGER_NUMS];
|
|
|
+ Except_Unkown_Reset_Info_t unkown_reset_info;
|
|
|
+ uint32_t struct_change_flag; //被更改标志位
|
|
|
} No_Init_t;
|
|
|
|
|
|
typedef struct exception{
|
|
@@ -111,24 +135,14 @@ static void Except_NotOSHardFault_Handler(uint32_t msp_addr)
|
|
|
|
|
|
msp_addr += 8; //进入中断后,堆栈又进入了2个u32数据,因此需要往后推
|
|
|
|
|
|
- no_init_data.unkown_reset_info[EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT].is_upload = true;
|
|
|
+ no_init_data.unkown_reset_info.is_upload = 1;
|
|
|
|
|
|
- no_init_data.unkown_reset_info[EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT].trigger = EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT;
|
|
|
+ no_init_data.unkown_reset_info.trigger |= (1<<EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT);
|
|
|
|
|
|
- memcpy((void *)&no_init_data.unkown_reset_info[EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT].stack, (STACK_DATA_TYPE *)msp_addr, sizeof(STACK_DATA_TYPE));
|
|
|
+ memcpy((void *)&no_init_data.unkown_reset_info.process_info.stack, (STACK_DATA_TYPE *)msp_addr, sizeof(STACK_DATA_TYPE));
|
|
|
|
|
|
p = (STACK_DATA_TYPE *)msp_addr;
|
|
|
p->PC -= 3; //PC指针要减去3
|
|
|
-//
|
|
|
-// DEBUG_LOG("R0:0x%08X\r\n", p->R0);
|
|
|
-// DEBUG_LOG("R1:0x%08X\r\n", p->R1);
|
|
|
-// DEBUG_LOG("R2:0x%08X\r\n", p->R2);
|
|
|
-// DEBUG_LOG("R3:0x%08X\r\n", p->R3);
|
|
|
-// DEBUG_LOG("R12:0x%08X\r\n", p->R12);
|
|
|
-// DEBUG_LOG("LR:0x%08X\r\n", p->LR);
|
|
|
-// DEBUG_LOG("PC:0x%08X\r\n", p->PC);
|
|
|
-// DEBUG_LOG("xPSR:0x%08X\r\n", p->xPSR);
|
|
|
-// DEBUG_LOG("system reset...\r\n");
|
|
|
}
|
|
|
|
|
|
////有操作系统时的异常处理
|
|
@@ -214,7 +228,6 @@ static void Exception_Led_Process(void)
|
|
|
else return;
|
|
|
|
|
|
//把鞋子倒转平放,且存在异常
|
|
|
-// DEBUG_LOG("Exception_Led_Process:%d,%d,%d\n",f_acc[0],f_acc[1],f_acc[2]);
|
|
|
if(f_acc[2] >= EXCEPT_LED_ON_ACC_Z && ob_exception.except_number_of_exist > 0)
|
|
|
{
|
|
|
Except_Led_OpenOnce();
|
|
@@ -227,58 +240,60 @@ static void Exception_Led_Process(void)
|
|
|
|
|
|
static void Exception_UnkownReset_Info_Send_Process(void)
|
|
|
{
|
|
|
+ uint32_t tim;
|
|
|
char buf[250]={0};
|
|
|
memset(buf,0,sizeof(buf));
|
|
|
-
|
|
|
-// static uint8_t cur_flow = 0;
|
|
|
-
|
|
|
- for(int i = 0; i < EXCEPT_UNKOWN_RESET_TRIGGER_NUMS; i++)
|
|
|
+
|
|
|
+ if(no_init_data.unkown_reset_info.is_upload == 1)
|
|
|
{
|
|
|
- if(no_init_data.unkown_reset_info[i].is_upload == true)
|
|
|
+ if((no_init_data.unkown_reset_info.trigger & (1<<EXCEPT_UNKOWN_RESET_TRIGGER_WDT)) != 0)
|
|
|
{
|
|
|
- switch(no_init_data.unkown_reset_info[i].trigger)
|
|
|
+ tim = no_init_data.unkown_reset_info.process_info.wdt_info.thread_end_tim;
|
|
|
+ if(tim < no_init_data.unkown_reset_info.process_info.wdt_info.thread_start_tim)tim += 16777216;
|
|
|
+
|
|
|
+ sprintf(buf,"id:0x%x,0x%x,%d,%f\r\n",no_init_data.unkown_reset_info.cur_process_id,no_init_data.unkown_reset_info.end_process_id, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.wdt_info.wdt_remain_tim, \
|
|
|
+ (tim-no_init_data.unkown_reset_info.process_info.wdt_info.thread_start_tim)/32.768);
|
|
|
+ if(Except_TxError(EXCEPT_UNKOWN_RESET,buf) == 0)
|
|
|
{
|
|
|
- case EXCEPT_UNKOWN_RESET_TRIGGER_WDT:
|
|
|
- sprintf(buf,"id:%d\r\n",no_init_data.unkown_reset_info[i].cur_process_id);
|
|
|
- if(Except_TxError(EXCEPT_UNKOWN_RESET,buf) == 0){no_init_data.unkown_reset_info[i].is_upload = false;}
|
|
|
- break;
|
|
|
-
|
|
|
- case EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT:
|
|
|
- sprintf(buf,"id:0x%x,R:0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,H:0x%x,S:0x%x\r\n", no_init_data.unkown_reset_info[i].cur_process_id, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.R0, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.R1, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.R2, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.R3, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.R12, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.LR, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.PC - 3, \
|
|
|
- no_init_data.unkown_reset_info[i].stack.xPSR,
|
|
|
- HARDWARE_VERSION,SOFTWARE_VERSION);
|
|
|
-// DEBUG_LOG("%s\r\n", buf);
|
|
|
- if(Except_TxError(EXCEPT_UNKOWN_RESET,buf) == 0){no_init_data.unkown_reset_info[i].is_upload = false;}
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- no_init_data.unkown_reset_info[i].is_upload = false;
|
|
|
- break;
|
|
|
+ no_init_data.unkown_reset_info.trigger &= ~(1<<EXCEPT_UNKOWN_RESET_TRIGGER_WDT);
|
|
|
+ if(no_init_data.unkown_reset_info.trigger == 0)no_init_data.unkown_reset_info.is_upload = 0;
|
|
|
}
|
|
|
-
|
|
|
- if(no_init_data.unkown_reset_info[i].trigger == EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT)
|
|
|
+ }
|
|
|
+ else if((no_init_data.unkown_reset_info.trigger & (1<<EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT)) != 0)
|
|
|
+ {
|
|
|
+ sprintf(buf,"id:0x%x,0x%x,R:0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,H:0x%x,S:0x%x\r\n", no_init_data.unkown_reset_info.cur_process_id,no_init_data.unkown_reset_info.end_process_id, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.R0, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.R1, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.R2, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.R3, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.R12, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.LR, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.PC - 3, \
|
|
|
+ no_init_data.unkown_reset_info.process_info.stack.xPSR,
|
|
|
+ HARDWARE_VERSION,SOFTWARE_VERSION);
|
|
|
+ if(Except_TxError(EXCEPT_UNKOWN_RESET,buf) == 0)
|
|
|
{
|
|
|
-// DEBUG_LOG("R0:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.R0);
|
|
|
-// DEBUG_LOG("R1:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.R1);
|
|
|
-// DEBUG_LOG("R2:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.R2);
|
|
|
-// DEBUG_LOG("R3:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.R3);
|
|
|
-// DEBUG_LOG("R12:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.R12);
|
|
|
-// DEBUG_LOG("LR:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.LR);
|
|
|
-// DEBUG_LOG("PC:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.PC - 3);
|
|
|
-// DEBUG_LOG("xPSR:0x%08X\r\n", no_init_data.unkown_reset_info[i].stack.xPSR);
|
|
|
+ no_init_data.unkown_reset_info.trigger &= ~(1<<EXCEPT_UNKOWN_RESET_TRIGGER_RUN_OUT);
|
|
|
+ if(no_init_data.unkown_reset_info.trigger == 0)no_init_data.unkown_reset_info.is_upload = 0;
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+ else if((no_init_data.unkown_reset_info.trigger & (1<<EXCEPT_UNKOWN_RESET_TRIGGER_APP_ERROR_CHECK)) != 0)
|
|
|
+ {
|
|
|
+ sprintf(buf,"id:0x%x,0x%x,%s",no_init_data.unkown_reset_info.cur_process_id,no_init_data.unkown_reset_info.end_process_id,no_init_data.unkown_reset_info.process_info.app_error_check_info.buff);
|
|
|
+ if(Except_TxError(EXCEPT_UNKOWN_RESET,buf) == 0)
|
|
|
{
|
|
|
-// DEBUG_LOG("id:%d\r\n", no_init_data.unkown_reset_info[i].cur_process_id);
|
|
|
+ no_init_data.unkown_reset_info.trigger &= ~(1<<EXCEPT_UNKOWN_RESET_TRIGGER_APP_ERROR_CHECK);
|
|
|
+ if(no_init_data.unkown_reset_info.trigger == 0)no_init_data.unkown_reset_info.is_upload = 0;
|
|
|
}
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //跑飞数据被篡改了
|
|
|
+ memset((void*)&no_init_data, 0 , sizeof(No_Init_t));
|
|
|
+ no_init_data.struct_change_flag = EXCEPT_NO_INIT_DATA_CHANGE_FLAG;
|
|
|
+ no_init_data.unkown_reset_info.is_upload = 0;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -297,7 +312,14 @@ void cb_BLE_Host_R_ERR(void* handle)
|
|
|
|
|
|
void Exception_Init(void)
|
|
|
{
|
|
|
-// memset(&no_init_data, 0 , sizeof(No_Init_t)*EXCEPT_UNKOWN_RESET_TRIGGER_NUMS);
|
|
|
+ //若结构体被改动,则重置。
|
|
|
+ if(no_init_data.struct_change_flag != EXCEPT_NO_INIT_DATA_CHANGE_FLAG)
|
|
|
+ {
|
|
|
+ memset((void*)&no_init_data, 0 , sizeof(No_Init_t));
|
|
|
+ no_init_data.struct_change_flag = EXCEPT_NO_INIT_DATA_CHANGE_FLAG;
|
|
|
+ no_init_data.unkown_reset_info.is_upload = 0;
|
|
|
+ }
|
|
|
+
|
|
|
memset(&ob_exception, 0 , sizeof(ob_exception));
|
|
|
ob_exception.led_switch = EXCEPT_LED_OFF;
|
|
|
ob_exception.led_display_time = EXCEPT_LED_DISPLAY_TIME/LED_PROCESS_CYCLE;
|
|
@@ -309,14 +331,8 @@ void Exception_Init(void)
|
|
|
|
|
|
BLE_Host_Rx_Regist(BLE_ERR,cb_BLE_Host_R_ERR);
|
|
|
|
|
|
-// DEBUG_LOG("Exception_Init - sizeof(no_init_data):%d\r\n", sizeof(no_init_data));
|
|
|
-
|
|
|
memcpy(&battery_record,&mFlash.mbattercb_t,sizeof(battercb_t));
|
|
|
|
|
|
- extern void printbatter_cb(battercb_t *c,battercb_t *C_flash);
|
|
|
-
|
|
|
-// printbatter_cb(&battery_record,&mFlash.mbattercb_t);
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -326,9 +342,49 @@ void Exception_Init(void)
|
|
|
*/
|
|
|
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
|
|
|
{
|
|
|
+ char err_info[200];
|
|
|
+
|
|
|
Flash_SaveLog(id,pc,info);
|
|
|
DEBUG_LOG("app_error_fault_handler,System reset\n");
|
|
|
-// nrf_gpio_cfg_output(PIN_RESET_PIN); nrf_gpio_pin_write(PIN_RESET_PIN,0);
|
|
|
+
|
|
|
+ no_init_data.unkown_reset_info.is_upload = 1;
|
|
|
+ no_init_data.unkown_reset_info.trigger |= (1<<EXCEPT_UNKOWN_RESET_TRIGGER_APP_ERROR_CHECK);
|
|
|
+ memset((void *)&no_init_data.unkown_reset_info.process_info.app_error_check_info, 0, sizeof(APP_ERROR_CHECK_INFO_TYPE));
|
|
|
+ switch (id)
|
|
|
+ {
|
|
|
+ #if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
|
|
|
+ case NRF_FAULT_ID_SD_ASSERT:
|
|
|
+ memcpy((void *)&no_init_data.unkown_reset_info.process_info.app_error_check_info,"SD: ASSERTION FAILED\r\n",sizeof(APP_ERROR_CHECK_INFO_TYPE));
|
|
|
+ break;
|
|
|
+ case NRF_FAULT_ID_APP_MEMACC:
|
|
|
+ memcpy((void *)&no_init_data.unkown_reset_info.process_info.app_error_check_info,"SD: INVALID MEMORY ACCESS\r\n",sizeof(APP_ERROR_CHECK_INFO_TYPE));
|
|
|
+ break;
|
|
|
+ #endif
|
|
|
+ case NRF_FAULT_ID_SDK_ASSERT:
|
|
|
+ {
|
|
|
+ assert_info_t * p_info = (assert_info_t *)info;
|
|
|
+ sprintf((char *)err_info,"f:%s,l:%u\r\n",
|
|
|
+ p_info->p_file_name,
|
|
|
+ p_info->line_num);
|
|
|
+ memcpy((void *)&no_init_data.unkown_reset_info.process_info.app_error_check_info,err_info,sizeof(APP_ERROR_CHECK_INFO_TYPE));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case NRF_FAULT_ID_SDK_ERROR:
|
|
|
+ {
|
|
|
+ error_info_t * p_info = (error_info_t *)info;
|
|
|
+ sprintf((char *)err_info,"e:%u,f:%s,l:%u\r\n",
|
|
|
+ p_info->err_code,
|
|
|
+ p_info->p_file_name,
|
|
|
+ p_info->line_num);
|
|
|
+ memcpy((void *)&no_init_data.unkown_reset_info.process_info.app_error_check_info,err_info,sizeof(APP_ERROR_CHECK_INFO_TYPE));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ sprintf((char *)err_info,"UNKNOWN FAULT 0x%08X\n", pc);
|
|
|
+ memcpy((void *)&no_init_data.unkown_reset_info.process_info.app_error_check_info,err_info,sizeof(APP_ERROR_CHECK_INFO_TYPE));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
NVIC_SystemReset(); //复位重启
|
|
|
}
|
|
|
|
|
@@ -378,13 +434,6 @@ bool Except_IsError(ExcepType_t excep_type)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-//bool Except_IsErrorExist(void)
|
|
|
-//{
|
|
|
-// if(ob_exception.except_number_of_exist > 0)return true;
|
|
|
-//
|
|
|
-// return false;
|
|
|
-//}
|
|
|
-
|
|
|
//硬件中断
|
|
|
void HardFault_Handler (void)
|
|
|
{
|
|
@@ -411,19 +460,32 @@ void HardFault_Handler (void)
|
|
|
|
|
|
void Except_Get_Cur_Porcess_ID(uint32_t cur_process_id)
|
|
|
{
|
|
|
- for(int i = 0; i < EXCEPT_UNKOWN_RESET_TRIGGER_NUMS; i++)
|
|
|
+ uint32_t cur_tim,feed_watchdogtim;
|
|
|
+
|
|
|
+ if(no_init_data.unkown_reset_info.is_upload == 0)
|
|
|
{
|
|
|
- if(no_init_data.unkown_reset_info[i].is_upload == false)
|
|
|
- {
|
|
|
- no_init_data.unkown_reset_info[i].cur_process_id = cur_process_id;
|
|
|
- }
|
|
|
+ no_init_data.unkown_reset_info.cur_process_id = cur_process_id;
|
|
|
+ cur_tim = NRF_RTC0->COUNTER;
|
|
|
+ feed_watchdogtim = Get_FeedWatchDogTime();
|
|
|
+ if(cur_tim<feed_watchdogtim) cur_tim += 16777216;
|
|
|
+ no_init_data.unkown_reset_info.process_info.wdt_info.wdt_remain_tim = WDT_RELOAD_VALUE - ((cur_tim-feed_watchdogtim)/32.768);
|
|
|
+ no_init_data.unkown_reset_info.process_info.wdt_info.thread_start_tim = cur_tim;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Except_Get_End_Porcess_ID(uint32_t end_process_id)
|
|
|
+{
|
|
|
+ if(no_init_data.unkown_reset_info.is_upload == 0)
|
|
|
+ {
|
|
|
+ no_init_data.unkown_reset_info.end_process_id = end_process_id;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void Except_Unkown_Reset_WDT_Set(void)
|
|
|
{
|
|
|
- no_init_data.unkown_reset_info[EXCEPT_UNKOWN_RESET_TRIGGER_WDT].is_upload = true;
|
|
|
- no_init_data.unkown_reset_info[EXCEPT_UNKOWN_RESET_TRIGGER_WDT].trigger = EXCEPT_UNKOWN_RESET_TRIGGER_WDT;
|
|
|
+ no_init_data.unkown_reset_info.is_upload = 1;
|
|
|
+ no_init_data.unkown_reset_info.trigger |= (1<<EXCEPT_UNKOWN_RESET_TRIGGER_WDT);
|
|
|
+ no_init_data.unkown_reset_info.process_info.wdt_info.thread_end_tim = NRF_RTC0->COUNTER;
|
|
|
}
|
|
|
|
|
|
/**
|