• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » Hercules™ Safety Microcontrollers » Hercules™ Safety Microcontrollers Forum » Interrupt exception vector handling with bootlaoder
Share
Hercules™ Safety Microcontrollers
  • Forum
  • E2E Wiki
Options
  • Subscribe via RSS

Interrupt exception vector handling with bootlaoder

Interrupt exception vector handling with bootlaoder

This question is answered
Joachim
Posted by Joachim
on Aug 07 2012 04:58 AM
Prodigy110 points

Hello,

In my current project i need to implement a bootloader for firmware update purpose. The bootlaoder is at the beginning of the flash and gets invoked after a power up or reset. If a update is necessary the bootloader updates the application otherwise starts the application at address 0x8000 (32kByte). So far the application is called by the bootloader as expected but behaves different than if programmed without bootloader at address 0x00.

The application has a couple of safety init features enabled like the ESRAM ECC Check (SAFETY INIT tab in HALCoGen) which provokes a data abort interrupt. This resolves to two issues, first the interrupt jumps to the execption vector located at address 0x00 instead of address 0x8000. This I can explain with Anthony F. Seely 's statement in this post http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/124544.aspx. I have to dispatch manually to the applications exception vector. Secondly it's not the data abort interrupt (at address 0x10) which is called but the prefetch abort (at address 0x0C).

Is there anywhere an example how to deal with this matter. Even as the bootloader example http://processors.wiki.ti.com/index.php/RM48_HDK_Kit doesn't show a solution to this an won't work for applications using exception vectors or FIQs.

Thanks in advance

Joachim

Report Abuse
  • Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
All Replies
  • Zhaohong Zhang
    Posted by Zhaohong Zhang
    on Aug 07 2012 09:49 AM
    Genius9265 points

    Joachim,

    Actually, I had many discussion about this interesting topic recently.  The following discussion is based on the assumptions (1) bootloader and application are independent entities such that changes in application will not affect bootloader and vice versa, and (2) bootloader only needs to handle reset and IRQ/FIQ.

    There are two types of interrupts on TMS570. The first types are exceptions such as reset, SWI, data and prefetch abort, etc. The second type is IRQs and FIQs.

    For IRQs  and FIQs, CPU directly fetches the ISR address from VIM module. If the hardware vector mode is enabled, CPU will not even jump to the exception vector at 0x00000018 or 0x0000001c. You can configure VIM module and RAM independently for the bootloader and application. The hardware vector mode can be enabled by the discussion in the following thread.

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/183311.aspx

    Since the exception vector table is not relocatable, Every time a reset or an abort happens, CPU will jump to the vectors starting at address 0x0. Assume that your bootloader occupies addresses from 0x0 to 0x7fff, and application starts at 0x8000. you can set up the bootloader vector table at 0x0 as follows,

        b _c_int00 ; entry point to bootloader

        b 0x8004   ; jump to application vector for processing

        b 0x8008   ; jump to application vector for processing

        b 0x800c   ; jump to application vector for processing

        b 0x8010  ; jump to application vector for processing

        b 0x8014  ; jump to application vector for processing

    In your application project, you need to put the vector table at address 0x8000. In this set up, when an exception occurs, CPU will first jump to the bootlaoder exception vector starting at address 0x0 and then jump to the application exception vector starting at address 0x8000. After a reset, CPU will always enter boot loader first. In the bootloader, you need to use intruction "b 0x8000" to jump to application. If you want to debug your application without bootloader, you can change the vector address in the application link command file from 0x8000 to 0x0.Or you cna change the first instruction in the bootloader vector from "b _cint00' to "b 0x8000".

    The limitation of this idea is that you cannot enable ECC for the bootloader because abort handling is not allowed for bootloader.

    Please let me know if this idea works for you. Please notify us if you can think of something better out of this discussion. 

    Thanks and regards,

    Zhaohong

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Joachim
    Posted by Joachim
    on Aug 09 2012 09:02 AM
    Prodigy110 points

    Zhaohong,

    Thanks for your informative answer. Unfortunately it doesn't solve the problem.

    The hardware vector mode is enabled already by HALCoGen with the tick "Enable IRQ Handling via VIC Controller" which produces exactly the assembler code you provided.

    The ESRAM ECC Check should trigger a data abort exception. What it does actually is generating a prefetch abort exception. Thats all I see with the debugger. After the instruction "ramread = tcramA2bit;" generated by HALCoGen (sys_selftest.c, in function checkB0RAMECC()) the PC jumps to 0x0C (prefetch abort) and sticks to there. Not even the jump to 0x800C is executed.

    Any idea why the appliaction triggers a different exception interrupt and why the PC sticks to that address?

    Thanks and regards,

    Joachim

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Zhaohong Zhang
    Posted by Zhaohong Zhang
    on Aug 09 2012 09:44 AM
    Verified Answer
    Verified by Joachim
    Genius9265 points

    Joachim,

    I forgot one thing in my earlier email. Although you do not enable Flash ECC for the bootloader, you need to calculate and ECC for the boot loader S/W. When you purposely generate a data abort in your application by a data read, CPU will generate a data abort and jump to address 0x10. If the ECC is not programmed for address 0x10, a prefetch abort will occur and CPU jumps to address 0xC. If ECC for address 0x C is not programmed, CPU will be locked into prefetch abort and you will see CPU locks to address 0xC. You can put breakpoints at address 0xC and 0x10. You should see CPU first stop at 0x10 and then locks to 0xC.

    Thanks and regards,

    Zhaohong

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Joachim
    Posted by Joachim
    on Aug 10 2012 07:49 AM
    Prodigy110 points

    Zhaohong,

    Thank you, this helped quite a lot to the situation. I won't get any prefetch aborts anymore.

    But first, somehow the assembler instruction for the  jump from exception vector of the bootloader to the one of the app is weird. For the data abort I have to write

    b    #0x7FF8

    instead of the expected

    b    #0x8010

    Do you have any idea why?

    Second, now I get  a step further in the app but get a undefined exception somewhere later. In the application code i just changed the command file telling the linker to start placing the code from address 0x8000. Do I have to make other modifications, or should this be enough?

    Thanks a lot and have a nice weekend

    Joachim

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Zhaohong Zhang
    Posted by Zhaohong Zhang
    on Aug 10 2012 09:15 AM
    Suggested Answer
    Genius9265 points

    Joachim,

    "b #0x77f8" is branch to an offset of 0x8000 from the current location. Branching back to current location is " b #-8". For branching to address 0x8000, you should use "b 0x8000".

    CPU always starts at 0x0. If you want to focusing on debugging the application, I would suggest you reserving the space from 0x800 to 0x820 and put the exception vector to 0x0. You can put it back to 0x8000 after everything in the application is working and start integrating with bootloader.

    Thanks and regards,

    Zhaohong

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Joachim
    Posted by Joachim
    on Aug 14 2012 04:36 AM
    Prodigy110 points

    Zhaohong,

    "b 0x8000" doesn't work with the assembler: [E0004]  Illegal operand

    Everything (Application and Bootloader) works fine with the app's exception vector at 0x00 (what you proposed to do). Something with the jump from 0x00 to 0x8000 seems to crash the system. Any idea?

    Best regards,

    Joachim

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Christian Herget
    Posted by Christian Herget
    on Aug 14 2012 09:40 AM
    Verified Answer
    Verified by Joachim
    Intellectual1470 points

    Joachim,

    Branches in ARM-v7R are relative.

    You can find this information in the ARM Assembler Reference: http://infocenter.arm.com/help/topic/com.arm.doc.dui0489e/Cihfddaf.html#id4685232


    What you also need to know for using the Branch instruction is the following:

    In ARM state, the value of the PC is the address of the current instruction plus 8 bytes.

    This can be found in the ARM Using the Assembler document: http://infocenter.arm.com/help/topic/com.arm.doc.dui0473e/Cacdbfji.html

    Which means if you want to do a branch from address 0x0 to 0x8000 you need an branch instruction with the offset 0x7FF8 (0x8000 - 0x0 - 0x8 ; Destination - Source (PC) - 0x8)

    One more thing I forget to add: In the TI assembler each immediate value has to start with #

    Best Regards,

    Christian

    ~~~ If a post answers your question, please mark it with the Verify Answer button. ~~~

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Zhaohong Zhang
    Posted by Zhaohong Zhang
    on Aug 14 2012 12:37 PM
    Genius9265 points

    Joachim,

    Do you use "b #0x7ff8" at address 0x0 to jump to address 0x8000? Can you put "b #-8" at address 0x8000 to check if branch occurs correctly? After a power-on-reset, CPU will starts at address 0x0. When you connect debugger to CPU, you should see PC at 0x8000. To branch to 0x8000 from the bootloader, you can call an assembly function from c-code. The assembly function can be constructed as follows assuming that you use eabi compiling option.

        .global branch2address
    .text
    branch2address:    
       b r0     ;no need to to save any register because CPU branches to a new application
       bx lr
    .end

    Calling in C:

    extern void branch2address(unsigned int address);

    branch2address(0x8000);

    Thanks and regards,

    Zhaohong

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Joachim
    Posted by Joachim
    on Aug 16 2012 03:54 AM
    Prodigy110 points

    Zhaohong,

    Ok, I found the solution. My exception table in the bootloader looks now like this:

        b   _c_int00    ;0x00
        b     #0x7FF8     ;0x04, undefined instruction
        b    #0x7FF8     ;0x08, Software interrupt
        b    #0x7FF8     ;0x0C, Abort (prefetch)
        b    #0x7FF8     ;0x10, Abort (data)
        b   #0x7FF8     ;0x14
        ldr pc,[pc,#-0x1b0]    ;0x18 IRQ
        ldr pc,[pc,#-0x1b0] ;0x1C FIQ

    The last two entries were missing (IRQ and FIQ). The ADC interrupts are configured in FIQ mode and if triggered jump to 0x1C. So long so good, but why is this? You said that the IRQs and FIQs are reallocated to VIM by hardware, this seems not to be the case for FIQ. Furthemore what does instruction "ldr pc,[pc,#-0x1b0]" and why is a simple "b   #0x7FF8" not working here?

    Hopefully you can bring some light into the dark.

    Thanks and regards,

    Joachim

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Christian Herget
    Posted by Christian Herget
    on Aug 16 2012 06:01 AM
    Verified Answer
    Verified by Joachim
    Intellectual1470 points

    Joachim,

    we have three different possibilities to react on interrupts:

    1. Legacy ARM7 Mode: In this mode the software designer has to write a software dispatcher for the FIQ and IRQ.
    2. Vectored interrupt: In this mode the VIM module dose the dispatching for IRQ and FIQ and has an register which shows the address of the pending interrupts routine. The CPU has to load the vector address to the PC via a LDR instruction.
    3. Hardware Vectored Interrupt: This mode is only available for IRQ. In this mode the VIM dose the dispatching and supplies the vector address to the Cortex-R4F CPU via the VIC Port. This mode is similar to #2 but it saves the load instruction on address 0x18 and thus a few cycles.

    The default setup in HALCoGen is to use #3 for IRQ and #2 for FIQ.

    The "LDR PC, [PC, #-0x1B0]" instruction is necessary for #2. In this mode the CPU has to load the vector address from the VIM register IRQVECREG for IRQ's and FIQVECREG for FIQ's.

    IRQVECREG is at 0xFFFF_FE70

    FIQVECREG is at 0xFFFF_FE74

    The coding for the LDR instruction is similar as for the branches I described in my post before.

    "LDR PC, [PC, #-0x1B0]" at address 0x18 resolves to a load from address 0xFFFF_FE70. (-0x1B0 == 0xFFFF_FE50 --> 0xFFFF_FE50 + 0x18 + 0x8 = 0xFFFF_FE70)

    So you do not need to forward IRQ and FIQ exception vectors to 0x8018 and 0x801C, as you don't need to write a software dispatcher for these if you use #2 or #3.

    Best Regards,

    Christian

    ~~~ If a post answers your question, please mark it with the Verify Answer button. ~~~

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Joachim
    Posted by Joachim
    on Aug 16 2012 06:29 AM
    Prodigy110 points

    Christian,

    Thanks for the satisfying explanation, it helps a lot.

    There is no possibility to use #3 for FIQ, is that right?

    Regards,

    Joachim

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Christian Herget
    Posted by Christian Herget
    on Aug 16 2012 06:35 AM
    Verified Answer
    Verified by Joachim
    Intellectual1470 points

    Joachim,

    Yes, this VIC Port is only available for IRQ and not for FIQ.
    The following is from the ARM Cortex-R4 TRM:


    Best Regards,
    Christian

    ~~~ If a post answers your question, please mark it with the Verify Answer button. ~~~

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
TI E2E™ Community
  • Support Forums
  • Blogs
  • Videos
  • Groups
  • Site Support & Feedback
  • Settings
TI E2E™ Community Groups
  • TI University Program
  • Make the Switch
  • Microcontroller Projects
  • Motor Drive & Control
Other Communities
  • Deyisupport
  • Designsomething.org
  • beagleboard.org
  • TI on Element 14
  • TI on TechXchangeSM
Other Technical & Support Resources
  • WEBENCH® Design Center
  • Product Information Centers
  • Technical Documents
  • TI Design Network
  • TI Technical Articles
  • TI Training

All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
embedded processors, along with software, tools and the industry’s largest sales/support staff.

© Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy Policy | Terms of Use