[嵌入式系统-37]:龙芯1B 开发学习套件 -6-协处理器CP0之CPU异常处理与外部中断控制器的中断处理

news/2024/4/24 17:32:28/文章来源:https://blog.csdn.net/HiWangWenBing/article/details/136521214

目录

一、MPIS CPU Core与32个异常exception

1.1 龙芯1B的MIPS CPU IP Core

1.2 MIP32指令系统

1.3 MIPS CPU寄存器

1.4 MIPS CPU的异常向量与异常向量号

1.5 龙芯异常exception与中断interrupt的区别

二、协议处理器CP0的中断控制与8个中断

2.1 CP0概述

2.2 协处理器支持的32个寄存器

2.3 CPU协处理器CP0支持的中断

2.4 协处理器CP0的中断服务程序

三、4个外部中断控制器与128个外部中断

3.1 外部中断源与4个中断控制器:INT0、INT1、INT2、INT3

3.2 如何配置外部中断源

3.3 四个中断控制器控制的所有外部中断的中断向量表

3.2.1 软件中断向量表结构定义:ls1b_irq.c

3.2.2 软件中断向量表定义:ls1b_irq.c和ls1b_irq.h

3.3.3 默认的中断处理或中断服务程序:ls1b_irq.c

3.3.4 中断向量表的初始化

3.3.5 安装用户自定义的中断服务程序的安装与移除

3.4 4个中断控制器的中断相关的寄存器

3.4.1 中断相关的寄存器列表(每个中断控制器有一套寄存器)

3.4.2 32bit 中断寄存器含义

3.4.3 32bits如何与中断源对应起来

3.4.5 如何根据中断原因寄存器挨个、逐一分发中断服务程序

2.4.6 四个中断控制器对应的中断服务程序

2.4.7 CPU协处理器是如何调用4个中断控制器对应的中断服务器程序


一、MPIS CPU Core与32个异常exception

1.1 龙芯1B的MIPS CPU IP Core

1.2 MIP32指令系统

1.3 MIPS CPU寄存器

1.4 MIPS CPU的异常向量与异常向量号

/** Define the name of the CPU family.*/
#define CPU_NAME "MIPS"/** MIPS Vector numbers for exception conditions. This is a direct map to the causes.*/
#define MIPS_EXCEPTION_BASE             0#define MIPS_EXCEPTION_INT              MIPS_EXCEPTION_BASE+0
#define MIPS_EXCEPTION_MOD              MIPS_EXCEPTION_BASE+1
#define MIPS_EXCEPTION_TLBL             MIPS_EXCEPTION_BASE+2
#define MIPS_EXCEPTION_TLBS             MIPS_EXCEPTION_BASE+3
#define MIPS_EXCEPTION_ADEL             MIPS_EXCEPTION_BASE+4
#define MIPS_EXCEPTION_ADES             MIPS_EXCEPTION_BASE+5
#define MIPS_EXCEPTION_IBE              MIPS_EXCEPTION_BASE+6
#define MIPS_EXCEPTION_DBE              MIPS_EXCEPTION_BASE+7
#define MIPS_EXCEPTION_SYSCALL          MIPS_EXCEPTION_BASE+8
#define MIPS_EXCEPTION_BREAK            MIPS_EXCEPTION_BASE+9
#define MIPS_EXCEPTION_RI               MIPS_EXCEPTION_BASE+10
#define MIPS_EXCEPTION_CPU              MIPS_EXCEPTION_BASE+11
#define MIPS_EXCEPTION_OVERFLOW         MIPS_EXCEPTION_BASE+12
#define MIPS_EXCEPTION_TRAP             MIPS_EXCEPTION_BASE+13
#define MIPS_EXCEPTION_VCEI             MIPS_EXCEPTION_BASE+14
/* FPE only on mips2 and higher */
#define MIPS_EXCEPTION_FPE              MIPS_EXCEPTION_BASE+15
#define MIPS_EXCEPTION_C2E              MIPS_EXCEPTION_BASE+16
/* 17-22 reserved */
#define MIPS_EXCEPTION_WATCH            MIPS_EXCEPTION_BASE+23
/* 24-30 reserved */
#define MIPS_EXCEPTION_VCED             MIPS_EXCEPTION_BASE+31#define MIPS_INTERRUPT_BASE             MIPS_EXCEPTION_BASE+32  //协处理器中断服务程序入口

1.5 龙芯异常exception与中断interrupt的区别

龙芯处理器中的异常(exception)和中断(interrupt)在概念上是有区别的,它们分别代表了不同类型的事件和处理机制:

  1. 异常(Exception):异常是指在程序执行过程中出现的一种非正常事件,通常是由指令执行时产生的,可以看作是处理器内部的问题。异常可以是因为错误的操作码、内存访问冲突、算术错误等原因导致的,需要处理器暂停当前指令的执行并执行相应的异常处理程序。异常通常由处理器本身或者处理器内部逻辑主动触发,它跳转到异常处理程序,处理完异常后再恢复到正常指令流程。

  2. 中断(Interrupt):中断是指来自外部设备的一种请求要求处理器暂停当前正在执行的程序,转而执行与中断相关的处理程序。中断是处理器响应外部事件的一种方式,可以是来自设备的信号或者时钟,需要处理器打断当前执行的指令流程,执行相应的中断服务程序,处理完中断后再返回到被中断的程序继续执行。

        在龙芯处理器中,异常和中断的区别在于触发原因和处理方式上:异常通常是由指令执行过程中的内部错误或意外情况引发,需要处理器内部去处理;而中断是由外部事件触发,需要处理器响应外部设备的请求。处理器在接收到异常或中断信号后,会根据具体情况执行相应的处理程序,保证系统的稳定运行和正确性。

二、协议处理器CP0的中断控制与8个中断

2.1 CP0概述

龙芯1B协处理器CP0(Coprocessor 0)是龙芯处理器(Loongson)中的一个重要组成部分,主要用于管理处理器的系统级行为和状态信息。CP0是一个与主处理器CPU紧密集成的协处理器,它的功能主要有以下几个方面:

  1. 地址转换和虚拟存储管理MMU:CP0可以实现物理地址的解析和转换,支持虚拟存储管理,使得应用程序可以像访问物理内存一样方便地访问虚拟内存区域。

  2. 异常和中断处理(本文要深入讨论的部分):CP0是处理器内部异常exception和外部中断Interrupt处理的核心,它存储了异常和中断向量表、错误状态码等信息,并负责中断的响应和异常处理程序的执行

  3. 性能计数器和性能分析:CP0中还包括可编程的性能计数器和时钟戳记寄存器,可以用于对程序的性能分析和调优,并支持操作系统的性能监控功能。

  4. 系统控制寄存器:CP0中还包含了一些系统级别的控制寄存器,可以用于修改处理器的运行状态,如设置缓存策略、开/关写缓冲等。

总之,龙芯1B协处理器CP0是Loongson处理器的重要组成部分,它管理和控制处理器中的系统级行为和状态信息,为操作系统和应用程序提供了重要的支持和保障。

2.2 协处理器支持的32个寄存器

协处理器支持32个寄存器,其中部分寄存器用于中断控制!!!

2.3 CPU协处理器CP0支持的中断

/** CP0 Cause ($12)  IP bit(15:8)=IP[7:0], IP[1:0] is soft-interrupt*     Status($13)  IM bit(15:8) if mask interrupts**/
#define LS1B_IRQ_SW0            (MIPS_INTERRUPT_BASE + 0)
#define LS1B_IRQ_SW1            (MIPS_INTERRUPT_BASE + 1)
#define LS1B_IRQ0_REQ           (MIPS_INTERRUPT_BASE + 2)
#define LS1B_IRQ1_REQ           (MIPS_INTERRUPT_BASE + 3)
#define LS1B_IRQ2_REQ           (MIPS_INTERRUPT_BASE + 4)
#define LS1B_IRQ3_REQ           (MIPS_INTERRUPT_BASE + 5)
#define LS1B_IRQ_PERF           (MIPS_INTERRUPT_BASE + 6)
#define LS1B_IRQ_CNT            (MIPS_INTERRUPT_BASE + 7)

2.4 协处理器CP0的中断服务程序

void c_interrupt_handler(void *p)
{unsigned int sr;unsigned int cause;mips_get_sr(sr);mips_get_cause(cause);  cause &= (sr & SR_IMASK);cause >>= CAUSE_IPSHIFT;/******************************************************************* XXX use as bsp system tick generator.*/if (cause & 0x80)			/* count/compare interrupt */{bsp_irq_handler_dispatch(LS1x_IRQ_CNT);}if (cause & 0x04)			/* Interrupt controller 0 */{call_vectored_isr(p, cause, (void *)LS1x_INTC0_BASE);}if (cause & 0x08)			/* Interrupt controller 1 */{call_vectored_isr(p, cause, (void *)LS1x_INTC1_BASE);}if (cause & 0x10)			/* Interrupt controller 2 */{call_vectored_isr(p, cause, (void *)LS1x_INTC2_BASE);}if (cause & 0x20)			/* Interrupt controller 3 */{call_vectored_isr(p, cause, (void *)LS1x_INTC3_BASE);}#if defined(LS1B)if (cause & 0x40)			/* Performance counter */{bsp_irq_handler_dispatch(LS1x_IRQ_PERF);}#elif defined(LS1C)if (cause & 0x40)			/* Interrupt controller 4 */{call_vectored_isr(p, cause, (void *)LS1x_INTC4_BASE);}#endifif (cause & 0x02)			/* Soft Interrupt SW[1] */{bsp_irq_handler_dispatch(LS1x_IRQ_SW1);}if (cause & 0x01)			/* Soft Interrupt SW[0] */{bsp_irq_handler_dispatch(LS1x_IRQ_SW0);}// mips_set_cause(0);
}

三、4个外部中断控制器与128个外部中断

3.1 外部中断源与4个中断控制器:INT0、INT1、INT2、INT3

龙芯1B SOC芯片内置了4个简单、灵活的中断控制器,即INT0、INT1、INT2、INT3,用于管理SOC芯片外设和GPIO的中断。每个中断控制器最大管辖32个中断。

1B芯片的中断控制器除了管理 GPIO输入的中断信号外,中断控制器还处理内部设备引起的中断。所有的中断寄存器的位域安排相同,一个中断源对应其中一位

SOC的中断控制器共四个中断线输出连接到CPU模块,分别对应 INT0, INT1, INT2, INT3

SOC芯片中断控制器本身能够支持 64个内部中断和 64个 GPIO的中断,最大一共128个硬件外部中断源,这128个中断源分为四组,每组最大支持32个中断源,分别归组为:INT0, INT1, INT2, INT3。

其中 INT0和 INT1分别对应于 64个内部中断的前后 32位,INT2和 INT3对应于 64个外部 GPIO中断。但龙芯1B的实现过程中,并非所有的中断源都被使用,部分中断源是保留未使用,

具体中断源如下表所示: 

从上图可以看出:

(1)GPIO31、GPIO62、GPIO63都未使用,属于保留位,因此一个64-3=61个GPIO中断源。

(2)并非所有的INT0和INT1的外设中断都被使用上,实际上,龙芯1B SOC芯片,并没有那么多外设,因此,大量的位都是闲置的,属于保留为,未定义其行为。

3.2 如何配置外部中断源

3.3 四个中断控制器控制的所有外部中断的中断向量表

3.2.1 软件中断向量表结构定义:ls1b_irq.c

/* 中断向量表 */
typedef struct isr_tbl
{void (*handler)(int, void *);       // 中断句柄unsigned int arg;                   // 参数 
} isr_tbl_t;

3.2.2 软件中断向量表定义:ls1b_irq.c和ls1b_irq.h

定义龙芯1B实际支持的中断源(去除保留位)


/******************************************************************************
 * Interrupt Vector Numbers
 * MIPS_INTERRUPT_BASE should be 32 (0x20)
 ******************************************************************************/

/*
 * CP0 Cause ($12)  IP bit(15:8)=IP[7:0],

*       IP[1:0] is soft-interrupt
 *     Status($13)  IM bit(15:8) if mask interrupts
 *
 */
#define LS1B_IRQ_SW0            (MIPS_INTERRUPT_BASE + 0)   # 协处理器的软中断
#define LS1B_IRQ_SW1            (MIPS_INTERRUPT_BASE + 1)   # 协处理器的软中断
#define LS1B_IRQ0_REQ           (MIPS_INTERRUPT_BASE + 2)  # 协处理器的中断请求0
#define LS1B_IRQ1_REQ           (MIPS_INTERRUPT_BASE + 3)   # 协处理器的中断请求1
#define LS1B_IRQ2_REQ           (MIPS_INTERRUPT_BASE + 4)   # 协处理器的中断请求2
#define LS1B_IRQ3_REQ           (MIPS_INTERRUPT_BASE + 5)   # 协处理器的中断请求3
#define LS1B_IRQ_PERF           (MIPS_INTERRUPT_BASE + 6)   # 协处理器的性能统计中断
#define LS1B_IRQ_CNT            (MIPS_INTERRUPT_BASE + 7)    # 协处理器的计数或tick中断,操作系统调度使用

/*
 * Interrupt Control 0 Interrupts: 中断控制器0支持的外设中断数量:29个
 */
#define LS1B_IRQ0_BASE          (MIPS_INTERRUPT_BASE + 8)

#define LS1B_UART0_IRQ          (LS1B_IRQ0_BASE + 2)
#define LS1B_UART1_IRQ          (LS1B_IRQ0_BASE + 3)
#define LS1B_UART2_IRQ          (LS1B_IRQ0_BASE + 4)
#define LS1B_UART3_IRQ          (LS1B_IRQ0_BASE + 5)
#define LS1B_CAN0_IRQ           (LS1B_IRQ0_BASE + 6)
#define LS1B_CAN1_IRQ           (LS1B_IRQ0_BASE + 7)
#define LS1B_SPI0_IRQ           (LS1B_IRQ0_BASE + 8)
#define LS1B_SPI1_IRQ           (LS1B_IRQ0_BASE + 9)
#define LS1B_AC97_IRQ           (LS1B_IRQ0_BASE + 10)
#define LS1B_DMA0_IRQ           (LS1B_IRQ0_BASE + 13)
#define LS1B_DMA1_IRQ           (LS1B_IRQ0_BASE + 14)
#define LS1B_DMA2_IRQ           (LS1B_IRQ0_BASE + 15)
#define LS1B_PWM0_IRQ           (LS1B_IRQ0_BASE + 17)
#define LS1B_PWM1_IRQ           (LS1B_IRQ0_BASE + 18)
#define LS1B_PWM2_IRQ           (LS1B_IRQ0_BASE + 19)
#define LS1B_PWM3_IRQ           (LS1B_IRQ0_BASE + 20)
#define LS1B_RTC0_IRQ           (LS1B_IRQ0_BASE + 21)
#define LS1B_RTC1_IRQ           (LS1B_IRQ0_BASE + 22)
#define LS1B_RTC2_IRQ           (LS1B_IRQ0_BASE + 23)
#define LS1B_TOY0_IRQ           (LS1B_IRQ0_BASE + 24)
#define LS1B_TOY1_IRQ           (LS1B_IRQ0_BASE + 25)
#define LS1B_TOY2_IRQ           (LS1B_IRQ0_BASE + 26)
#define LS1B_RTC_IRQ            (LS1B_IRQ0_BASE + 27)
#define LS1B_TOY_IRQ            (LS1B_IRQ0_BASE + 28)
#define LS1B_UART4_IRQ          (LS1B_IRQ0_BASE + 29)
#define LS1B_UART5_IRQ          (LS1B_IRQ0_BASE + 30)

/*
 * Interrupt Control 1 interrupts:中断控制器1支持的外设中断:4个
 */
#define LS1B_IRQ1_BASE          (MIPS_INTERRUPT_BASE + 40)

#define LS1B_EHCI_IRQ           (LS1B_IRQ1_BASE + 0)
#define LS1B_OHCI_IRQ           (LS1B_IRQ1_BASE + 1)
#define LS1B_GMAC0_IRQ          (LS1B_IRQ1_BASE + 2)
#define LS1B_GMAC1_IRQ          (LS1B_IRQ1_BASE + 3)

/*
 * Interrupt Control 2 interrupts (GPIO):中断控制器2支持的GPIO中断数:31个
 */
#define LS1B_IRQ2_BASE          (MIPS_INTERRUPT_BASE + 72)

#define LS1B_GPIO0_IRQ          (LS1B_IRQ2_BASE + 0)
#define LS1B_GPIO1_IRQ          (LS1B_IRQ2_BASE + 1)
#define LS1B_GPIO2_IRQ          (LS1B_IRQ2_BASE + 2)
#define LS1B_GPIO3_IRQ          (LS1B_IRQ2_BASE + 3)
#define LS1B_GPIO4_IRQ          (LS1B_IRQ2_BASE + 4)
#define LS1B_GPIO5_IRQ          (LS1B_IRQ2_BASE + 5)
#define LS1B_GPIO6_IRQ          (LS1B_IRQ2_BASE + 6)
#define LS1B_GPIO7_IRQ          (LS1B_IRQ2_BASE + 7)
#define LS1B_GPIO8_IRQ          (LS1B_IRQ2_BASE + 8)
#define LS1B_GPIO9_IRQ          (LS1B_IRQ2_BASE + 9)
#define LS1B_GPIO10_IRQ         (LS1B_IRQ2_BASE + 10)
#define LS1B_GPIO11_IRQ         (LS1B_IRQ2_BASE + 11)
#define LS1B_GPIO12_IRQ         (LS1B_IRQ2_BASE + 12)
#define LS1B_GPIO13_IRQ         (LS1B_IRQ2_BASE + 13)
#define LS1B_GPIO14_IRQ         (LS1B_IRQ2_BASE + 14)
#define LS1B_GPIO15_IRQ         (LS1B_IRQ2_BASE + 15)
#define LS1B_GPIO16_IRQ         (LS1B_IRQ2_BASE + 16)
#define LS1B_GPIO17_IRQ         (LS1B_IRQ2_BASE + 17)
#define LS1B_GPIO18_IRQ         (LS1B_IRQ2_BASE + 18)
#define LS1B_GPIO19_IRQ         (LS1B_IRQ2_BASE + 19)
#define LS1B_GPIO20_IRQ         (LS1B_IRQ2_BASE + 20)
#define LS1B_GPIO21_IRQ         (LS1B_IRQ2_BASE + 21)
#define LS1B_GPIO22_IRQ         (LS1B_IRQ2_BASE + 22)
#define LS1B_GPIO23_IRQ         (LS1B_IRQ2_BASE + 23)
#define LS1B_GPIO24_IRQ         (LS1B_IRQ2_BASE + 24)
#define LS1B_GPIO25_IRQ         (LS1B_IRQ2_BASE + 25)
#define LS1B_GPIO26_IRQ         (LS1B_IRQ2_BASE + 26)
#define LS1B_GPIO27_IRQ         (LS1B_IRQ2_BASE + 27)
#define LS1B_GPIO28_IRQ         (LS1B_IRQ2_BASE + 28)
#define LS1B_GPIO29_IRQ         (LS1B_IRQ2_BASE + 29)
#define LS1B_GPIO30_IRQ         (LS1B_IRQ2_BASE + 30)
 
/*
 * Interrupt Control 3 source bit (GPIO):中断控制器3支持的GPIO中断数:30个。
 */
#define LS1B_IRQ3_BASE          (MIPS_INTERRUPT_BASE + 104)

#define LS1B_GPIO32_IRQ         (LS1B_IRQ3_BASE + 0)
#define LS1B_GPIO33_IRQ         (LS1B_IRQ3_BASE + 1)
#define LS1B_GPIO34_IRQ         (LS1B_IRQ3_BASE + 2)
#define LS1B_GPIO35_IRQ         (LS1B_IRQ3_BASE + 3)
#define LS1B_GPIO36_IRQ         (LS1B_IRQ3_BASE + 4)
#define LS1B_GPIO37_IRQ         (LS1B_IRQ3_BASE + 5)
#define LS1B_GPIO38_IRQ         (LS1B_IRQ3_BASE + 6)
#define LS1B_GPIO39_IRQ         (LS1B_IRQ3_BASE + 7)
#define LS1B_GPIO40_IRQ         (LS1B_IRQ3_BASE + 8)
#define LS1B_GPIO41_IRQ         (LS1B_IRQ3_BASE + 9)
#define LS1B_GPIO42_IRQ         (LS1B_IRQ3_BASE + 10)
#define LS1B_GPIO43_IRQ         (LS1B_IRQ3_BASE + 11)
#define LS1B_GPIO44_IRQ         (LS1B_IRQ3_BASE + 12)
#define LS1B_GPIO45_IRQ         (LS1B_IRQ3_BASE + 13)
#define LS1B_GPIO46_IRQ         (LS1B_IRQ3_BASE + 14)
#define LS1B_GPIO47_IRQ         (LS1B_IRQ3_BASE + 15)
#define LS1B_GPIO48_IRQ         (LS1B_IRQ3_BASE + 16)
#define LS1B_GPIO49_IRQ         (LS1B_IRQ3_BASE + 17)
#define LS1B_GPIO50_IRQ         (LS1B_IRQ3_BASE + 18)
#define LS1B_GPIO51_IRQ         (LS1B_IRQ3_BASE + 19)
#define LS1B_GPIO52_IRQ         (LS1B_IRQ3_BASE + 20)
#define LS1B_GPIO53_IRQ         (LS1B_IRQ3_BASE + 21)
#define LS1B_GPIO54_IRQ         (LS1B_IRQ3_BASE + 22)
#define LS1B_GPIO55_IRQ         (LS1B_IRQ3_BASE + 23)
#define LS1B_GPIO56_IRQ         (LS1B_IRQ3_BASE + 24)
#define LS1B_GPIO57_IRQ         (LS1B_IRQ3_BASE + 25)
#define LS1B_GPIO58_IRQ         (LS1B_IRQ3_BASE + 26)
#define LS1B_GPIO59_IRQ         (LS1B_IRQ3_BASE + 27)
#define LS1B_GPIO60_IRQ         (LS1B_IRQ3_BASE + 28)
#define LS1B_GPIO61_IRQ         (LS1B_IRQ3_BASE + 29)

#define LS1B_MAXIMUM_VECTORS        (LS1B_GPIO61_IRQ+1)

#define BSP_INTERRUPT_VECTOR_MIN    0
#define BSP_INTERRUPT_VECTOR_MAX    LS1B_MAXIMUM_VECTORS

备注:中断向量表中一共支持8 + 29 + 4 + 31 + 30 = 8 + 33 + 61 = 102个中断。

中断向量表:

static isr_tbl_t isr_table[BSP_INTERRUPT_VECTOR_MAX];

3.3.3 默认的中断处理或中断服务程序:ls1b_irq.c

/** 默认中断 */
static void mips_default_isr(int vector, void *arg)
{unsigned int sr;unsigned int cause;mips_get_sr(sr);mips_get_cause(cause);printf("Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n",vector, cause, sr);while (1);
}

3.3.4 中断向量表的初始化

/* * 初始化*/ 
void mips_init_isr_table(void)
{unsigned int i;for (i=0; i<BSP_INTERRUPT_VECTOR_MAX; i++) {isr_table[i].handler = mips_default_isr;isr_table[i].arg = i;}
}

使用默认的中断服务程序mips_default_isr初始化中断向量表。

3.3.5 安装用户自定义的中断服务程序的安装与移除

void ls1x_install_irq_handler(int vector, void (*isr)(int, void *), void *arg)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){mips_interrupt_disable();isr_table[vector].handler = isr;isr_table[vector].arg = (unsigned int)arg;mips_interrupt_enable();}
}void ls1x_remove_irq_handler(int vector)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){mips_interrupt_disable();isr_table[vector].handler = mips_default_isr;isr_table[vector].arg = vector;mips_interrupt_enable();}
}

3.4 4个中断控制器的中断相关的寄存器

3.4.1 中断相关的寄存器列表(每个中断控制器有一套寄存器)

/** Interrupt Control register*/
#define LS1B_INTC0_BASE         0xBFD01040  #中断控制器0对应的寄存器的基地址
#define LS1B_INTC1_BASE         0xBFD01058  #中断控制器1对应的寄存器的基地址
#define LS1B_INTC2_BASE         0xBFD01070  #中断控制器2对应的寄存器的基地址
#define LS1B_INTC3_BASE         0xBFD01088  #中断控制器3对应的寄存器的基地址#define LS1B_INTC_ISR(base)     (*(volatile unsigned int*)(base + 0x00))   /* 中断控制状态寄存器 */
#define LS1B_INTC_IEN(base)     (*(volatile unsigned int*)(base + 0x04))   /* 中断控制使能寄存器 */
#define LS1B_INTC_SET(base)     (*(volatile unsigned int*)(base + 0x08))   /* 中断置位寄存器 */
#define LS1B_INTC_CLR(base)     (*(volatile unsigned int*)(base + 0x0C))   /* 中断清空寄存器 */
#define LS1B_INTC_POL(base)     (*(volatile unsigned int*)(base + 0x10))   /* 高电平触发中断使能寄存器 *//* EDGE 电平触发时: 1=高电平触发, 0=低电平触发EDGE 边沿触发时: 1=上升沿触发, 0=下降沿触发 */
#define LS1B_INTC_EDGE(base)    (*(volatile unsigned int*)(base + 0x14))   /* 边沿触发中断使能寄存器; 1:边沿触发, 0: 电平触发 */

3.4.2 32bit 中断寄存器含义

(1)中断控制状态寄存器:表面是否有某种中断发生

(2)中断控制使能寄存器:使能某个中断控制器的某个中断

(3)中断置位寄存器:强制置位对应bits的中断

(4)中断清空寄存器:强制清空对应bit的中断

(5)高电平触发中断使能寄存器:中断使能

3.4.3 32bits如何与中断源对应起来

四个中断控制器对应的bits有各自的含义

/** Interrupt Control 0 source bit:中断控制器0的中断源*/
#define INTC0_UART5_BIT         bit(30)
#define INTC0_UART4_BIT         bit(29)
#define INTC0_TOY_BIT           bit(28)
#define INTC0_RTC_BIT           bit(27)
#define INTC0_TOY2_BIT          bit(26)
#define INTC0_TOY1_BIT          bit(25)
#define INTC0_TOY0_BIT          bit(24)
#define INTC0_RTC2_BIT          bit(23)
#define INTC0_RTC1_BIT          bit(22)
#define INTC0_RTC0_BIT          bit(21)
#define INTC0_PWM3_BIT          bit(20)
#define INTC0_PWM2_BIT          bit(19)
#define INTC0_PWM1_BIT          bit(18)
#define INTC0_PWM0_BIT          bit(17)
#define INTC0_DMA2_BIT          bit(15)
#define INTC0_DMA1_BIT          bit(14)
#define INTC0_DMA0_BIT          bit(13)
#define INTC0_AC97_BIT          bit(10)
#define INTC0_SPI1_BIT          bit(9)
#define INTC0_SPI0_BIT          bit(8)
#define INTC0_CAN1_BIT          bit(7)
#define INTC0_CAN0_BIT          bit(6)
#define INTC0_UART3_BIT         bit(5)
#define INTC0_UART2_BIT         bit(4)
#define INTC0_UART1_BIT         bit(3)
#define INTC0_UART0_BIT         bit(2)/** Interrupt Control 1 source bit:中断控制器1的中断源*/
#define INTC1_GMAC1_BIT         bit(3)
#define INTC1_GMAC0_BIT         bit(2)
#define INTC1_OHCI_BIT          bit(1)
#define INTC1_EHCI_BIT          bit(0)/** Interrupt Control 2 source bit (GPIO) :中断控制器2对应的中断源*/
#define INTC2_GPIO30_BIT        bit(30)
#define INTC2_GPIO29_BIT        bit(29)
#define INTC2_GPIO28_BIT        bit(28)
#define INTC2_GPIO27_BIT        bit(27)
#define INTC2_GPIO26_BIT        bit(26)
#define INTC2_GPIO25_BIT        bit(25)
#define INTC2_GPIO24_BIT        bit(24)
#define INTC2_GPIO23_BIT        bit(23)
#define INTC2_GPIO22_BIT        bit(22)
#define INTC2_GPIO21_BIT        bit(21)
#define INTC2_GPIO20_BIT        bit(20)
#define INTC2_GPIO19_BIT        bit(19)
#define INTC2_GPIO18_BIT        bit(18)
#define INTC2_GPIO17_BIT        bit(17)
#define INTC2_GPIO16_BIT        bit(16)
#define INTC2_GPIO15_BIT        bit(15)
#define INTC2_GPIO14_BIT        bit(14)
#define INTC2_GPIO13_BIT        bit(13)
#define INTC2_GPIO12_BIT        bit(12)
#define INTC2_GPIO11_BIT        bit(11)
#define INTC2_GPIO10_BIT        bit(10)
#define INTC2_GPIO9_BIT         bit(9)
#define INTC2_GPIO8_BIT         bit(8)
#define INTC2_GPIO7_BIT         bit(7)
#define INTC2_GPIO6_BIT         bit(6)
#define INTC2_GPIO5_BIT         bit(5)
#define INTC2_GPIO4_BIT         bit(4)
#define INTC2_GPIO3_BIT         bit(3)
#define INTC2_GPIO2_BIT         bit(2)
#define INTC2_GPIO1_BIT         bit(1)
#define INTC2_GPIO0_BIT         bit(0)/** Interrupt Control 3 source bit (GPIO):中断控制器3对应的中断源*/
#define INTC3_GPIO61_BIT        bit(29)
#define INTC3_GPIO60_BIT        bit(28)
#define INTC3_GPIO59_BIT        bit(27)
#define INTC3_GPIO58_BIT        bit(26)
#define INTC3_GPIO57_BIT        bit(25)
#define INTC3_GPIO56_BIT        bit(24)
#define INTC3_GPIO55_BIT        bit(23)
#define INTC3_GPIO54_BIT        bit(22)
#define INTC3_GPIO53_BIT        bit(21)
#define INTC3_GPIO52_BIT        bit(20)
#define INTC3_GPIO51_BIT        bit(19)
#define INTC3_GPIO50_BIT        bit(18)
#define INTC3_GPIO49_BIT        bit(17)
#define INTC3_GPIO48_BIT        bit(16)
#define INTC3_GPIO47_BIT        bit(15)
#define INTC3_GPIO46_BIT        bit(14)
#define INTC3_GPIO45_BIT        bit(13)
#define INTC3_GPIO44_BIT        bit(12)
#define INTC3_GPIO43_BIT        bit(11)
#define INTC3_GPIO42_BIT        bit(10)
#define INTC3_GPIO41_BIT        bit(9)
#define INTC3_GPIO40_BIT        bit(8)
#define INTC3_GPIO39_BIT        bit(7)
#define INTC3_GPIO38_BIT        bit(6)
#define INTC3_GPIO37_BIT        bit(5)
#define INTC3_GPIO36_BIT        bit(4)
#define INTC3_GPIO35_BIT        bit(3)
#define INTC3_GPIO34_BIT        bit(2)
#define INTC3_GPIO33_BIT        bit(1)
#define INTC3_GPIO32_BIT        bit(0)

3.4.5 如何根据中断原因寄存器挨个、逐一分发中断服务程序

(1)读取中断原因寄存器

#define LS1B_INTC_ISR(base)     (*(volatile unsigned int*)(base + 0x00))   /* 中断控制状态寄存器 */

#define LS1x_INTC_ISR(base)     LS1B_INTC_ISR(base)

(2)逐一检查原因寄存器

//-----------------------------------------------------------------------------static void call_vectored_isr(void *p, unsigned int cause, void *ctrlr)
{unsigned int src;int index;/* check request */src = LS1x_INTC_ISR((unsigned int)ctrlr);index = 0;while (src)  //挨个检查所有的中断源{/* check LSB */if (src & 1) {/* clear */LS1x_INTC_CLR((unsigned int)ctrlr) = (1 << index);asm volatile ("sync");if ((unsigned int)ctrlr == LS1x_INTC0_BASE){bsp_irq_handler_dispatch(LS1x_IRQ0_BASE + index);}else if ((unsigned int)ctrlr == LS1x_INTC1_BASE){bsp_irq_handler_dispatch(LS1x_IRQ1_BASE + index);}else if ((unsigned int)ctrlr == LS1x_INTC2_BASE){bsp_irq_handler_dispatch(LS1x_IRQ2_BASE + index);}else if ((unsigned int)ctrlr == LS1x_INTC3_BASE){bsp_irq_handler_dispatch(LS1x_IRQ3_BASE + index);}#if defined(LS1C)else if ((unsigned int)ctrlr == LS1x_INTC4_BASE){bsp_irq_handler_dispatch(LS1x_IRQ4_BASE + index);}#endif}index++;/* shift, and make sure MSB is clear */src = (src >> 1) & 0x7fffffff;  //挨个检查所有的中断源}
}

(3)根据中断向量表执行中断服务器程序

//-----------------------------------------------------------------------------
// 中断分发 
//-----------------------------------------------------------------------------static void bsp_irq_handler_dispatch(int vector)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){if (isr_table[vector].handler){/* * 关中断由中断程序自己处理 */isr_table[vector].handler(vector, (void *)isr_table[vector].arg);/* * 开中断由中断程序自己处理 */}else{mips_default_isr(vector, NULL);}}else{mips_default_isr(vector, NULL);}
}

2.4.6 四个中断控制器对应的中断服务程序

static void call_vectored_isr(void *p, unsigned int cause, void *ctrlr)
{unsigned int src;int index;/* check request */src = LS1x_INTC_ISR((unsigned int)ctrlr);index = 0;while (src) {/* check LSB */if (src & 1) {/* clear */LS1x_INTC_CLR((unsigned int)ctrlr) = (1 << index);asm volatile ("sync");if ((unsigned int)ctrlr == LS1x_INTC0_BASE){bsp_irq_handler_dispatch(LS1x_IRQ0_BASE + index);}else if ((unsigned int)ctrlr == LS1x_INTC1_BASE){bsp_irq_handler_dispatch(LS1x_IRQ1_BASE + index);}else if ((unsigned int)ctrlr == LS1x_INTC2_BASE){bsp_irq_handler_dispatch(LS1x_IRQ2_BASE + index);}else if ((unsigned int)ctrlr == LS1x_INTC3_BASE){bsp_irq_handler_dispatch(LS1x_IRQ3_BASE + index);}#if defined(LS1C)else if ((unsigned int)ctrlr == LS1x_INTC4_BASE){bsp_irq_handler_dispatch(LS1x_IRQ4_BASE + index);}#endif}index++;/* shift, and make sure MSB is clear */src = (src >> 1) & 0x7fffffff;}
}

2.4.7 CPU协处理器是如何调用4个中断控制器对应的中断服务器程序

void c_interrupt_handler(void *p)
{unsigned int sr;unsigned int cause;mips_get_sr(sr);mips_get_cause(cause);  cause &= (sr & SR_IMASK);cause >>= CAUSE_IPSHIFT;/******************************************************************* XXX use as bsp system tick generator.*/if (cause & 0x80)			/* count/compare interrupt */{bsp_irq_handler_dispatch(LS1x_IRQ_CNT);}if (cause & 0x04)			/* Interrupt controller 0 中断控制器0对应的中断服务程序 */{call_vectored_isr(p, cause, (void *)LS1x_INTC0_BASE);}if (cause & 0x08)			/* Interrupt controller 1 中断控制器1对应的中断服务程序*/{call_vectored_isr(p, cause, (void *)LS1x_INTC1_BASE);}if (cause & 0x10)			/* Interrupt controller 2 中断控制器2对应的中断服务程序*/{call_vectored_isr(p, cause, (void *)LS1x_INTC2_BASE);}if (cause & 0x20)			/* Interrupt controller 3 中断控制器3对应的中断服务程序*/{call_vectored_isr(p, cause, (void *)LS1x_INTC3_BASE);}#if defined(LS1B)if (cause & 0x40)			/* Performance counter */{bsp_irq_handler_dispatch(LS1x_IRQ_PERF);}#elif defined(LS1C)if (cause & 0x40)			/* Interrupt controller 4 */{call_vectored_isr(p, cause, (void *)LS1x_INTC4_BASE);}#endifif (cause & 0x02)			/* Soft Interrupt SW[1] */{bsp_irq_handler_dispatch(LS1x_IRQ_SW1);}if (cause & 0x01)			/* Soft Interrupt SW[0] */{bsp_irq_handler_dispatch(LS1x_IRQ_SW0);}// mips_set_cause(0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_998491.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++精简版回顾】18.文件操作

1.文件操作头文件 2.操作文件所用到的函数 1.文件io 1.头文件 #include<fstream> 2.打开文件 &#xff08;1&#xff09;函数名 文件对象.open &#xff08;2&#xff09;函数参数 /* ios::out 可读 ios::in 可…

类与对象(三)--static成员、友元

文章目录 1.static成员1.1概念&#x1f3a7;面试题✒️1.2static的特性&#x1f3a7;1.3思考&#x1f3a7; 2.友元2.1什么是友元&#xff1f;&#x1f3a7;2.2两种友元关系&#xff1a;&#x1f3a7; 1.static成员 1.1概念&#x1f3a7; &#x1f50e; static关键字用于声明类…

IO接口 2月5日学习笔记

1.fgetc 用于从文件中读取一个字符&#xff0c;fgetc 函数每次调用将会返回当前文件指针所指向的字符&#xff0c;并将文件指针指向下一个字符。 int fgetc(FILE *stream); 功能: 从流中读取下一个字符 参数: stream:文件流指针 返回值: …

【Docker】若依ruoyi项目部署

一 搭建局域网 1 # 搭建net-ry局域网&#xff0c;用于部署若依项目docker network create net-ry --subnet172.68.0.0/16 --gateway172.68.0.1 # 注意1&#xff1a;关闭宿主机的防火墙&#xff0c;否者容器内部的MySQL、redis等服务&#xff0c;外部访问不了&#xff1b;开放…

Linux 文件系列:深入理解文件描述符fd,重定向,自定义shell当中重定向的模拟实现

Linux 文件系列:深入理解文件fd,重定向,自定义shell当中重定向的模拟实现 一.预备知识二.回顾C语言中常见的文件接口跟重定向建立联系1.fopen函数的介绍2.fclose函数的介绍3.代码演示1.以"w"(写)的方式打开2.跟输出重定向的联系3.以 "a"(追加)的方式打开4.…

导出谷歌gemma模型为ONNX

参考代码如下&#xff08;从GitHub - luchangli03/export_llama_to_onnx: export llama to onnx修改而来&#xff0c;后面会合入进去&#xff09; 模型权重链接参考&#xff1a; https://huggingface.co/google/gemma-2b-it 可以对modeling_gemma.py进行一些修改(transforme…

革命文物的新征程:SpringBoot实践

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【QT】定时器事件应用

public&#xff1a;//定时器void timerEvent(QTimerEvent *);private:int id;#include <QTimerEvent> //QWidget 默认不追踪鼠标事件 mylabel::mylabel(QWidget *parent) : QLabel(parent) {this->setMouseTracking(true);//启动定时器//参数1&#xff1a;触发定时器的…

electron+vue3全家桶+vite项目搭建【29】封装窗口工具类【3】控制窗口定向移动

文章目录 引入实现效果思路声明通用的定位对象主进程模块渲染进程测试效果 引入 demo项目地址 窗口工具类系列文章&#xff1a; 封装窗口工具类【1】雏形 封装窗口工具类【2】窗口组&#xff0c;维护窗口关系 封装窗口工具类【3】控制窗口定向移动 很多时候&#xff0c;我们想…

2024 AI 辅助研发的新纪年

随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&#xff0c;AI辅助研发不仅…

【粉丝福利】探秘内部审计数字化之道:精准解析转型方法与成功路径

&#x1f33c;前言 内部审计是一种独立的、客观的确认和咨询活动&#xff0c;包括鉴证、识别和分析问题以及提供管理建议和解决方案。狭义的数字化转型是指将企业经营管理和业务操作的各种行为、状态和结果用数字的形式来记录和存储&#xff0c;据此再对数据进行挖掘、分析和应…

万字详解,Java实现低配版线程池

文章目录 1.什么是线程池2.线程池的优势3.原理4.代码编写4.1 阻塞队列4.2 ThreadPool线程池4.3 Worker工作线程4.4 代码测试 5. 拒绝策略5.1 抽象Reject接口5.2 BlockingQueue新增tryPut方法5.3 修改ThreadPool的execute方法5.4 ThreadPool线程池构造函数修改5.5 拒绝策略实现1…

运输层端口号、复用和分用的概念

运行在计算机上的进程用进程标识符PID来标志&#xff0c;但不同操作系统使用的进程标识符又不一样。 所以为了能让不同计算机上的进程进行网络通信&#xff0c;就需要统一的方式来进行标识&#xff0c;这就是TCP/IP体系的端口号&#xff0c;范围是0~65535&#xff0c;2字节 运…

详解float函数类型转换

函数描述 float([x]) 函数将数字或数字的字符串表示形式转换为与它等效的有符号浮点数。如果参数x是一个字符串&#xff08;十进制表示的数字串&#xff09;&#xff0c;数字前面可以添加符号来表示正数&#xff0c;或负数。符号和数字之间不能出现空格&#xff0c;但是符号前…

【Web前端】Vue核心基础

文章目录 1. Vue简介2. Vue官网使用指南3. 初识Vue3.1 搭建Vue开发环境3.2 HelloWorld案例3.3 el与data的两种写法3.4 MVVM模型3.5 模板语法 4. 数据绑定4.1 v-bind单向数据绑定4.2 v-model双向数据绑定 5. 事件处理5.1 v-on绑定事件5.2 事件修饰符5.3 键盘事件 6. 计算属性6.1…

关于出国留学和考研比较----以本人双非跨考计算机为例

文章目录 中心论点国内就业现状勿让旧认知害了自己那出国留学真的一无是处了吗?1. 藤校仍旧是具有极高价值2. 时间成本低3. 研究生一定比单纯的本科找工作强!4. 很多人说出国读博好,可以无脑入,真是这样吗? 中心论点 如果在选择出国留学还是国内考研的最终核心诉求都是有更好…

【kubernetes】关于k8s集群的污点和容忍,以及k8s集群的故障排查思路

目录 一、污点 关于污点的增删改查 验证污点的作用——NoExecute ​编辑 验证污点的作用——NoSchedule 验证污点的作用——PreferNoSchedule 二、容忍 三、关于cordon 和 drain 四、Pod启动阶段 五、关于pod的五种状态 六、k8s常见的排障手段 针对组件故障 针对pod…

04 Python的面向对象编程

self是一个指针&#xff0c;指向对象xiaoming,可以调用对象里面的属性和方法。 name 和 age是实例变量。 desplay_msg是类变量 xiaoming就是具体的对象&#xff0c;是类的实例化

如何使用apk2url从APK中快速提取IP地址和URL节点

关于apk2url apk2url是一款功能强大的公开资源情报OSINT工具&#xff0c;该工具可以通过对APK文件执行反汇编和反编译&#xff0c;以从中快速提取出IP地址和URL节点&#xff0c;然后将结果过滤并存储到一个.txt输出文件中。 该工具本质上是一个Shell脚本&#xff0c;专为红队…

字节跳动发布SDXL-Lightning模型,支持WebUI与ComfyUI双平台,只需一步生成1024高清大图!

字节跳动发布SDXL-Lightning模型,WebUI与ComfyUI平台,只需一步生成1024高清大图,需要的步数比 LCM 更低了! 什么是SDXL-Lightning: SDXL-Lightning 是一种快速的文本到图像生成模型。SDXL-Lightning模型的核心优势在于其创新的蒸馏策略,它可以通过几个步骤生成高质量的 1…