ARM裸机 - 中断处理编程实战_arm断电文件内容丢失

这篇具有很好参考价值的文章主要介绍了ARM裸机 - 中断处理编程实战_arm断电文件内容丢失。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#define exception_vector_table_base 0xD0037400
#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)

// 中断源编号
#define INT_LIMIT (96)

//INT NUM - VIC0
#define NUM_EINT0 (0)
#define NUM_EINT1 (1)
#define NUM_EINT2 (2)
#define NUM_EINT3 (3)
#define NUM_EINT4 (4)
#define NUM_EINT5 (5)
#define NUM_EINT6 (6)
#define NUM_EINT7 (7)
#define NUM_EINT8 (8)
#define NUM_EINT9 (9)
#define NUM_EINT10 (10)
#define NUM_EINT11 (11)
#define NUM_EINT12 (12)
#define NUM_EINT13 (13)
#define NUM_EINT14 (14)
#define NUM_EINT15 (15)
#define NUM_EINT16_31 (16)
#define NUM_Reserved17 (17)
#define NUM_MDMA (18)
#define NUM_PDMA0 (19)
#define NUM_PDMA1 (20)
#define NUM_TIMER0 (21)
#define NUM_TIMER1 (22)
#define NUM_TIMER2 (23)
#define NUM_TIMER3 (24)
#define NUM_TIMER4 (25)
#define NUM_SYSTIMER (26)
#define NUM_WDT (27)
#define NUM_RTC_ALARM (28)
#define NUM_RTC_TICK (29)
#define NUM_GPIOINT (30)
#define NUM_FIMC3 (31)

//INT NUM - VIC1
#define NUM_CORTEX0 (32+0)
#define NUM_CORTEX1 (32+1)
#define NUM_CORTEX2 (32+2)
#define NUM_CORTEX3 (32+3)
#define NUM_CORTEX4 (32+4)
#define NUM_IEM_APC (32+5)
#define NUM_IEM_IEC (32+6)
#define NUM_Reserved39 (32+7)
#define NUM_NFC (32+8)
#define NUM_CFC (32+9)
#define NUM_UART0 (32+10)
#define NUM_UART1 (32+11)
#define NUM_UART2 (32+12)
#define NUM_UART3 (32+13)
#define NUM_I2C (32+14)
#define NUM_SPI0 (32+15)
#define NUM_SPI1 (32+16)
#define NUM_SPI2 (32+17)
#define NUM_AUDIO (32+18)
#define NUM_I2C_PMIC (32+19)
#define NUM_I2C_HDMI (32+20)
#define NUM_HSIRX (32+21)
#define NUM_HSITX (32+22)
#define NUM_UHOST (32+23)
#define NUM_OTG (32+24)
#define NUM_MSM (32+25)
#define NUM_HSMMC0 (32+26)
#define NUM_HSMMC1 (32+27)
#define NUM_HSMMC2 (32+28)
#define NUM_MIPI_CSI (32+29)
#define NUM_MIPI_DSI (32+30)
#define NUM_ONENAND_AUDI (32+31)

//INT NUM - VIC2
#define NUM_LCD0 (64+0)
#define NUM_LCD1 (64+1)
#define NUM_LCD2 (64+2)
#define NUM_LCD3 (64+3)
#define NUM_ROTATOR (64+4)
#define NUM_FIMC_A (64+5)
#define NUM_FIMC_B (64+6)
#define NUM_FIMC_C (64+7)
#define NUM_JPEG (64+8)
#define NUM_2D (64+9)
#define NUM_3D (64+10)
#define NUM_MIXER (64+11)
#define NUM_HDMI (64+12)
#define NUM_HDMI_I2C (64+13)
#define NUM_MFC (64+14)
#define NUM_TVENC (64+15)
#define NUM_I2S0 (64+16)
#define NUM_I2S1 (64+17)
#define NUM_I2S2 (64+18)
#define NUM_AC97 (64+19)
#define NUM_PCM0 (64+20)
#define NUM_PCM1 (64+21)
#define NUM_SPDIF (64+22)
#define NUM_ADC (64+23)
#define NUM_PENDN (64+24)
#define NUM_KEYPAD (64+25)
#define NUM_Reserved90 (64+26)
#define NUM_HASH (64+27)
#define NUM_FEEDCTRL (64+28)
#define NUM_PCM2 (64+29)
#define NUM_SDM_IRQ (64+30)
#define NUM_SMD_FIQ (64+31)

//INT NUM - VIC3
#define NUM_IPC (96+0)
#define NUM_HOSTIF (96+1)
#define NUM_HSMMC3 (96+2)
#define NUM_CEC (96+3)
#define NUM_TSI (96+4)
#define NUM_MDNIE0 (96+5)
#define NUM_MDNIE1 (96+6)
#define NUM_MDNIE2 (96+7)
#define NUM_MDNIE3 (96+8)
#define NUM_ADC1 (96+9)
#define NUM_PENDN1 (96+10)
#define NUM_ALL (200)

#endif



**-> 中断控制器初始化,绑定异常向量表到异常处理程序**



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”);
}

// 主要功能:绑定第一阶段异常向量表;禁止所有中断;选择所有中断类型为IRQ;
// 清除VICnADDR为0
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;

// 初始化中断控制器的基本寄存器
intc_init();

}



**-> intc\_init()的函数展开(禁止所有中断源;选择所有中断类型为IRQ;清理VICnADDR寄存器为0)**



// 清除需要处理的中断的中断处理函数的地址
void intc_clearvectaddr(void)
{
// VICxADDR:当前正在处理的中断的中断处理函数的地址
VIC0ADDR = 0;
VIC1ADDR = 0;
VIC2ADDR = 0;
VIC3ADDR = 0;
}

// 初始化中断控制器
void intc_init(void)
{
// 禁止所有中断
// 为什么在中断初始化之初要禁止所有中断?
// 因为中断一旦打开,因为外部或者硬件自己的原因产生中断后一定就会寻找isr
// 而我们可能认为自己用不到这个中断就没有提供isr,这时它自动拿到的就是乱码
// 则程序很可能跑飞,所以不用的中断一定要关掉。
// 一般的做法是先全部关掉,然后再逐一打开自己感兴趣的中断。一旦打开就必须
// 给这个中断提供相应的isr并绑定好。
VIC0INTENCLEAR = 0xffffffff;
VIC1INTENCLEAR = 0xffffffff;
VIC2INTENCLEAR = 0xffffffff;
VIC3INTENCLEAR = 0xffffffff;

// 选择中断类型为IRQ
VIC0INTSELECT = 0x0;
VIC1INTSELECT = 0x0;
VIC2INTSELECT = 0x0;
VIC3INTSELECT = 0x0;

// 清VICxADDR
intc_clearvectaddr();

}



**-> 中断的使能与禁止**


思路是先根据中断号判断这个**中断属于VIC几**,然后在用中断源减去这个**VIC的偏移量**,得到这个中断号在**本VIC中**的偏移量,然后1<<x位,写入相应的VIC的INTENABLE/INTENCLEAR寄存器即可。



// 使能中断
// 通过传参的intnum来使能某个具体的中断源,中断号在int.h中定义,是物理中断号
void intc_enable(unsigned long intnum)
{
unsigned long temp;
// 确定intnum在哪个寄存器的哪一位
// <32就是0~31,必然在VIC0
if(intnum<32)
{
temp = VIC0INTENABLE;
temp |= (1<<intnum); // 如果是第一种设计则必须位操作,第二种设计可以
// 直接写。
VIC0INTENABLE = temp;
}
else if(intnum<64)
{
temp = VIC1INTENABLE;
temp |= (1<<(intnum-32));
VIC1INTENABLE = temp;
}
else if(intnum<96)
{
temp = VIC2INTENABLE;
temp |= (1<<(intnum-64));
VIC2INTENABLE = temp;
}
else if(intnum<NUM_ALL)
{
temp = VIC3INTENABLE;
temp |= (1<<(intnum-96));
VIC3INTENABLE = temp;
}
// NUM_ALL : enable all interrupt
else
{
VIC0INTENABLE = 0xFFFFFFFF;
VIC1INTENABLE = 0xFFFFFFFF;
VIC2INTENABLE = 0xFFFFFFFF;
VIC3INTENABLE = 0xFFFFFFFF;
}

}

// 禁止中断
// 通过传参的intnum来禁止某个具体的中断源,中断号在int.h中定义,是物理中断号
void intc_disable(unsigned long intnum)
{
unsigned long temp;

if(intnum<32)
{
    temp = VIC0INTENCLEAR;
    temp |= (1<<intnum);
    VIC0INTENCLEAR = temp;
}
else if(intnum<64)
{
    temp = VIC1INTENCLEAR;
    temp |= (1<<(intnum-32));
    VIC1INTENCLEAR = temp;
}
else if(intnum<96)
{
    temp = VIC2INTENCLEAR;
    temp |= (1<<(intnum-64));
    VIC2INTENCLEAR = temp;
}
else if(intnum<NUM_ALL)
{
    temp = VIC3INTENCLEAR;
    temp |= (1<<(intnum-96));
    VIC3INTENCLEAR = temp;
}
// NUM_ALL : disable all interrupt
else
{
    VIC0INTENCLEAR = 0xFFFFFFFF;
    VIC1INTENCLEAR = 0xFFFFFFFF;
    VIC2INTENCLEAR = 0xFFFFFFFF;
    VIC3INTENCLEAR = 0xFFFFFFFF;
}

return;

}



**-> 绑定自己实现的isr到VICnVECTADDR**


搞清楚2个寄存器的区别:VICnVECTADDR和VICnADDR.


VICVECTADDR寄存器一共有4×32个,每个中断源都有一个VECTADDR寄存器,我们应该将自己为这个中断源写**的isr地址**丢到这个中断源对应的VECTADDR寄存器中即可。



// 绑定我们写的isr到VICnVECTADDR寄存器
// 绑定过之后我们就把isr地址交给硬件了,剩下的我们不用管了,硬件自己会处理
// 等发生相应中断的时候,我们直接到相应的VICnADDR中去取isr地址即可。
// 参数:intnum是int.h定义的物理中断号,handler是函数指针,就是我们写的isr

// VIC0VECTADDR定义为VIC0VECTADDR0寄存器的地址,就相当于是VIC0VECTADDR0~31这个
// 数组(这个数组就是一个函数指针数组)的首地址,然后具体计算每一个中断的时候
// 只需要首地址+偏移量即可。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

[外链图片转存中…(img-9QyweP1b-1712230268993)]

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

ARM裸机 - 中断处理编程实战_arm断电文件内容丢失,程序员,嵌入式

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

更多资料点击此处获qu!!文章来源地址https://www.toymoban.com/news/detail-852811.html

到了这里,关于ARM裸机 - 中断处理编程实战_arm断电文件内容丢失的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【理解ARM架构】中断处理 | CPU模式

    🐱作者:一只大喵咪1201 🐱专栏:《理解ARM架构》 🔥格言: 你只管努力,剩下的交给时间! 如上图,在上篇文章中本喵主要介绍的是右侧框中的异常,这里开始介绍一下左边框里的中断,中断主要由三部分组成: 中断源: 中断源多种多样,比如GPIO、定时器、UART、DMA等等

    2024年02月05日
    浏览(37)
  • ARM单片机中断处理过程解析

    前言 中断,在单片机开发中再常见不过了。当然对于中断的原理和执行流程都了然于胸,那么对于ARM单片机中断的具体处理行为,你真的搞清楚了吗? 今天来简单聊一聊,ARM单片机中断处理过程中的具体行为是什么样的,搞清楚了这些,让你彻底理解中断是如何执行的。 掌

    2024年02月06日
    浏览(33)
  • ARM实验6-基于中断的按键处理程序实验

    一、实验名称:基于中断的按键处理程序实验 二、实验目的:         1.掌握ARM处理器的中断处理过程。         2.掌握ARM处理器中断服务程序的编写方法。         3.通过该编程实验,进一步巩固和强化学生ARM汇编编程的能,ARM应用程序框架,培养学生实际应用的

    2024年02月08日
    浏览(31)
  • 【ARM】-数据访问中止异常中断处理程序的返回

    当发生数据访问中止异常中断时,程序要返回到该有问题的数据指令处,重新访问该数据。因此数据访问中止异常中断程序应该返回到该数据访问中止异常中断的指令处,而不是像前面两种情况下返回到发生中断的指令的下一条指令。 数据访问中止异常中断是由数据访问指令

    2024年02月12日
    浏览(44)
  • ARM处理器有哪些工作模式和寄存器?各寄存器作用是什么?ARM异常中断处理流程?

    快速学习嵌入式开发其他基础知识? 返回专栏总目录 《嵌入式工程师自我修养/C语言》 Tip📌:鼠标悬停双虚线/句,可获得更详细的描述   ARM处理器有多种工作模式,如下表所示。应用程序正常运行时,ARM处理器工作在 用户模式(User mode) ,当程序运行出错或有中

    2024年02月21日
    浏览(42)
  • [ARM 汇编]进阶篇—异常处理与中断—2.4.1 异常处理概念

    异常处理简介 在ARM汇编开发中,异常处理和中断是常见的概念,它们是对系统运行过程中出现的特殊情况进行处理的一种机制。异常处理和中断包括硬件异常、软件异常和外部中断等。当处理器遇到这些特殊情况时,它会自动执行相应的处理程序。 异常和中断的分类 复位(

    2024年02月09日
    浏览(40)
  • 【ARM】-IRQ 和 FIQ 异常中断处理程序的返回

    通常处理器执行完当前指令后,查询 IRQ 中断引脚及 FIQ 中断引脚,并且查看系统是否允许 IRQ 中断及 FIQ中断。 如果有中断引脚有效,并且系统允许该中断产生,处理器将产生 IRQ 异常中断或 FIQ 异常中断。 当 IRQ 和 FIQ 异常中断产生时, 程序计数器 PC 的值已经更新 ,它指向

    2024年02月08日
    浏览(20)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第二天-ARM中断、定时器、看门狗(物联技术666)

    链接:https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd=1688 提取码:1688 上午:中断           吕峰老师 下午:定时器 教学内容: 一、中断 ARM 中断分为二级,分为一级中断和二级中断,二级中断为子中断,对于 ARM 来说有 50 个中断源, 其中有 32+ ( EINT23-4 ) 23-4+1-2=50 子中断源

    2024年02月19日
    浏览(42)
  • ARM裸机开发-串口通信

    一、在使用EXYNOS4412的串口发送和接收的时候,首先要对EXYNOS4412的串口进行配置,我们使用轮询方式时的配置有哪些? 1、配置GPIO,使对应管脚作为串口的发送和接收管脚   GPA0CON寄存器[7:4][3:0] 0x22    GPA0PUD寄存器[3:0] 0 禁止上下拉电阻 2、配置串口单元本身寄存器    

    2024年02月11日
    浏览(33)
  • ARM裸机-3

            主流的单片机平台:51、PIC、STM32、AVR、MSP430等         主流的嵌入式平台:ARM、PPC、MIPS         单片机片上资源有限、价格低、应用领域多为小家电、终端设备等。         嵌入式系统片上资源丰富、价格较高、应用领域宽广,例如智能手机、平板电脑、游戏机

    2024年02月15日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包