Difference between Software/Hardware vector mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Difference between Software/Hardware vector mode

Jump to solution
3,605 Views
jean-christoph7
Contributor III

Hello,

I'm working on a MPC5604B µC and I've some difficulties to do the difference between software vector mode and hardware vector mode.

Where can I find simple explanations about the difference between the both interrupt vector modes ?

Thanks.

1 Solution
2,044 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

Yes, you understand correct. But there also other differences.

In software vector mode, address of the common handler is composed of IVPR + IVOR4. Common handler must identify the interrupt source by reading INTC_IACKR register. This register consist of Vector Table Base Address and Interrupt Vector address. These two addresses are concatenated to select the desire ISR (interrupt service routine) entry in the vector table.

In hardware vector mode INTC_IACKER does not need to be read. Address of the interrupt service routine is composed of IVPR and interrupt vector source number.

The advantage of the software vector mode is that all interrupts can share common prolog and epilog. This can reduce code size when a large number registers need to be saved.

The advantage of the hardware vector mode is that it reduces interrupt latency because of address composing and also prologs and epilogs can have different length (can be shorter) for every ISR.

Regards,

Martin

View solution in original post

0 Kudos
10 Replies
2,044 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

look at this application note:

http://cache.nxp.com/files/32bit/doc/app_note/AN2865.pdf?fsrch=1&sr=6&pageNum=1

Chapters 4, 5, 6 and 7 describe how the interrupt modes work.

You can also look at Bolero reference manual chapter 16.4.1.1 and 16.4.1.2:

http://cache.nxp.com/files/32bit/doc/ref_manual/MPC5604BCRM.pdf?fsrch=1&sr=5&pageNum=1

If you have any other questions please feel free to write me back.

Regards,

Martin

0 Kudos
2,044 Views
jean-christoph7
Contributor III

Thanks for your answer.

tell me if I understand: correctly:

In software mode, we handle all ISR save/restore context with the same mechannism  then in hardware mode, we can handle every ISR save/restore context with a specify mechanism.

Is there other difference?

0 Kudos
2,045 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

Yes, you understand correct. But there also other differences.

In software vector mode, address of the common handler is composed of IVPR + IVOR4. Common handler must identify the interrupt source by reading INTC_IACKR register. This register consist of Vector Table Base Address and Interrupt Vector address. These two addresses are concatenated to select the desire ISR (interrupt service routine) entry in the vector table.

In hardware vector mode INTC_IACKER does not need to be read. Address of the interrupt service routine is composed of IVPR and interrupt vector source number.

The advantage of the software vector mode is that all interrupts can share common prolog and epilog. This can reduce code size when a large number registers need to be saved.

The advantage of the hardware vector mode is that it reduces interrupt latency because of address composing and also prologs and epilogs can have different length (can be shorter) for every ISR.

Regards,

Martin

0 Kudos
2,044 Views
jean-christoph7
Contributor III

Thanks a lot.

Does a SW vector table exist for MPC5604B?

0 Kudos
2,044 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

if you use CodeWarrior, you do not have to deal with SW vector table. All is prepared for your work. If you do not use CodeWarrior, please look at the application  note mentioned above, chapter 4.3.3 or 6.3.3 according to use BookE or VLE instruction set.

Regards,

Martin

0 Kudos
2,044 Views
jean-christoph7
Contributor III

Hello,

I used  chapter 4.3.3 to create my interupt vector table with Codewarrior, but in this example, there is not the "Internal FLASH linker command file"  (MPC56xx_FLASH.lcf) to define the memory area to store the table.

Do you have a file *.lcf exemple  to define an interrupt vector table in ROM (not in RAM).

Thanks.

0 Kudos
2,044 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

look at the attached example. This example was created for TRK-MPC5604B. There are some points which has to be configured:

1)    In linker file is created section flash_handler which has to be aligned to 2KB and LOAD directive __flash_handler. Internal flash section  is moved to 5000.

2)    In file vector_MPC5606BK.c is changed pragma section.

3)    In the end of file IntcInterrupts.c is INTCInterruptsHandlerTable replaced by vectorTableIsr.

4)    In main function is set interrupt priority and base priority is set to 0.

If you have another question, feel free to write me back.

Regards,

Martin

0 Kudos
2,044 Views
jean-christoph7
Contributor III

Hello,

I tried to implement my interrupt table in flash with several ways, but it doesn't work

I tried 4 solutions and just one is working but  I am not satisfied of this solution.

1/ In the exemple1 , I create  my section before the internal_flash section. I've not error or warning during the compilation, but when I load the code on my board, I go directly in illegal interrupt.

MPC5604B_FLASH.lcf

    exception_handlers:    org = 0x00001000,   len = 0x00002000

  

    flash_isr_handler:          org = 0x00003000,   len = 0x00002000

    internal_flash:        org = 0x00005000,   len = 0x00070000

  

    .....

    .ivor_branch_table (VLECODE) LOAD(ADDR(exception_handlers)) ALIGN (0x10) : {}

  

    .intc_hw_branch_table (VLECODE) LOAD(_e_ivor_branch_table) ALIGN(0x800) : {}

    .__exception_handlers  (VLECODE) LOAD(_e_intc_hw_branch_table) : {}

    } > exception_handlers

    .flash_isr_handler LOAD (0x00003000): {} > flash_isr_handler

  

INTS_SwInterrupt.code

    #pragma push /* Save the current state */

    #pragma section const_type ".__flash_isr_handler" ".__flash_isr_handler"

  

    const INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR] =

    {

    }

  

INTS_Interrupt.h

extern const INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR];

2/ In the exemple2,  I've not error or warning during the compilation, but when I load the code on my board, I go directly in illegal interrupt.

MPC5604B_FLASH.lcf

    exception_handlers:    org = 0x00001000,   len = 0x00002000

  

    flash_isr_handler:          org = 0x00003000,   len = 0x00002000

    internal_flash:        org = 0x00005000,   len = 0x00070000

  

    .....

    .ivor_branch_table (VLECODE) LOAD(ADDR(exception_handlers)) ALIGN (0x10) : {}

  

    .intc_hw_branch_table (VLECODE) LOAD(_e_ivor_branch_table) ALIGN(0x800) : {}

  

    .__exception_handlers  (VLECODE) LOAD(_e_intc_hw_branch_table) : {}

    } > exception_handlers

    GROUP : {

       .__flash_isr_handler ALIGN(2048) : {}

    } > flash_isr_handler

  

  

INTS_SwInterrupt.c

    #pragma push /* Save the current state */

    #pragma section const_type ".__flash_isr_handler" ".__flash_isr_handler"

  

    const INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR] =

    {

    }

  

INTS_Interrupt.h

#pragma push

#pragma section const_type ".__flash_isr_handler"

extern const __declspec(section ".__flash_isr_handler") INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR];

#pragma pop

3/ In the exemple3, I shift my section after the internal_flash section before the end of the flash, but when I go in debug mode, nothing happen (no message).

MPC5604B_FLASH.lcf

    exception_handlers:    org = 0x00001000,   len = 0x00002000

  

    internal_flash:        org = 0x00003000,   len = 0x00070000

  

    flash_isr_handler:          org = 0x00073000,   len = 0x00002000

  

    .....

    GROUP : {

      .text : {}

      .text_vle (VLECODE) ALIGN(0x08): {

         *(.text)

         *(.text_vle)

       }

       .rodata (CONST) : {

         *(.rdata)

         *(.rodata)

       }

              /* The INTC module for this device contains 217 IRQs.*/

      /* .__initialized_flash_isr_handle   ALIGN(2048) : {}

       .__uninitialized_flash_isr_handle ALIGN(2048) : {}*/

       .ctors : {}

       .dtors : {}

       extab : {}

       extabindex : {}

    } > internal_flash

    GROUP : {

       .__flash_isr_handler ALIGN(2048) : {}

    } > flash_isr_handler

  

INTS_SwInterrupt.c

    #pragma push /* Save the current state */

    #pragma section const_type ".__flash_isr_handler" ".__flash_isr_handler"

  

    const INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR] =

    {

    }

  

INTS_Interrupt.h

#pragma push

#pragma section const_type ".__flash_isr_handler"

extern const __declspec(section ".__flash_isr_handler") INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR];

#pragma pop

In the exemple4, it is working, but I define my interrupt table in the internal_flash section.

But I prefere to create a special section for the interrupt, I'm not satisfied of this solution.

MPC5604B_FLASH.lcf

    exception_handlers:    org = 0x00001000,   len = 0x00002000

  

    internal_flash:        org = 0x00003000,   len = 0x0007D000

  

  

    .....

   GROUP : {

      .text : {}

      .text_vle (VLECODE) ALIGN(0x08): {

         *(.text)

         *(.text_vle)

       }

       .rodata (CONST) : {

         *(.rdata)

         *(.rodata)

       }

       /* The INTC module for this device contains 217 IRQs.*/

       .__initialized_flash_isr_handle   ALIGN(2048) : {}

       .__uninitialized_flash_isr_handle ALIGN(2048) : {}

       .ctors : {}

       .dtors : {}

       extab : {}

       extabindex : {}

    } > internal_flash

    GROUP : {

       .__flash_isr_handler ALIGN(2048) : {}

    } > flash_isr_handler

  

INTS_SwInterrupt.c

#pragma push /* Save the current state */

#pragma section data_type ".__initialized_flash_isr_handle" ".__uninitialized_flash_isr_handle"

const INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR] =

  

INTS_Interrupt.h

#pragma push

#pragma section data_type ".__initialized_flash_isr_handle" ".__uninitialized_flash_isr_handle"

extern const __declspec(section ".__initialized_flash_isr_handle") INTSInterruptFn INTSSwInterruptsTable[INTS_U8_NUMBER_OF_ISR];

#pragma pop

Do you have an idea where does come from the problem?

0 Kudos
2,044 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

I checked Example1 code , but I do not see any obvious error. The only one thing I found is Interrupt Vector Table declaration which is different from mine.  There should not be any problem if the section is placed in front of flash section. Use the first example and at first, try to look if the vector table is located in the right place in flash. Then check, if there is correct address in INTC IACKR. It should be address 3000.

Which IDE and compiler do you use? It is possible for you to download CodeWarrior 10.6 and try to recreate first example in this IDE (only the necessary code)? Here is the link for CW 10.6:

CodeWarrior for Microcontrollers-Eclipse IDE|NXP

Regards,

Martin

0 Kudos
2,044 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

I am on vacation right now. I will be back in the office on 1st February. Then I will try to look at the problem.

Regards,

Martin

0 Kudos