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移植工程。

posted @ 2020-02-20 15:24  凉风SK  阅读(2182)  评论(2编辑  收藏  举报