vagrant-vbguest
我的代码似乎进入了这个陷阱,我几乎无法弄清楚为什么它来自我的代码中调用有效函数或更好的问题一直困扰着我是处理器如何知道存在违规。
1)当我在调试器中查看监视窗口时,void _general_exception_handler (unsigned caused, unsigned status)
{
RCON = RCON_EXCEPTION;
// Point of No return.
Kernel_Reset();
}
向我显示cause
,Address 0xA0007EC0
和value 0x10800C1C
向我显示status
和address 0xA0007EC4
。我怎样才能从这些地址和价值信息中找出异常的原因和状态?
2)处理器如何知道存在异常故障?
答案 0 :(得分:0)
这是我在PIC32项目中经常使用的处理程序:
// Exception handler:
static enum {
EXCEP_IRQ = 0, // interrupt
EXCEP_AdEL = 4, // address error exception (load or ifetch)
EXCEP_AdES, // address error exception (store)
EXCEP_IBE, // bus error (ifetch)
EXCEP_DBE, // bus error (load/store)
EXCEP_Sys, // syscall
EXCEP_Bp, // breakpoint
EXCEP_RI, // reserved instruction
EXCEP_CpU, // coprocessor unusable
EXCEP_Overflow, // arithmetic overflow
EXCEP_Trap, // trap (possible divide by zero)
EXCEP_IS1 = 16, // implementation specfic 1
EXCEP_CEU, // CorExtend Unuseable
EXCEP_C2E // coprocessor 2
} _excep_code;
static unsigned int _epc_code;
static unsigned int _excep_addr;
// this function overrides the normal _weak_ generic handler
void _general_exception_handler(void)
{
asm volatile("mfc0 %0,$13" : "=r" (_excep_code));
asm volatile("mfc0 %0,$14" : "=r" (_excep_addr));
_excep_code = (_excep_code & 0x0000007C) >> 2;
while (1) {
// Examine _excep_code to identify the type of exception
// Examine _excep_addr to find the address that caused the
exception
Nop();
Nop();
Nop();
}
}// End of exception handler
答案 1 :(得分:0)
我遇到的问题是微芯片代码中的错误:
sprintf(foo_str, "%f", NAN)
会(并且会)抛出一个总线错误异常...(“_fconvert”函数中的错误)调试/识别我修改了我的异常处理程序以打印出来(产品已经与其主机有ASCII UART连接)异常是什么,违反的地址是什么,然后它将重置自己。重置部分很难找到,它是PIC32MX的许多Microchip文档之一。这取代了Harmony(1.10)生成的“_general_exception_handler()”,不确定它是否与Harmony 2.x兼容
void _general_exception_handler ( void )
{
char fail_str[96];
/* Mask off Mask of the ExcCode Field from the Cause Register
Refer to the MIPs Software User's manual */
_excep_code = (_CP0_GET_CAUSE() & 0x0000007C) >> 2;
_excep_addr = _CP0_GET_EPC();
_cause_str = cause[_excep_code];
sprintf(fail_str, "ERROR,%s,cause=%d,addr=%x,",
_cause_str, _excep_code, _excep_addr);
//"send_my_string" copies the string to the ring buffer
send_my_string(fail_str);
//"tx_chars_from_ring_buffer" returns # of chars left in the ring buffer
while(tx_chars_from_ring_buffer());
//queue up another set of chars equal to the length of the UART FIFO
sprintf(fail_str, "\r\r\r\r\r\r\r\r\r\r");
send_my_string(fail_str);
while(tx_chars_from_ring_buffer());
#if (__DEBUG)
while (1)
{
SYS_DEBUG_BreakPoint();
}
#endif
/* The following code illustrates a software Reset */
// assume interrupts are disabled
// assume the DMA controller is suspended
// assume the device is locked
/* perform a system unlock sequence */
// starting critical sequence
SYSKEY = 0x00000000; //write invalid key to force lock
SYSKEY = 0xAA996655; //write key1 to SYSKEY
SYSKEY = 0x556699AA; //write key2 to SYSKEY
// OSCCON is now unlocked
/* set SWRST bit to arm reset */
RSWRSTSET = 1;
/* read RSWRST register to trigger reset */
_excep_code = RSWRST;
/* prevent any unwanted code execution until reset occurs*/
while(1);
}
我必须稍微玩一下,以确保在调用重置之前消息通过输出FIFO ...