ARM裸机 - 中断系统之异常向量表

本文介绍了中断的概念,如何通过异常向量表进行中断处理的第一阶段,包括绑定异常处理函数,并详细阐述了中断处理的第三阶段,即判断中断源和执行相应的中断服务程序。重点讲解了S5PV210中断系统的设计和中断处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是中断

中断的发明是用来解决宏观上的并行需要的。宏观就是从整体上来看,并行就是多件事情都完成了。

如:一个人在看电影,快递来了暂停电影跑去收快递,收完快递继续回来看电影,这个例子就是宏观上的并行和微观上的串行。例子中一个人等同于SoC中1个CPU(也就是单核CPU),这个CPU看电影就不能收快递,收快递就不能看电影(也就是说不能真正的并行)。单核心CPU在微观角度是串行的,但是因为CPU很快,所以在宏观看来可以并行。

2.中断处理第一阶段:绑定异常向量表

在CPU设计时,就事先定义了CPU中一些特定地址作为特定异常的入口地址,硬件已经决定了发生什么异常CPU自动跳转PC到哪个地址去执行,软件需要做的就是把处理这个异常的代码的首地址填入这个异常向量地址。

在这里插入图片描述

-> 像内存一样去访问异常向量表

iRAM中的异常向量表起始地址为0xD0037400。知道了异常向量表的起始地址后,各个异常对应的入口就很好知道了。

在这里插入图片描述

-> 函数名的实质就是函数的首地址

函数名就是这个函数的函数指针,编译器会把这个函数的函数体对应的代码段和这个函数的函数名实质是符号)对应起来,函数名实际对应的是函数体那一个代码段的首地址

-> int.h文件进行异常向量表的绑定

#ifndef __INT_H__
#define __INT_H__


#define exception_vector_table_base		0xD0037400        //cpu异常向量表的基地址
#define exception_reset					(exception_vector_table_base + 0x00)
#define exception_undef					(exception_vector_table_base + 0x04)
#define exception_sotf_int				(exception_vector_table_base + 0x08)
#define exception_prefetch				(exception_vector_table_base + 0x0C)
#define exception_data					(exception_vector_table_base + 0x10)
#define exception_irq					(exception_vector_table_base + 0x18)
#define exception_fiq					(exception_vector_table_base + 0x1C)

#define r_exception_reset		(*(volatile unsigned int *)exception_reset)
#define r_exception_undef		(*(volatile unsigned int *)exception_undef)
#define r_exception_sotf_int	(*(volatile unsigned int *)exception_sotf_int)
#define r_exception_prefetch	(*(volatile unsigned int *)exception_prefetch)
#define r_exception_data		(*(volatile unsigned int *)exception_data)
#define r_exception_irq			(*(volatile unsigned int *)exception_irq)
#define r_exception_fiq			(*(volatile unsigned int *)exception_fiq)

-> 异常向量的执行函数int.c:

#include "int.h"
#include "stdio.h"



void system_init_exception(void)
{
	r_exception_reset = (unsigned int)reset_exception;
	r_exception_undef = (unsigned int)undef_exception;
	r_exception_sotf_int = (unsigned int)sotf_int_exception;
	r_exception_prefetch = (unsigned int)prefetch_exception;
	r_exception_data = (unsigned int)data_exception;
	r_exception_irq = (unsigned int)IRQ_handle;
	r_exception_fiq = (unsigned int)IRQ_handle;
	

}

void reset_exception(void)          //复位异常,到此处执行复位的操作,下面的各个函数的功能都类似
{
	printf("reset_exception.\n");
}

void undef_exception(void)
{
	printf("undef_exception.\n");
}

void sotf_int_exception(void)
{
	printf("sotf_int_exception.\n");
}

void prefetch_exception(void)
{
	printf("prefetch_exception.\n");
}

void data_exception(void)
{
	printf("data_exception.\n");
}



// 真正的中断处理程序。意思就是说这里只考虑中断处理,不考虑保护/恢复现场
void irq_handler(void)
{
	//printf("irq_handler.\n");
	// SoC支持很多个(在低端CPU例如2440中有30多个,在210中有100多个)中断
	// 这么多中断irq在第一个阶段走的是一条路,都会进入到irq_handler来
	// 我们在irq_handler中要去区分究竟是哪个中断发生了,然后再去调用该中断
	// 对应的isr。

}

3.中断处理第三阶段:判断具体发生的中断

处理过程:

S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。

当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,我们软件只要去这个寄存器中执行函数就行了。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值