General Exception Handler in PIC32 in MPLAB -X , How does software know when to throw this?

大兔子大兔子 提交于 2019-12-24 19:19:14

问题


void _general_exception_handler (unsigned caused, unsigned status)
    {
       RCON = RCON_EXCEPTION;

       // Point of No return.
       Kernel_Reset();
    }

My code seems to be getting in this trap and I have few questions to figure out why it get here from calling valid functions in my code or the better question that keeps bothering me is how does the processor know there has been a violation.

1) When I look in the watch window in the debugger, the cause shows me Address 0xA0007EC0 and the value 0x10800C1C and the status shows me address 0xA0007EC4 and value is 0x00100003. How can I, From these Address and value information figure out the cause and status of the exception? 2) How does the processor know that there has been an exception fault?


回答1:


Here is the handler I usually use in a PIC32 project:

//  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  



回答2:


I had an issue that turned out to be a bug in microchip's code:

sprintf(foo_str, "%f", NAN)

would (and will) throw a bus error exception... (bug in their "_fconvert" function) To debug/identify that I modified my exception handler to print out (product was already had an ASCII UART connection to its host) what the exception was, what the violating address was and then it will reset itself. The reset portion was hard to find, it is in one of the many Microchip docs for the PIC32MX. This replaces the Harmony (1.10) generated "_general_exception_handler()", not sure if it's compatible with 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);
}

I did have to play with it a bit to ensure that the message got thru the output FIFO before the reset was invoked...



来源:https://stackoverflow.com/questions/45299750/general-exception-handler-in-pic32-in-mplab-x-how-does-software-know-when-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!