This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Way to find cause of error

Other Parts Discussed in Thread: HALCOGEN

Hello.

RM57, CCS 6.0.1 is used in my system. An ethernet communication has been developed and tested now, but there is an error and I can't find the causes. It goes to ' _c_int00' when data is received or stopped on  'dataEntry' frequently. Is there any way to find the problem point? It is hard to find what code is making an error. The errors are occured suddenly. I've tried follow all codes line by line, but it works well... it uses several threads and interrupt for communication, so it is more complex..

 

  • Hi Kim,

    It works in single step, this might mean that a delay() or status checking is required somewhere in your code. Please add a breakpoint just before the data communication, then check the value of the EMAC/PHY registers to make sure all the registers are programmed correctly.

    Regards,

    QJ 

  • Hello QJ,

    Thank you for your reply. It is good way inserting some delay or checking code. but I can't guess the problem now, so it is hard.. Is there any trace function in CCS? Can I see the fucntion call trace when it goes entry error. for example, it arrives _c_int00 or dataEntry, can I know last call fucntion or executed code?

    Best Regards.

  • Hi Kim,

    CCS provides a rich debugging environment that allows you to step through your code, set breakpoints, and examine registers as your code executes. Please insert breakpoints at several places to trace down where the code halts. Another way, add statements at several places to send debug message to hyper terminal.

    Do you know how to use the breakpoint in CCS?

    Regards,

    QJ

     

  • Hello QJ.

    I can use breakpoint in CCS and I know it is so useful. But it is hard to find the problem with print debug message and set breakpoints in this situation, so I was wondered that there is another way to debug. I will try to use those ways again.

    Thank you for your reply :)

    Best Regards,

    Wonjae Kim.

  • Hello Wonjae,

      if you are getting an abort, have you tried to look at the linked register (LR) to find out the instruction that caused the abort? 

  • Hello, Charles.

    I have never used it.. Is there any document or wiki related it?

    Best Regards.

  • Hello Wonjae,

    Please go through ARM Cortex-R5 TRM at below link for further information about the LR. The instruction that caused the abort should be LR-8. Also in the CPU, you can find additional information about the cause of the abort in the DFSR (data fault status register) and DFAR (data fault address register). In CCS, if you go to the Registers Window you can find the LR under the Core Registers. For DFSR and DFAR you can find them under the CP15 register.

    http://infocenter.arm.com/help/topic/com.arm.doc.ddi0460c/DDI0460C_cortexr5_trm.pdf

    Synchronous aborts
    A synchronous abort, also known as a precise abort, is one for which the exception is guaranteed
    to be taken on the instruction that generated the aborting memory access. The abort handler can
    use the value in the Link Register (r14_abt) to determine which instruction generated the abort,
    and the value in the Saved Program Status Register (SPSR_abt) to determine the state of the
    processor when the abort occurred.

  • Hello Charles.

    Your answer is what I want.  I will try it. Thank you

    Best Regards.

  • Hello Wonjae,

      I don't know if you have a data abort handler or you simply have a branch to itself at the data abort vector address. Please look at the LR_abt register for the link register in abort mode. Note that there is different LR when CPU is in different mode, i.e. system, user, pabort, dabort, irq, fiq and etc.

  • Hello Charles.

    I want to check some registers.

    1) I don't have any data abort handler or branch and I don't know how do I make it.

    2) I can't understand 'there is different LR'..

    Regards.

  • Hello Wonjae,

      HalcoGen will generate the below default interrupt vector table. Please also see the ARM TRM about the vector table. The vector table is fixed per ARM architecture. For example, if you have a reset condition, the CPU will always jumps to 0x0. If you have data abort the CPU will always jump to 0x10. If you have a IRQ the CPU will always jump to 0x18. As you can see if you have a data abort fault, then the CPU will jump to the dataEntry (at 0x10) where you will be looping here.


    ; interrupt vectors

    resetEntry
            b   _c_int00
    undefEntry
            b   undefEntry
    svcEntry
            b   svcEntry
    prefetchEntry
            b   prefetchEntry
    dataEntry
            b   dataEntry
    reservedEntry
            b   reservedEntry
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

     Normally your application will create an handler to handle the abort condition. See below example:

    ;-------------------------------------------------------------------------------
    ; import reference for interrupt routines
    
        .ref _c_int00
        .ref _dabort
        .ref phantomInterrupt
        .def resetEntry
    
    ;-------------------------------------------------------------------------------
    ; interrupt vectors
    
    resetEntry
            b   _c_int00
    undefEntry
            b   undefEntry
    svcEntry
            b   svcEntry
    prefetchEntry
            b   prefetchEntry
            b   _dabort
            b   phantomInterrupt
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

      Here when you get a data abort fault, the CPU will first jump to 0x10 where it will further branch to the "_dabort" handler. The "_dabort" handler is up to your application what to do and how to handle the abort condition. Here I'm providing an example _dabort handler created by the HalcoGen.

    8311.dabort.asm

      When you get an abort, the CPU will jump to 0x10. During this time, the CPU also saves the returned address in the LR register. Note the R14 register is also known as the LR register. The actual instruction that causes the abort is actually the LR - 8. For example, if you happen to have databort and if the LR(R14) register is showing a value of 0x1008 then the actual instruction that have caused the abort is at address 0x1000.

      The Cortex-R4/R5 has banked registers architecture where in each different type of processor modes it can use the banked registers to give rapid context switching for dealing with processor exceptions. The LR register is banked, meaning that in each one of the processor modes there is an unique LR register. Since you are getting a data abort you would want to look at the LR for the Abort mode but no others such as the LR for FIQ or IRQ. Please see the LR in the below register view in CCS. See under the All Banked Registers there is the R14_FIQ, R14,_SVC, R14_ABT, R14_IRQ and R14_UND. When you get an abort it is the R14_ABT that you want to look at. This R14_ABT also known as the LR will tell you which instruction caused the abort. Note it is the R14_ABT minus 8 that actually caused the abort.

     

     

  • Hello Charles.

    Really thank you for your detailed reply!

    Now I can find the R14_ABT and minus 8, then I can see the address in memory browser, but it is just hex value..

    For example, my R14_ABT is '0x0000_0A78', actual address is '0x0000_0A70'.

    A value of the address is '0xE580_E000' (Little endian).

    I can find a fucntion that include this code. It is very useful.

    Is there a way to get more specific code which is called lastly in memory browser? 

    Best Regards.

     

    +)  I can see some blue text in memory browser '$C$L114'. Please explain its meaning also..

  • Hello Wonjae,

       For abort debugging, you would want to open the disassembly window instead of the memory browser window. The disassembly window will show you the instruction mnemonic instead of just machine code in the memory browser window. I think the instruction that caused the abort will be some type of STR or LDR instruction. Open the disassembly window and enter the 0x0a70 as the address and find out what instruction is there. You can even put a breakpoint at that address and single step the assembly instructions. The CCS should also show you the corresponding line in your C code.

  • Hello Charles.

    Your reply is really clear. Thank you so much!

  • Hello Wonjae,

      As I mentioned before the LR will tell you the address that caused the abort. To find out what is the cause of the abort (i.e. MPU fault, external error , parity/ECC error and etc) you will need to look at the data fault status register and data fault address register. Please see below snapshot of the CP15 registers in the ARM core. Please refer to the ARM TRM for details on these registers. If you have a prefetch abort then you would look at the instruction fault status and instruction fault address registers instead.