ARM裸机开发-中断

ARM裸机开发:外部中断配置与优化实践 中断处理是嵌入式系统开发的核心机制,尤其在ARM架构裸机环境中,开发者需要直接管理硬件中断资源。外部中断通过GPIO引脚触发,广泛应用于按键检测、传感器信号采集等场景。其实现依赖于NVIC中断控制器、EXTI事件检测器和SYSCFG配置模块的协同工作。理解中断优先级管理、服务例程编写和低功耗唤醒等关键技术,能够提升系统实时性和可靠性。本文以STM32为例,详解外部中断的GPIO配置、EXTI线路映射和NVIC优先级设置流程,并针对中断风暴、响应延迟等典型问题提供解决方案。 阅读详情

以key按键功能为例,对于中断,首先先配置GPIO1_18引脚触发方式与使能引脚中断

    // 配置按键引脚中断触发方式:下降沿触发
    GPIO1->ICR2 |= (3 << 4);      

    // 使能引脚中断
    GPIO1->IMR |= (1 << 18);

然后当按下按键后外设会产生对应的中断号99。(如下图所示,GPIO1组的16-31号引脚都为99,当产生中断号后,要查看具体引脚可通过GPIO的ISR状态寄存器查看)

产生中断号后,不仅在外设中保存,也会传给GIC控制器,在GIC中,将中断号写入IAR寄存器,再完成对应的工作之后,会通过上图的四条线路中的任意一条将中断送给ARM内核,ARM内核读取该寄存器里的中断号,确定是哪个外设引发的中断,执行中断处理函数,结束后将中断号写入EOIR寄存器,告诉GIC中断处理结束,同时外设的ISR寄存器也要记得清零。

一些细节:

首先在_reset_handler:函数中设置irq模式的中断开启,将bit7置0,

    bic r0, r0, #(1 << 7)   // irq

其次,初始化GIC

void system_interrupt_init(void)
{
    // 初始化GIC控制器
    GIC_Init(); 
}

同时,打开GIC中断

// 使能GIC中断
GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);

然后,要找到GIC中的IAR寄存器,参考下图,当知道GIC的基地址之后,加上偏移量即可得到寄存器地址,而要找到GIC基地址,则应借助coprocessor协处理器,在Cortex-A7内部,用于协助CPU完成特定任务,在内核中有cp0-cp15一共16个协处理器,功能各不相同,平时cp15使用最多,GIC的基地址也在此处。

而cp15协处理器有c0-c15一共16个寄存器组,下图以c0寄存器组的MIDR寄存器为例

分别表示ARM架构(相当于写死),内核主版本号,汇编指令集版本号,处理器型号,主版本号

而本次中断要配置的有c1中的SCTLR寄存器

将V位置0,表示可以通过VBAR寄存器更改启动代码的默认起始地址,置1则表示,起始地址为0XFFFF 0000,且不能再被重映射。在上文链接时更改了链接的起始地址为0x8780 0000,此时,由于系统默认只会从0x00地址处开始执行异常处理函数,当产生异常时,再去原先的地址则找不到异常函数,此时应进行重映射

默认从0x00处开始,而由于此时起始地址已经变为0x8780 0000,故应进行重映射,而SCTLR寄存器就是负责此功能

要操作协处理器的寄存器数据,引入以下两条指令:

mrc:读取cp15中寄存器的数据到通用寄存器

mcr:将通用寄存器中的数据写入到cp15中寄存器

使用格式:

mrc <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>对照参考手册即可,例如:

mrc p15,0,r0,c1,c0,0意思为将cp15中SCTLR寄存器值读到R0寄存器

此外12位应置1,表示将icache打开,指令处理速率变快(dcache尽量关闭,每次操作数据,若将数据放在dcache,则会忽略对寄存器本身的读取,不利于学习)

_enable_icache:
    mrc p15, 0, r0, c1, c0, 0   
    bic r0, r0, #(1 << 13)  //将cp15中SCTLR寄存器值读到R0寄存器
    orr r0, r0, #(1 << 12)
    mcr p15, 0, r0, c1, c0, 0
    bx lr

此时只是将SCTLR配置了,此外还应配置VBAR寄存器,在c12组里

_set_vbar:
    ldr r0, =0x87800000
    mcr p15, 0, r0, c12, c0, 0
    bx lr

最后在c15里的CBAR寄存器,可以读出GIC的基地址,不过可以通过Cortex-A7的固件库实现,即初始化GIC函数

inline:内联函数,本质是函数,调用内联函数前,必须有该函数的定义,编译时,内联函数会在函数调用位置被展开,类似宏,就地展开,不用跳转函数,提高函数执行效率,可在头文件中定义函数。

irq中断异常处理:

_irq_handler:
    subs lr, lr, #4    //返回地址偏移量加了4,所以先减4

    // GIC 基地址
    mrc p15, 4, r1, c15, c0, 0    //读c15的CBAR寄存器里的基地址
    add r1, r1, #0x2000    //基地址+偏移量
    ldr r0, [r1, #0x0C]    //r1再加到IAR寄存器的偏移量,将IAR里面的中断号放到r0

    stmfd sp!, {r0-r12, lr}
    stmfd sp!, {r0, r1}    //中断号还要写到EOIR,所以单独保护
	bl system_interrupt_handler //汇编调用c函数,参数小于4个时,通过r0-r3传值,所以r0的值就是中断号
    ldmfd sp!, {r0, r1}
    // 清除GIC中断标记位
    str r0, [r1, #0x10]             
    ldmfd sp!, {r0-r12, pc}^

void system_interrupt_handler(int num) 
{
    if (num == GPIO1_Combined_16_31_IRQn)
    {
        if ((GPIO1->ISR & (1 << 18)) != 0)
        {
            led_nor();
        }
        GPIO1->ISR |= (1 << 18);
    }
}

最后可创建一个interrupt的.c文件,用于存放中断相关函数

typedef void (*irq_handler_t)(void);         // 函数指针类型
irq_handler_t interrupt_vector_table[160];   // 函数地址

void system_interrupt_init(void)
{
    // 初始化GIC控制器
    GIC_Init(); 
}

void system_interrupt_register(int num, irq_handler_t handler)
{
    interrupt_vector_table[num] = handler;
}

void system_interrupt_handler(int num) 
{
    if (interrupt_vector_table[num] != NULL)
    {
        interrupt_vector_table[num]();   
    }
}

在key.c中

void key_interrupt_handler(void)
{
    if ((GPIO1->ISR & (1 << 18)) != 0) 
    {
        led_nor();
        beep_nor();
    }
    GPIO1->ISR |= (1 << 18);
}    
void key_init(void)
{
    // 引脚复用功能
    IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
    // 引脚电气属性
    IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF0B0);
    // 按键引脚初始化
    GPIO_Type_t t = 
    {
        .direction = gpio_input
    };
    gpio_init(GPIO1, 18, &t);

    // 配置按键引脚中断触发方式:下降沿触发
    GPIO1->ICR2 |= (3 << 4);      

    // 使能引脚中断
    GPIO1->IMR |= (1 << 18);

    // 注册按键中断
    system_interrupt_register(GPIO1_Combined_16_31_IRQn, key_interrupt_handler); 
    // 设置按键中断优先级
    GIC_SetPriority(GPIO1_Combined_16_31_IRQn, 0);

    // GIC使能按键中断
    GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);
}

ARM裸机程序开发——中断系统 ★中断控制机制 CPU在运行过程中,怎样知道外部设备需要进行一些事件的处理呢?比如在一个按键程序设计中,按下某个按键,蜂鸣器会发出响声。当按下按键的时候,CPU怎样知道按键已经被按下,并且调用相应的蜂鸣器处理函数呢?在这里有两种方式,一种是轮询,另一种是中断。 ◇轮询 轮询就是让CPU不同的循环检测有没有按键被按下,如果检测到按键被按下了,就马上指 阅读详情

相关推荐

ARM裸机程序开发:中断系统在ARM开发中的应用

在这个例子中,我们将USART1中断的优先级设置为1,将USART2中断的优先级设置为2。的中断处理程序,用于处理外部中断0的事件。在中断处理程序中,我们可以添加相应的代码来处理中断事件,例如更新状态、执行特定操作等。在处理完中断事件后,我们需要清除中断标志位,以便能够再次触发相同的中断。请注意,以上示例代码是基于STM32F4系列的ARM微控制器进行的演示,实际的ARM开发可能涉及不同的硬件平台和开发工具链,因此具体的实现方式可能会有所差异。以下是一个简单的示例代码,演示如何配置中断的优先级和中断嵌套。

LklAngular的博客 140

ARM裸机开发:输入中断

ARM裸机开发:输入中断

嵌入式学习记录站点 2084

ARM裸机开发实战:ADS1.2下从汇编启动到GPIO中断全流程

裸机开发是嵌入式系统底层能力的基石,其核心在于理解CPU复位流程、异常向量机制与寄存器级外设控制原理。掌握ARM汇编启动代码编写、栈模式切换及向量表重定位,可构建稳定可靠的最小执行环境;结合ADS 1.2等经典工具链完成编译、链接与联合仿真,能有效规避环境配置陷阱并实现硬件行为可观测。该技术路径广泛应用于教学实验、Bootloader开发、MCU固件验证及嵌入式系统设计师认证备考场景,尤其适配ARM926EJ-S等无MMU处理器平台。本文聚焦ADS 1.2环境下startup.s汇编初始化与AXU15EGP

weixin_29171087的博客 256

ARM裸机开发:key、中断、代码封装(满足OCP原则)

3.中断状态寄存器:GPIO->ISR,判断GPIO1的第18个bit是否为1,(与1 <<18 )相与不等于0则进行中断处理。0.DMA:直接内存访问,全部连接在外设上,128个(可使用)+内部自己使用的中断号(32),则ARMV7总共有160。3.此设备(IM6ULL)中断(1个内核):32-159外设可使用中断(参考函数库)①SGI:0-15(软中断),PPI:16-31(私人外设中断)置1表示清0,(区分16-31)中哪一个。1.SGI:0-15(软中断),PPI:16-31(私人外设中断)

2501_91498265的博客 1200

【C++】lambda表达式

本篇文章我们要学习的是lambda表达式,它是C++11新增的一种特别方便的语法,相较于之前的函数指针以及仿函数都方便了不少,下面就让我们一起来学习吧。

malloc不出对象的博客 2630

PR控制以及使用PR控制用于单相离/并网逆变器

最近想学习一下并网逆变器,需要用到PR控制,全网找遍了许多学习资料,终于掌握的差不多了,在此做个记录,以及个人对PR(Proportional Resonant)控制的理解。在去年7月准备电赛的时候偶然看到有几篇讲解数字滤波器,第一次接触传递函数离散化,深刻被数字时代的数字方式折服,改改代码,就可以实现不同的截至频率,甚至不同阶数,而模拟方式还要改元器件。当时就感觉这玩意太他妈牛逼了,很想学懂它,奈何学不会呀。后面全身心做电赛,就忘了这事儿。直至最近学习PR控制,当初的感觉又回来了,一股劲儿吃下来了。

xht2403267701的博客 3万+

ARM裸机开发:中断系统

ARM裸机开发:中断系统

嵌入式学习记录站点 2241

STM32无线遥控小车的设计

基于SPI通信的无线摇杆小车的设计

weixin_69414084的博客 2928

ARM Cortex-A7(IMX6ULL)嵌入式裸机开发指南:从点灯到中断

本文详细介绍了基于IMX6ULL处理器的嵌入式裸机开发全流程。主要内容包括:1)C语言点灯实现,重点讲解volatile关键字、寄存器操作及结构体封装;2)工程规范化管理,涉及SDK引入、BSP工程构建和链接脚本编写;3)中断系统实现,从轮询方式到事件驱动,详细解析GIC中断控制器配置及中断处理框架设计。通过实践案例展示了寄存器操作、Makefile使用等核心开发技能,为嵌入式开发者提供了完整的裸机开发指南。

YangXY66的博客 1216

保姆级避坑指南:用Keil和J-Flash搞定凌思微LE5010蓝牙芯片的首次程序下载

本文提供了一份详细的保姆级避坑指南,帮助开发者使用Keil和J-Flash工具完成凌思微LE5010蓝牙芯片的首次程序下载。文章重点解决了算法文件混淆、协议栈漏烧和仿真器连接异常等常见问题,并详细介绍了开发环境配置、协议栈烧录和下载接口的物理层奥秘,助力开发者高效完成蓝牙开发任务。

weixin_28739079的博客 467

3D Slicer中安装MedSAM插件

大家应该都读过这篇论文:《Segment Anything in Medical Images》这个插件便是该论文团队推出的在3D Slicer上使用的插件,可以分割医学图像的任何感兴趣区域。

m0_73719342的博客 2330

ARM 裸机开发学习笔记(5)中断体系结构

ARM 裸机开发学习笔记(5)中断体系结构 ARM体系CPU一共有7种工作模式,分别为:用户模式,快速中断模式,中断模式,管理模式,数据访问终止模式,系统模式,未定义指令中止模式。 可以通过软件来进行模式切换,或者发生各类中断,异常时CPU自动进入相应的模式。除用户模式外,其余的6中工作模式都属于特权模式。大多数程序运行于用户模式,进入特权模式是为了处理中断,异常,或者访问被保护的系统资源。 1. 异常事件处理方式 CPU运行过程中,是如何知道外设发生了某些事件,如按键,触摸屏,与外设数据的交互。 有两

qq_38037674的博客 321

使用FPGA实现MIPI DSI接口

通过使用FPGA,我们可以实现MIPI DSI接口,并在FPGA上生成相应的时序和电平转换电路。通过使用FPGA,我们可以实现MIPI DSI接口,并在FPGA上生成相应的时序和电平转换电路。在本文中,我们将探讨如何使用FPGA实现MIPI DSI接口,并提供相应的源代码。根据不同的发送状态,我们设置相应的输出信号。请注意,这只是一个基本的示例,用于说明如何使用FPGA实现MIPI DSI接口的发送功能。请注意,这只是一个基本的示例,用于说明如何使用FPGA实现MIPI DSI接口的发送功能。

ZdqDeveloper的博客 1700

ARM裸机开发(二)中断编程

       以下裸机程序基于GT2440,编译器为arm-linux-gcc-4.4.3。      程序布局:源代码由interrupt.S和led.c两个文件组成,interrupt负责初始化工作,led.c里定义了中断处理程序。      程序流程:首先安装异常向量表,在复位异常里关闭看门狗,然后进入普通中断模式,设置普通中断的栈指针(为C语言写的中断处理程序做准备),接着设为特权模式...

weixin_34224941的博客 193

ADS电路仿真方法综述:原理与应用

在射频与微波电路设计中,精确的仿真技术是验证性能的关键。ADS(Advanced Design System)作为行业标准工具,集成了多种仿真方法,适用于不同场景。本文将系统解析瞬态分析、谐波平衡(HB)、交流分析(AC)、直流分析(DC)、S参数、大信号SP(LSSP)及包络分析的原理、实现机制与应用场景。

u014344410的博客 481

Vue3 - 详细实现微信公众号H5网页内置浏览器中预览下载word文档(doc)、excel表格(xls)、ppt文稿、pdf文档等文件,微信内部直接打开预览和下载到本地教程,安卓苹果手机无差异兼容

vue3,nuxt3,微信公众号,h5,移动端,网页,网站,vue微信内置浏览器下载文件,下载文件,在微信浏览器里面实现下载任意文件,H5需要在微信浏览器中下载excel文件,实现网页在微信内置浏览器中下载文件详细教程,安卓点击下载会提示打开浏览器,后端返回流文件,如何解决无法下载文件,跳转至浏览器下载文件,发送到电脑微信,安卓,苹果,手机系统,微信H5页面,vue3微信公众号H5网站,内置浏览器下载文档,如何在微信浏览器中预览office文件,word文档,excel文档,pdf文档,ppt文档,offi

🏆 前端领域优质创作者 1万+

【ARM 裸机开发 (IMX6ULL-mini)】中断篇:代码解耦|GIC 控制器、GPIO 外部按键中断实现

本文基于 IMX6ULL-mini 开发板继续 ARM 裸机开发,遵循高内聚低耦合思想,封装通用 GPIO 驱动,实现按键 GPIO 输入读取。对比 51 单片机中断,讲解 Cortex‑A7 的 GIC V2 通用中断控制器,介绍 SPI/PPI/SGI 三类中断。阐述 CP15 协处理器、SCTLR/VBAR/CBAR 寄存器作用,完成向量表重定向。从 GPIO 中断寄存器配置、GIC 初始化、汇编异常入口到 C 语言中断服务函数,完整实现按键外部中断,讲解裸机 IRQ 中断整套开发流程。

2403_89702754的博客 533

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

ARM嵌入式裸机开发:中断与RTC模块的寄存器级编程实战

中断机制是嵌入式系统实现实时响应的核心技术,它允许CPU在处理主任务时,能够被外部紧急事件打断并优先处理。其原理是通过硬件信号触发,由中断控制器进行优先级仲裁,最终引导CPU跳转到预设的中断服务程序执行。这项技术的核心价值在于避免了低效的轮询,极大提升了系统响应效率与资源利用率,广泛应用于工业控制、消费电子等对时序和功耗有严格要求的场景。本文以Freescale i.MX系列ARM处理器为例,深入剖析了通过直接操作CPSR寄存器、中断控制器及RTC模块寄存器来实现精准中断响应与定时功能的底层逻辑,涵盖了从*

weixin_29159127的博客 247

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IMX6ULL裸机开发|ARM启动、中断与时钟系统学习笔记

ARM Cortex-A7裸机启动代码完成七项核心任务:设置异常向量表并重映射至0x87800000,为各工作模式配置栈,使能IRQ中断,清零BSS段,开启I-Cache,最终跳转至C语言main函数。IMX6ULL时钟系统基于24MHz晶振,通过PLL倍频、Prescaler分频、PFD灵活调频,实现内核528MHz主频,并配置AHB(132MHz)、PERCLK(66MHz)、IPG(66MHz)三路根时钟。采用GICV2中断控制器管理160个中断源,实现高效中断处理。

2502_90211789的博客 320

硬件开发2-ARM裸机开发3-IMX6ULL - 引入中断

摘要:本文介绍了通过按键控制LED和蜂鸣器的实现过程,分析了轮询模式的响应延迟问题,提出引入中断机制以提高响应速度。详细阐述了中断的概念、流程及GIC中断控制器的功能,包括SGI、PPI、SPI三种中断类型。同时介绍了协处理器CP15在访问GIC寄存器时的关键作用,以及异常向量表的配置方法。最后给出了中断模式的具体代码实现方案(interrupt.c、interrupt.h、start.S),解决了轮询模式下的响应延迟问题。

DebugKitty的博客 872

ARM裸机开发自学笔记:IMX6ULL 中断系统与按键中断实战

在嵌入式学习中,中断是极其重要的一环,它让CPU摆脱了低效的轮询(Polling)模式。最近在自学 ARM Cortex-A7(IMX6ULL)的裸机开发,通过理论结合代码,彻底理清了从外设触发中断到内核处理完毕的整个流程。本篇博客将梳理 GIC(通用中断控制器)的理论知识,并通过编写按键中断的代码,记录自己的学习心得。一、 核心理论知识梳理根据学习资料,现代 ARM 架构(如 Cortex-A7)的中断管理比传统的 51 单片机要复杂得多。51单片机通常是“外设 -> 内核”,而 IMX6ULL 引入了

2602_96624055的博客 381

从51到ARM裸机开发实验(009)LPC2138 中断实验

LPC2138 中断实验

ThinkCockpit的博客 1657

ARM裸机开发全教程|从0基础点灯到中断与BSP架构进阶(超详细学习路线)

arm

ouynagda的博客 251

ARM裸机开发22(2440中断原理)

1CPU与外设之间的数据传送控制方式(I/O控制方式) 通常有以下三种方式 1.查询方式 2.中断方式 3.DMA方式(在独立开辟的一个空间不由CPU控制,有DMA自己进行管理。实现存储器与外设的高速的数据传输方式) 主要讲中断: 中断请求---->中断仲裁---->中断响应---->中断处理---->中断返回(要保存现场) 中断处理流程: 1.中断控制器捕获当前外

道法自然 1263

【ARM 裸机开发 (IMX6ULL-mini)】中断嵌套实现、代码 OCP 改造与时钟配置

本文基于 IMX6ULL-mini 平台开展 ARM 裸机开发,针对 IRQ 模式无法中断嵌套的问题,借助 ARMv6 的 CPS 汇编指令切换处理器工作模式,实现高优先级中断抢占;结合 GIC V2 中断控制器,讲解中断抢占与子优先级配置方法。引入 OCP 开闭原则,利用函数指针数组重构中断管理代码,新增外设中断无需修改核心处理逻辑,完成代码解耦。最后介绍 IMX6ULL 时钟系统,讲解晶振、PLL、PFD 原理,分步完成 ARM 内核及总线根时钟的寄存器配置,为后续外设驱动开发打下基础。

2403_89702754的博客 432
上一篇: ARM裸机开发-蜂鸣器与按键
下一篇: ARM裸机开发-时钟
剑指offer.
博客等级 码龄3年 15粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值