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.

CCS/UCD3138: The confirmation ABORT

Part Number: UCD3138

Tool/software: Code Composer Studio

Hello!

I have a question about PSFB software of ucd3138.
The following code was added to standard_interrupt.c in order to intentionally cause an abort process as a confirmation when an error is detected.

*(Uint32*)0x99999999 = 1;



Then, I used the debugger to perform step execution at the assembler level.
The following screen was displayed.

The following figure shows the result of Assembly Step conducted once.

I think that interrupt processing of data abort will occur, but what is happening?

Also, please tell me how to intentionally cause the following three abnormalities:
・Data abort
・Prefetch abort
・Undefined exception

best regards.

  • Then, I used the debugger to perform step execution at the assembler level.
    The following screen was displayed.

    The following figure shows the result of Assembly Step conducted once.

  • I'm not sure what's happening with the JTAG debugger, I haven't tried to single step through an abort.  Often in circuit emulators struggle with things like that.  

    There probably is a data abort happening.  I can try to describe it, but I think it is better to introduce you to the ARM7TDMI Technical Reference Manual here:

    https://static.docs.arm.com/ddi0029/g/DDI0029.pdf

    I suggest you read the first 2 chapters, up through 2.8 - Exceptions.  This will give you the foundation in the processor, give you a correct and detailed description, and introduce to a very useful piece of documentation if you are going to dive into the details of the ARM7 core further.  

    You're already doing a data abort, I suspect.  To do a prefetch abort, just arrange to jump to an illegal address.

    For an illegal instruction abort, I found a web page that claims to have an illegal instruction code.  Use the code and the web page at your own risk.  It does look safe to me, but no guarantees:

    https://stackoverflow.com/questions/11851976/arm7-tdmi-undefined-instruction-exception-manual-generation

    On our compiler, all you need to do to insert the instruction code is to put this in your C code wherever you want it:

    asm("  .long 0x26889912;") // bad opcode from third party website

    Note that the space after the first " is important to the assembler.  

    In general, you will find that if you google your questions with ARM7TDMI, you will often find an answer.  Billions and billions of ARM7 cores have been sold in lots of places, so there is lots of information out there.  You can most likely get a quicker answer that way.  

  • Thank you for your reply.

    It's a bit different from the answer I'm asking for, so I'd like to give you some additional background information.


    The intention of this question is
    It is to confirm that the process at the time of occurrence was added to the function of the abort handler.
    Currently, the processing at the time of occurrence is tentatively as follows.

    interrupt.c

     

    #pragma INTERRUPT(abort_data_fetch_exception,DABT)

    void abort_data_fetch_exception(void)

    {

       XXX = 1; // Substitution process for variables

       for( ; ; );

    }

     

     

    void abort_prefetch_exception(void)

    void undefined_instruction_exception(void)

    Same processing for the above two.

     



    In this state, set a breakpoint at "XXX = 1;",
    When "* (Uint32 *) 0x99999999 = 1;" was executed, it did not stop at "XXX = 1;".

    For this reason, when I ran a breakpoint at the location of "* (Uint32 *) 0x99999999 = 1;" and performed step execution, the state of the first question was reached.

    What I would like to ask in this question is why, if there is a data abort, why not jump to "void abort_data_fetch_exception (void)".
    Also, if you are having trouble confirming the execution of an abort using the JTAG debugger,
    How can I check if "void abort_data_fetch_exception (void)" in interrupt.c was called?
    best regards.

     

     

     

  • In these cases, I always prefer to put in code to toggle an I/O line to tell me it got there.  Using I/Os is often very useful, especially with power supplies, for example for measuring firmware timing, including how long something takes to execute, or when the firmware processes a fault.  You can use the I/O line along with the analog signals on the scope.  

    In this case, probably the JTAG is getting confused by the abort exception.  So toggling an I/O line if it gets to the abort handler is an alternative.  

  • Thank you for your reply.

    Based on Ian's advice, I investigated with the evaluation board (UCD3138PSFBEVM-027) whether the abort handler is called using the I/O line (AC_FAIL_IN).

    The source code of the I/O line actually used is shown below.

    MiscAnalogRegs.GLBIOVAL.all | = MASK_AC_FAIL_IN;

    GPIO port output set
    Executed in standard_interrupt.c and confirmed that it turned on with an oscilloscope.


    I wrote this code in the handler shown below.(@interrupt.c)
    ・ Void undefined_instruction_exception (void)
    {
        MiscAnalogRegs.GLBIOVAL.all | = MASK_AC_FAIL_IN;
    }
    ・ Void abort_prefetch_exception (void)
    {
       MiscAnalogRegs.GLBIOVAL.all | = MASK_AC_FAIL_IN;
    }
    ・ Void abort_data_fetch_exception (void)
    {
       MiscAnalogRegs.GLBIOVAL.all | = MASK_AC_FAIL_IN;
    }


    When the abnormal operation "asm (" .long 0x26889912; ");" was executed in standard_interrupt.c, it was confirmed by the I/O line (AC_FAIL_IN) whether it was called by the abort handler.


    As a result, the output of the I/O line did not turn on even if an abnormal operation was performed.
    We also confirmed that the PWM signal stops during abnormal operation. (See the figure below)
     


    Even if the following source code that causes a data abort is executed, the result is that only the PWM is stopped while the I/O port remains OFF.
    (Same result as ” asm( ".long 0x26889912;");)
    * (Uint32 *) 0x99999999 = 1;
    Since the I / O port was not turned on, I think that the interrupt handler of interrupt.c will not be executed even if a prefetch abort or a data abort occurs.

    Is there a relationship between the PWM stopping and the abort handler not running?
    best regards.
  • The abort exceptions also have their own stack area and stack pointers.  You need to initialize them as well.  Some of our EVMs do not, because we are happy to just reset.  If the stack pointers are not initialized, they will most likely point to an illegal address.  This causes a second abort, which seems to reset the part.  

    You need to go to load.asm, and add these lines to the program:

    ;*------------------------------------------------------
    ;* SET TO IRQ MODE, init IRQ stack
    ;*------------------------------------------------------
    MRS r0, cpsr
    BIC r0, r0, #0x1F ; CLEAR MODES
    ORR r0, r0, #0x12 ; SET IRQ MODE
    MSR cpsr_cf, r0

    LDR R13, c_irq_stack_top ; initialize stack pointer
    ;*------------------------------------------------------
    ;* SET TO ABORT MODE, init ABORT stack
    ;*------------------------------------------------------
    MRS r0, cpsr
    BIC r0, r0, #0x1F ; CLEAR MODES
    ORR r0, r0, #0x17 ; SET ABORT MODE
    MSR cpsr_cf, r0

    LDR R13, c_abt_stack_top ; initialize stack pointer
    ;*------------------------------------------------------
    ;* SET TO UNDEFINED MODE, init UNDEFINED stack
    ;*------------------------------------------------------
    MRS r0, cpsr
    BIC r0, r0, #0x1F ; CLEAR MODES
    ORR r0, r0, #0x1B ; SET UNDEFINED MODE
    MSR cpsr_cf, r0

    LDR R13, c_und_stack_top ; initialize stack pointer
    ;*------------------------------------------------------
    ;* SET TO USER MODE, init user stack
    ;*------------------------------------------------------

    You will also need to add the stack addresses to the .equ statement in the front of load.asm.  These are for the UCD3138128 addresses, you will have to change the addresses to match the other stack addresses in other devices:

    SUP_STACK_TOP .equ 0x69ffc ;Supervisor mode (SWI stack) starts at top of memory
    FIQ_STACK_TOP .equ 0x69e00 ;allocate 256 bytes to supervisor stack, then do FIQ stack
    IRQ_STACK_TOP .equ 0x69d00 ;allocate 256 bytes to fiq stack, then start irq stack
    ABT_STACK_TOP .equ 0x69b50 ;Allocate 432 bytes to irq stack
    UND_STACK_TOP .equ 0x69b50 ;allocate 80 bytes to abt stack
    USER_STACK_TOP .equ 0x69b00 ;allocate 80 bytes to und stack, regular stack gets rest, down to variables

    Finally, you will have to add the actual putting of the constants into program flash at the bottom of load.asm:

    c_sup_stack_top .long SUP_STACK_TOP
    c_abt_stack_top .long ABT_STACK_TOP
    c_und_stack_top .long UND_STACK_TOP
    c_user_stack_top .long USER_STACK_TOP

  • Thank you for your reply.

    I added the description in the reply to the code of UCD3138_load.asm and confirmed the operation.
    RESULT
    When executing “asm (" .long 0x26889912; ");”, it was confirmed from the waveform below that an undefined exception occurred.

    However, with "* (Uint32 *) 0x99999999 = 1;" that should enter the data abort, the result is that only the PWM stops, while the I / O port remains the same as before. (Same result as May 4, 2020 2:13 AM question's figure )


    From this, it is possible that the UCD3138_load.asm setting for data abort may not have been completed correctly.
    Currently, the added UCD3138_load.asm is described below. Is there a problem with the settings?
    【UCD3138_load.asm】


    An excerpt of the map file is also described below. (For setting the TOP address of the stack)
    【UCD3138_PSFB_PCM.map】

    Best regards.
  • It really seems like if you've gotten one working, the other one should work too.  Just to check, did you put the I/O line toggle in the exception handler for the data abort as well?  

  • Yes, the waveform remained off even if I / O line ON signal was set to the abort data handler (void abort_data_fetch_exception (void)).

     

     

     

    The following code was executed in "standard_interrupt.c" to confirm that the abort handler was called.

                     void (* func) () = 0x10000000;

                     (* func) ();

     

    In the abort handler, the processing to turn on AC_FAIL_IN of I / O line is entered.

    void abort_prefetch_exception (void) {

    MiscAnalogRegs.GLBIOVAL.all | = MASK_AC_FAIL_IN;

    }

    void abort_data_fetch_exception (void) {

    MiscAnalogRegs.GLBIOVAL.all | = MASK_AC_FAIL_IN;

    }

     

    As a result, I / O port remains OFF, but only PWM stops.


    Therefore, using the JTAG debugger, we confirmed the changes in the following registers before and after abnormal processing.

    System Exception Control Register (SYSECR)

    System Exception Status Register (SYSESR)

    Abort Exception Status Register (ABRTESR)

     

     

    As a result, the registers have the following values ​​after the abnormal processing occurs.


     

     

    The table below shows a summary of the changes.

    Variable name

    Before error processing

    After error processing

    SYSECR.bit.RESET

    01

    00

    SYSESR.bit.ILLADR

    0

    1

    ABRTESR.bit.ADRABT

    0

    1

     

     

    Since the above ABRTESR.bit.ADRABT is 1, I think that an illegal address abort has occurred.

     

     

    However, I don't understand why the handler (void abort_prefetch_exception (void) or void abort_data_fetch_exception (void)) is not called even though the abort occurred. Is any necessary operation missing?

     

    Also, please tell me how the PWM signal stops when an abort occurs.

    I believe that the PWM output will continue to be output even if an abort occurs.

     

     

    Addendum

     

    When the error handling currently performed in standard_interrupt.c is performed in main.c, the I / O line signal turns ON.

      

     

     

    Is there a way to execute the abort handler

    (void abort_prefetch_exception (void)

    or void abort_data_fetch_exception (void))

    in standard_interrupt.c (IRQ) or interrupt.c (FIQ)?

    bet regards.

  • This one is going to take some research on my part.  I haven't tried executing the code in the standard interrupt before. The reason the PWM is getting turned off is that the processor is getting reset.  The bit in SYSESR shows that the abort is occurring.  Normally the reset is caused by an additional fault occurring on the way to the abort interrupt.  I'm going to need a little time to look into this one and see if I can duplicate your results.  and maybe talk to the designers.  

    Are there other things going on in standard interrupt.c that could have any bearing on this?  Do you have the watchdog enabled?

  • Thank you for your reply.

    I don't do anything like standard_interrupt.c to reset the processor.

    These source codes don't have watchdog enabled.


    We are looking forward to the survey results.
    ・ Method to execute abort handler (void abort_prefetch_exception (void) or void abort_data_fetch_exception (void)) in standard_interrupt.c (IRQ) or interrupt.c (FIQ)
    ・ How the PWM signal stops when an abort occurs
    Best regards.
  • The PWM signal stops because the device is being reset by the abort somehow.  

    I can't think of any reason why the abort shouln't work in the standard interrupt as well as in main.c.  

    Have you tried it with the JTAG disconnected?  If you have a breakpoint set somewhere, that could interfere with the normal function of the abort, for example.  

    And it is really with a UCD3138 that you are trying this, right?  If I have to test it, I want to do it on the correct device.  

  • Yes, all the questions so far are investigated using the PSFB evaluation board (UCD3138PSFBEVM-027) of UCD3138.


    The reason why the PWM signal turns off when an additional abort occurs.
    If the processor resets when an additional abort occurs, it will start from address 0 and the PWM signal is expected to recover, but it will remain stopped (Figure 1). (@ JTAG Debugger disconnected)


    conditions:
    AC_FAIL_IN I / O Line toggle set in abort_prefetch_exception ()
    prefetch abort execution @standard_interrupt () (IRQ)

    When simulating the abort, the result was the same as in Fig. 1 regardless of whether IRQ or FIQ was executed.

    From this, I think that when an additional abort occurs and the processor resets, the peripherals inside the UCD3138 (such as the module that generates the PWM) are also reset. Isn't it?
    Best regards.
  • Well, I've managed to duplicate your results, but I had to write to the SYSECR register to get an exact duplication.  

    When I put the function call to an illegal address in background, it went to the abort.

    When I put the function call to an illegal address in the standard interrupt, it reset the device and turned the DPWM off, and then either stayed in ROM mode or restarted, as I expected.  With the checksum in place and it going into ROM mode, I could tell because the DPWM stopped for 10 milliseconds.  This is because the ROM takes 10 msec to calculate the checksum.  It's easy to miss this unless you are looking for it.  I put out a signal on an I/O pin just before doing the illegal function call and triggered on that.

    However, if I set the PACCOVR, ACCOVR, and ILLOVR bits in the SYSECR, I get the DPWM staying on and the program getting lost.  Somehow it isn't going to the ABORT, and it isn't getting reset either.  

    That's what I see.  Can you tell me what you are trying to accomplish with the ABORT.  if you want a reset, I think that you are getting that, as long as you don't set those bits.  Unless you have a code that can cause the issue without setting those bits.  If you have a code which does that, perhaps you can reduce it to the minimum, remove any proprietary elements and send it to me, and I can see if I can duplicate it.  

    I'm pretty sure that what we both see is what will happen with the device, so if you can tell me what you are trying to accomplish, I can try to help you with that.  After all, the device is its own best documentation.  

  • Thank you for your research.

     

    What I want to do when an ABORT occurs is to output a signal from the I / O line to the outside of ucd3138 and keep the program inside the abort handler.

    After that, I want to reset from outside instead of ucd3138.

     

    There were some differences between Ian's research results and my event, so I asked the reply to ask questions in red.

     

    It is shown below.

     

    (20200515 Mr. Ian’s Reply)

    When I put the function call to an illegal address in the standard interrupt, it reset the device and turned the DPWM off, and then either stayed in ROM mode or restarted, as I expected. With the checksum in place and it going into ROM mode, I could tell because the DPWM stopped for 10 milliseconds. This is because the ROM takes 10 msec to calculate the checksum. It's easy to miss this unless you are looking for it. I put out a signal on an I/O pin just before doing the illegal function call and triggered on that.

    Q1. I think that the abort handler is not called during this research. Is there any recognition?

     

    Q2. Ian says that in the research of abnormal operation without setting SYSECR, PWM will be in either restart mode or ROM mode after being stopped for 10ms. What happens to each?

    Q2_1 When restarting

    I think that the PWM will turn on and off again, is this correct?

    Q2_2 ROM mode

    I think that PWM does not repeat ON / OFF after stopping for 10ms. Is it correct?

    I don't have much understanding about ROM mode, so please tell me the materials.

     

    However, if I set the PACCOVR, ACCOVR, and ILLOVR bits in the SYSECR, I get the DPWM staying on and the program getting lost. Somehow it isn't going to the ABORT, and it isn't getting reset either.

        Q3. Does the DPWM stay on (staying on…) mean that it remains ON (High level)? Or does it mean that the ON / OFF control is continued?

     

     

     

    Also, I confirmed from the JTAG debugger that each OVR register of SYSECR is not set (remaining 0) in both the back ground loop (main.c) and IRQ (standard_interrupy.c).

     

     

     

    Best Regards.

  • The abort handler doesn't seem to be called when the function call to the illegal address occurs

    In ROM mode, it sets the address to 11 or 0xB, and waits for the ROM commands for memory examine and modify memory, download, and execute PFLASH program.  This is the mode in which we download, where the boot ROM is in control.

    If the checksum is valid, it goes back to the flash program that you have downloaded.  So when restarting, the PWM should turn off and on again repeatedly.

    In my case, that would probably cause the device to lock up, and not be able to clear the checksum.  So I set it up to require an additonal PMBus command to trigger the illegal memory call.  If you have the checksum locked, and the code hard coded to call the illegal address, I'd expect it to start the DPWM and stop it over and over again.  

    When I set the OVR bits, the DPWM stays on continuously, and the PMBus doesn't respond to either the program flash messages or the ROM messages, so probably the program is lost somewhere.  As I say, I see this only if I set the OVR bits.  It's entirely possible that you see it differently, it probably has to do with a difference with your program and mine.  

    The abort logic is helpful with program debugging, catching bugs in program execution, and catching when the processor gets lost due to disturbance, like power supply noise.  It's never been perfect.  It doesn't seem like you will be able to catch as many cases as we thought.  If you want more security, I'd suggest using the watchdog as well.  And, of course, write your code without any illegal calls in the interrupts.  

  •  

    Thank you for your reply.

     

    The waveforms so far have been implemented with the checksum enabled. (See Figure 1 below)

     

     

    conditions:

    AC_FAIL_IN I / O Line toggle set in abort_prefetch_exception ()

    Prefetch abort execution @standard_interrupt () (IRQ)

    result:

    DPWM stops due to abnormal operation. (The abort handler is not called.)

     

    When the ENABLE signal (ON / OFF switch on the evaluation board) was turned OFF / ON in this state, the PWM was turned OFF / ON again. (See Figure 2 below)

     

     

    From this, I think that it is restarting from address 0 due to illegal processing.

    One concern is that the Enable signal is not recognized even though it is in the ON state.

    I would like to know the specifications of the Enable signal. (Level detection? Edge detection?)

     

    Best regads.

  • Looking at that, it suggest that while the background program is getting lost, the standard interrupt is still running, since an enable/disable generally makes the system go to idle mode and back to restarting.   The best way to protect against that is to have the watchdog running and have only the background loop keeping the watchdog from resetting the processor.  That way if the background loop gets lost, the processor will be reset by the watchdog.  

    To see if this is happening, I'd suggest having the standard interrupt toggling an I/O line everytime it is entered, and see if this line keeps toggling.  

  • This one has been going on for quite a while, and it's been several days since I responded to your latest post, so I'm going to try to close this post.