• Tricore系列MCU中断系统的原理(二、补充)+Trap使用总结


    在上一篇文章中介绍了软件中断管理与硬件中断管理,但是硬件中断的内容遗漏了一部分:iLLD下的硬件中断管理,在此进行补充。

    首先说明一下中断管理代码的位置,以明确整体架构。

    iLLD

    | - - - IfxCpu_Irq.c + CompilerGnuc.h 软件中断管理

    | - - - CompilerGnuc.h 硬件中断管理

    no iLLD

    | - - - cint_tc29x.c 硬件中断管理(没有软件中断管理)

    直接看代码(删除了部分无关代码):

    /**
     * \file CompilerGnuc.h
     */
    
    #ifndef COMPILERGNUC_H
    #define COMPILERGNUC_H 1
    
    /******************************************************************************/
    
    #include <stddef.h>
    
    /*Linker definitions which are specific to Gnuc */
    /* IFX_CFG_USE_COMPILER_DEFAULT_LINKER shall be defined in Ifx_Cfg.h
     * to use the default compiler linker varaibles and startup */
    #ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER
    
    /*End: Common definitions ************************************************ */
    
    /*Start: Core 0 definitions ********************************************** */
    
    /*C extern defintions */
    #define IFXCOMPILER_CORE_LINKER_SYMBOLS(cpu)                                    \
        extern unsigned int __USTACK##cpu[];      /**< user stack end */            \
        extern unsigned int __ISTACK##cpu[];      /**< interrupt stack end */       \
        extern unsigned int __INTTAB_CPU##cpu[];  /**< Interrupt vector table */    \  //refer to the Label defined in linker script(.lsl)
        extern unsigned int __TRAPTAB_CPU##cpu[]; /**< trap table */                \
        extern unsigned int __CSA##cpu[];         /**< context save area 1 begin */ \
        extern unsigned int __CSA##cpu##_END[];   /**< context save area 1 begin */
    
    #define __USTACK(cpu)      __USTACK##cpu
    #define __ISTACK(cpu)      __ISTACK##cpu
    #define __INTTAB_CPU(cpu)  __INTTAB_CPU##cpu
    #define __TRAPTAB_CPU(cpu) __TRAPTAB_CPU##cpu
    #define __CSA(cpu)         __CSA##cpu
    #define __CSA_END(cpu)     __CSA##cpu##_END
    
    /*Wrapper macros for the tool specific definitions */
    #if defined(IFX_USE_SW_MANAGED_INT)  //select software or hardware management
    #define __INTTAB(cpu)      ((unsigned int)__INTTAB_CPU##cpu | (unsigned int)0x1FE0)  //software mode sets BIV to the value of int vector table's base address(defined in .lsl) + 0x1FE0(mask the PIPN's effect) and locate the single vector at intvec_255 in linker script(.lsl file).(see also the last article to know more)
    #else // #define __INTTAB(cpu) __INTTAB_CPU##cpu //hardware mode sets the BIV to the int vector table's base address, which is the vector_0's address.
    //these 2 different macros are used in 2 different kind of interrupt management respectly. see the BIV's assigment in CPU startup program: IfxCpu_Cstart0.c
    #endif /*defined(IFX_USE_SW_MANAGED_INT) */ #define __TRAPTAB(cpu) __TRAPTAB_CPU##cpu #endif /*IFX_CFG_USE_COMPILER_DEFAULT_LINKER*/ /******************************************************************************/ #define IFX_INTERRUPT_FAST IFX_INTERRUPT #if defined(IFX_USE_SW_MANAGED_INT) #ifndef IFX_INTERRUPT #define IFX_INTERRUPT(isr, vectabNum, prio) void isr(void) //in software mode, macro IFX_INTERRUPT is just used to define a normal function. #endif #else /* *INDENT-OFF* */ #ifndef IFX_INTERRUPT #define IFX_INTERRUPT(isr, vectabNum, prio) IFX_INTERRUPT_INTERNAL(isr, vectabNum, prio) //in hardware mode, IFX_INTERRUPT is used to define a section .intvec_tc0_<prio> and a int handler, the code in this section will call the handler.refer to the example below
    #endif /*defined(IFX_USE_SW_MANAGED_INT)*/

    #ifndef IFX_INTERRUPT_INTERNAL 
    #define IFX_INTERRUPT_INTERNAL(isr, vectabNum, prio) \
    __asm__ (
    ".ifndef .intr.entry.include \n"\
        ".altmacro \n"\
        ".macro .int_entry.2 intEntryLabel, name # define the section and inttab entry code \n"\
        "   .pushsection .\\intEntryLabel,\"ax\",@progbits \n"\
        "   __\\intEntryLabel : \n"\
        "     svlcx \n"\
        "     movh.a %a14, hi:\\name \n"\
        "     lea %a14, [%a14]lo:\\name \n"\
        "     ji %a14 \n"\
        "   .popsection \n"\
        ".endm \n"\
        ".macro .int_entry.1 prio,vectabNum,u,name \n"\
        "  .int_entry.2 intvec_tc\\vectabNum\\u\\prio,(name) # build the unique name \n"\
        ".endm \n"\
        "                                               \n"\
        ".macro .intr.entry name,vectabNum,prio \n"\
        "  .int_entry.1 %(prio),%(vectabNum),_,name # evaluate the priority and the cpu number \n"\
        ".endm \n"\
        ".intr.entry.include: \n"\
        ".endif \n"\
        ".intr.entry "#isr","#vectabNum","#prio );\
    IFX_EXTERN
    void __attribute__ ((interrupt_handler)) isr(); \
    void isr (void)
    //example of interrupt handler's installing in hardware mode:
    /*
    IFX_INTERRUPT( IsrStm, 0, 3 )
    {
      //clear int flag
      //increase compare value
      //...
    }
    */
    /*       
    ||
    ||
    \|| /
    \/
    */
    /*

    .pushsection .intvec_tc0_3, "ax", @progbits
    __intvec_tc0_3 :
      svlcx movh.a %a14, hi:IsrStm
      lea %a14, [%a14]lo:IsrStm
      ji %a14
    .popsection
    extern void __attribute__ ((interrupt_handler)) IsrStm(); \
    void IsrStm (void)
    {
      //clear int flag
      //increase compare value
      //...
    }
    */

    // sections predefined in linker script(.lsl):
    // .inttab_tc0_000 (LCF_INTVEC0_START + 0x0) : { . = ALIGN(8) ; KEEP (*(.intvec_tc0_0)); } > pfls0
    // .inttab_tc0_001 (LCF_INTVEC0_START + 0x20) : { . = ALIGN(8) ; KEEP (*(.intvec_tc0_1)); } > pfls0
    // .inttab_tc0_002 (LCF_INTVEC0_START + 0x40) : { . = ALIGN(8) ; KEEP (*(.intvec_tc0_2)); } > pfls0
    // .inttab_tc0_003 (LCF_INTVEC0_START + 0x60) : { . = ALIGN(8) ; KEEP (*(.intvec_tc0_3)); } > pfls0
    // .inttab_tc0_004 (LCF_INTVEC0_START + 0x80) : { . = ALIGN(8) ; KEEP (*(.intvec_tc0_4)); } > pfls0
    // ......
    #endif
    /* IFX_INTERRUPT_INTERNAL */

    /* *INDENT-ON* */

    #endif
    /* COMPILERGNUC_H */

    /* software mode VS hardware mode in installing int handler:
    1.software:
    (1)define isr:
    IFX_INTERRUPT( IsrFunc, 0, ISR_PRIO )
    {
      int handle...
    }
    or:
    void IsrFunc(void)
    {
      int handle...
    }
    (2)install isr
    IfxCpu_Irq_installInterruptHandler( IsrFunc, ISR_PRIO );

    2.hardware:
    (1)define isr:
    IFX_INTERRUPT( IsrFunc, 0, ISR_PRIO )
    {
      int handle...
    }
    needn't to install manually, built in ASM.
    */

     

     至此,中断系统的管理就已经分析完了。

    -----------------------------------------------------

    本来想总结一下Trap的使用,不过由于Trap和中断在原理和向量表等方面非常相近,所以就不想另起一篇了,这里只大概总结一下:

    1.cint_tc29x.c和IfxCpu_Trap.h/.c中都用汇编语言定义并安装了trap向量表;

    2.向量表的入口地址存入了BTV寄存器中(Base Address of Trap Vector Table),BTV寄存器类似于BIV寄存器;

    3.trap处理函数中都开放了钩子函数接口(Extend Hook)供开发者使用。

    关于Trap的具体使用方法,参考IfxCpu_Trap.h中的使用说明。具体应用实例参考FreeRTOS移植工程。

  • 相关阅读:
    向量求导几则公式备忘
    电脑硬件接触不良
    caffe编译新问题
    faster-rcnn 目标检测 数据集制作
    py-faster-rcnn 的makefile.config 注意事项
    ubuntu14.04 python + opencv 傻瓜式安装解决方案
    轻量级神经网络平台tiny-dnn实践
    OpenMP 并行编程
    React在Render中使用bind可能导致的问题
    为了cider,尝试emacs的坑
  • 原文地址:https://www.cnblogs.com/uestcliming666/p/12334904.html
Copyright © 2020-2023  润新知