修正中断模块里面的异常日志输出

This commit is contained in:
nnhy 2014-08-17 18:51:21 +00:00
parent cf8edc1ff3
commit 88ef493e48
2 changed files with 90 additions and 65 deletions

View File

@ -210,86 +210,111 @@ void FAULT_SubHandler()
// 显示异常详细信息
int i;
if(exception==3)
debug_printf("硬件错误\r\n");
if(exception==5)
{
uint n = *(uint*)(0xE000ED2C);
debug_printf("\r\n硬件错误 %d\r\n", n);
if(n & (1<<1))
{
debug_printf("硬fault 是在取向量时发生的\r\n");
}
else if(n & (1u<<30))
{
debug_printf("硬fault 是总线fault存储器管理fault 或是用法fault 上访的结果\r\n");
}
else if(n & (1u<<31))
{
debug_printf("硬fault 因调试事件而产生\r\n");
}
}
else if(exception==5)
{
i = *(byte*)(0xE000ED29);
#ifdef STM32F10X
debug_printf("\r\nBus Fault %d 0x%08x: ", i, SCB->BFAR);
debug_printf("\r\nBus Fault %d 0x%08x: \r\n", i, SCB->BFAR);
#endif
switch(i)
if(i & (1<<0))
{
case 0:
debug_printf("IBUSERR 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了
break;
case 1:
debug_printf("PRECISERR 在数据访问期间的总线错误。通过BFAR可以获取具体的地址。发生fault的原因同上。"); // 在数据访问期间的总线错误。通过BFAR可以获取具体的地址。发生fault的原因同上。
break;
case 2:
debug_printf("IMPRECISERR 与设备之间传送数据的过程中发生总线错误。可能是因为设备未经初始化而引起或者在用户级访问了特权级的设备或者传送的数据单位尺寸不能为设备所接受。此时有可能是LDM/STM指令造成了非精确总线fault。"); // 与设备之间传送数据的过程中发生总线错误。可能是因为设备未经初始化而引起或者在用户级访问了特权级的设备或者传送的数据单位尺寸不能为设备所接受。此时有可能是LDM/STM指令造成了非精确总线fault。
break;
case 3:
debug_printf("UNSTKERR 自动出栈期间出错。如果没有发生过STKERR则最可能的就是在异常处理期间把SP的值破坏了"); // 自动出栈期间出错。如果没有发生过STKERR则最可能的就是在异常处理期间把SP的值破坏了
break;
case 4:
debug_printf("STKERR (自动)入栈期间出错 1. 堆栈指针的值被破坏 2. 堆栈用量太大,到达了未定义存储器的区域 3. PSP未经初始化就使用"); // (自动)入栈期间出错 1. 堆栈指针的值被破坏 2. 堆栈用量太大,到达了未定义存储器的区域 3. PSP未经初始化就使用
break;
case 7:
debug_printf("BFARVALID 表示BFAR有效"); // 表示BFAR有效
break;
debug_printf("IBUSERR 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了\r\n"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了
}
debug_printf("\r\n");
}else if(exception==4)
else if(i & (1<<1))
{
debug_printf("PRECISERR 在数据访问期间的总线错误。通过BFAR可以获取具体的地址。发生fault的原因同上。\r\n"); // 在数据访问期间的总线错误。通过BFAR可以获取具体的地址。发生fault的原因同上。
}
else if(i & (1<<2))
{
debug_printf("IMPRECISERR 与设备之间传送数据的过程中发生总线错误。可能是因为设备未经初始化而引起或者在用户级访问了特权级的设备或者传送的数据单位尺寸不能为设备所接受。此时有可能是LDM/STM指令造成了非精确总线fault。\r\n"); // 与设备之间传送数据的过程中发生总线错误。可能是因为设备未经初始化而引起或者在用户级访问了特权级的设备或者传送的数据单位尺寸不能为设备所接受。此时有可能是LDM/STM指令造成了非精确总线fault。
}
else if(i & (1<<3))
{
debug_printf("UNSTKERR 自动出栈期间出错。如果没有发生过STKERR则最可能的就是在异常处理期间把SP的值破坏了\r\n"); // 自动出栈期间出错。如果没有发生过STKERR则最可能的就是在异常处理期间把SP的值破坏了
}
else if(i & (1<<4))
{
debug_printf("STKERR (自动)入栈期间出错 1. 堆栈指针的值被破坏 2. 堆栈用量太大,到达了未定义存储器的区域 3. PSP未经初始化就使用\r\n"); // (自动)入栈期间出错 1. 堆栈指针的值被破坏 2. 堆栈用量太大,到达了未定义存储器的区域 3. PSP未经初始化就使用
}
else if(i & (1<<5))
{
debug_printf("BFARVALID 表示BFAR有效\r\n"); // 表示BFAR有效
}
//debug_printf("\r\n");
}
else if(exception==4)
{
i = *(byte*)(0xE000ED28);
#ifdef STM32F10X
debug_printf("\r\nMemManage Fault %d 0x%08x: ", i, SCB->MMFAR);
debug_printf("\r\nMemManage Fault %d 0x%08x: \r\n", i, SCB->MMFAR);
#endif
switch(i)
if(i & (1<<0))
{
case 0:
debug_printf("IACCVIOL 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了
break;
case 1:
debug_printf("DACCVIOL 数据内存访问保护违例。一般是访问非法内存位置所致。可以注意筛查野指针问题。"); // 内存访问保护违例。这是MPU发挥作用的体现。常常是用户应用程序企图访问特权级region所致
break;
case 3:
debug_printf("MUNSTKERR 出栈时发生错误 1. 异常服务例程破坏了堆栈指针 2. 异常服务例程更改了MPU配置"); // 出栈时发生错误 1. 异常服务例程破坏了堆栈指针 2. 异常服务例程更改了MPU配置
break;
case 4:
debug_printf("MSTKERR 入栈时发生错误 1. 堆栈指针的值被破坏 2. 堆栈容易过大已经超出MPU允许的region范围"); // 入栈时发生错误 1. 堆栈指针的值被破坏 2. 堆栈容易过大已经超出MPU允许的region范围
break;
case 7:
debug_printf("MMARVALID 表示MMAR有效"); // 表示MMAR有效
break;
debug_printf("IACCVIOL 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了\r\n"); // 取指访问违例 1. 内存访问保护违例。常常是用户应用程序企图访问特权级region。在这种情况下入栈的PC给出的地址就是产生问题的代码之所在 2. 跳转到不可执行指令的 regions 3. 异常返回时使用了无效的EXC_RETURN值 4. 向量表中有无效的向量。例如异常在向量建立之前就发生了或者加载的是用于传统ARM内核的可执行映像 5. 在异常处理期间入栈的PC值被破坏了
}
debug_printf("\r\n");
}else if(exception==6)
else if(i & (1<<1))
{
debug_printf("DACCVIOL 数据内存访问保护违例。一般是访问非法内存位置所致。可以注意筛查野指针问题。\r\n"); // 内存访问保护违例。这是MPU发挥作用的体现。常常是用户应用程序企图访问特权级region所致
}
else if(i & (1<<3))
{
debug_printf("MUNSTKERR 出栈时发生错误 1. 异常服务例程破坏了堆栈指针 2. 异常服务例程更改了MPU配置\r\n"); // 出栈时发生错误 1. 异常服务例程破坏了堆栈指针 2. 异常服务例程更改了MPU配置
}
else if(i & (1<<4))
{
debug_printf("MSTKERR 入栈时发生错误 1. 堆栈指针的值被破坏 2. 堆栈容易过大已经超出MPU允许的region范围\r\n"); // 入栈时发生错误 1. 堆栈指针的值被破坏 2. 堆栈容易过大已经超出MPU允许的region范围
}
else if(i & (1<<7))
{
debug_printf("MMARVALID 表示MMAR有效\r\n"); // 表示MMAR有效
}
//debug_printf("\r\n");
}
else if(exception==6)
{
i = *(byte*)(0xE000ED2A);
debug_printf("\r\nUsage Fault %d: ", i);
switch(i)
debug_printf("\r\nUsage Fault %d: \r\n", i);
if(i & (1<<0))
{
case 0:
debug_printf("UNDEFINSTR 执行的指令其编码是未定义的——解码不能"); // 执行的指令其编码是未定义的——解码不能
break;
case 1:
debug_printf("INVSTATE 试图切入ARM状态"); // 试图切入ARM状态
break;
case 2:
debug_printf("INVPC 在异常返回时试图非法地加载EXC_RETURN到PC"); // 在异常返回时试图非法地加载EXC_RETURN到PC。包括非法的指令非法的上下文以及非法的EXC_RETURN值。The return PC指向的指令试图设置PC的值
break;
case 3:
debug_printf("NOCP 企图执行一个协处理器指令。引发此fault的指令可以从入栈的PC读取"); // 企图执行一个协处理器指令。引发此fault的指令可以从入栈的PC读取
break;
case 8:
debug_printf("UNALIGNED 当UNALIGN_TRP置位时发生未对齐访问。引发此fault的指令可以从入栈的PC读取"); // 当UNALIGN_TRP置位时发生未对齐访问。引发此fault的指令可以从入栈的PC读取
break;
case 9:
debug_printf("DIVBYZERO 表示除法运算时除数为零。引发此fault的指令可以从入栈的PC读取"); // 表示除法运算时除数为零只有在DIV_0_TRP置位时才会发生。引发此fault的指令可以从入栈的PC读取
break;
debug_printf("UNDEFINSTR 执行的指令其编码是未定义的——解码不能\r\n"); // 执行的指令其编码是未定义的——解码不能
}
debug_printf("\r\n");
else if(i & (1<<1))
{
debug_printf("INVSTATE 试图切入ARM状态\r\n"); // 试图切入ARM状态
}
else if(i & (1<<2))
{
debug_printf("INVPC 在异常返回时试图非法地加载EXC_RETURN到PC\r\n"); // 在异常返回时试图非法地加载EXC_RETURN到PC。包括非法的指令非法的上下文以及非法的EXC_RETURN值。The return PC指向的指令试图设置PC的值
}
else if(i & (1<<3))
{
debug_printf("NOCP 企图执行一个协处理器指令。引发此fault的指令可以从入栈的PC读取\r\n"); // 企图执行一个协处理器指令。引发此fault的指令可以从入栈的PC读取
}
else if(i & (1<<4))
{
debug_printf("UNALIGNED 当UNALIGN_TRP置位时发生未对齐访问。引发此fault的指令可以从入栈的PC读取\r\n"); // 当UNALIGN_TRP置位时发生未对齐访问。引发此fault的指令可以从入栈的PC读取
}
else if(i & (1<<5))
{
debug_printf("DIVBYZERO 表示除法运算时除数为零。引发此fault的指令可以从入栈的PC读取\r\n"); // 表示除法运算时除数为零只有在DIV_0_TRP置位时才会发生。引发此fault的指令可以从入栈的PC读取
}
//debug_printf("\r\n");
}
#endif

2
Sys.h
View File

@ -57,7 +57,7 @@ public:
uint CystalClock; // 晶振时钟
byte MessagePort; // 消息口默认0表示USART1
#if defined(STM32F0XX) && !defined(GD32)
byte ID[4]; // 芯片ID
byte ID[12]; // 芯片ID
#else
byte ID[12]; // 芯片ID
#endif