正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结

文章目录

前言

一、文件分析

        start.S文件:

        Core_ca7.h文件:

        MCIMX6Y2.h文件:

        bsp_gpio.h文件:

        bsp_gpio.c文件:

        bsp_int.h文件:

        bsp_int.c文件:

        Exit文件夹:

二、代码实现流程:

总结

前言

最近在学习正点原子I.MX6ULL开发板的外部中断实验,此章实验增加了许多新的内容,包括中断向量表、GIC的控制函数等,GPIO的配置中还增加了中断的相关配置。在第一次学习完后对一些函数的实现和函数之间的调用思路不是很清晰,对一些函数指针、结构体数组等定义不是太理解,特写此文来梳理思路。

一、文件分析

start.S文件:

1:首先定义中断向量表

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第1张图片

2:I.MX6ULL复位后,在汇编文件会进入复位中断,通过修改SCTLR寄存器来关闭I、D Cache和MMU。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第2张图片

 SCTLR寄存器相关位

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第3张图片

 正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第4张图片

3:修改CPSR寄存器的低五位进入不同的运行模式,进入不同运行模式后修改对应模式的sp指针。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第5张图片

 正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第6张图片

4:基本配置完成后就跳转到C语言的main函数

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第7张图片

5:IRQ_Handler的实现,中断发生后首先将spsrlr等寄存器值进行压栈操作,然后跳转到system_irqhandler

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第8张图片

 正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第9张图片

 6:中断服务函数执行完中断后恢复现场

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第10张图片

 
Core_ca7.h文件:

左盟主移植的Cortex-A7关于GIC的一些操作函数和寄存器相关宏的定义、C语言内嵌汇编、GIC的分发器端和cpu接口端的寄存器结构体等。在后面中断初始化的时候会用到GIC_Init()(被bsp_int.c中的interr_init(void)调用), GIC_EnableIRQ(IRQn_Type IRQn)(被bsp_exti.c中的exit_init(void)调用)。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第11张图片

 正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第12张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第13张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第14张图片

MCIMX6Y2.h文件:

IRQn枚举类型定义了IRQ中断下所有的中断ID号

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第15张图片

bsp_gpio.h文件:

增加了中断触发类型枚举,GPIO配置结构体增加了中断触发方式(gpio_interrupt_mode_t) 在_gpio_pin_config中添加了中断触发方式interruptMode

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第16张图片

注意:enum _gpio_interrupt_mode 定义的量并不是传入ICR寄存器而是后面switch case语句中的变量

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第17张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第18张图片

bsp_gpio.c文件:

添加了中断配置函数,并修改了gpio_init()函数,增加了中断配置;增加了中断使能、失能、清除中断标志位函数。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第19张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第20张图片

新增gpio_intconfig()gpio_init()函数

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第21张图片

bsp_int.h文件:

定义了通用中断服务函数格式,中断处理函数结构体(包括指向中断服务函数的指针,用户参数)

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第22张图片

bsp_int.c文件:

包含通用中断的模板、中断处理函数的实现、注册中断处理函数

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第23张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第24张图片

Exit文件夹

包含外部中断的初始化和服务函数,结构就类似于stm32,调用了Core_ca7.h里面的一些GIC函数、bsp_int的注册中断函数、bsp_gpio.c文件中的gpio_init(),gpio_enableint()函数。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第25张图片

最终实现的按键中断服务函数

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第26张图片

二、代码实现流程:

首先是对start.S基本的配置,配置完成后进入C语言的main()函数对基本外设进行初始化,首先是执行中断初始化interr_init() 

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第27张图片

interr_init() 里面包含GIC_Init()和中断向量表初始化、中断向量偏移

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第28张图片

 正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第29张图片

system_irqtable_init(void)先让所有的中断服务函数指向了default_irqhandler(unsigned int gicciar, void *param),用户参数默认为NULL

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第30张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第31张图片

 interr_init()初始化完成后,执行其余5个初始化函数(因为与之前相同这里就不做具体分析)。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第32张图片

 接下来进入exti_init()函数对按键进行外部中断初始化

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第33张图片

函数中先定义了按键IO的结构体key_config,然后将按键所连接的端口UART1_CTS_B进行复用成GPIO1_IO18,配置按键为输入模式,下降沿的中断触发方式,然后进入gpio_init()函数。

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第34张图片

 在函数中配置了GPIO1的GDIR寄存器控制为输入,IMR对应的位先写0关闭中断,然后进入gpio_intconfig()函数对中断的触发方式进行配置

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第35张图片

gpio_init()执行完成后进入GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第36张图片

执行中断注册函数system_register_irqhandler(GPIO1_Combined_16_31_IRQn, gpio1_io18_irqhandler, NULL);

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第37张图片

gpio_enableint(GPIO_Type* base, unsigned int pin)IMR寄存器对应的位置1开启gpio中断正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第38张图片

配置完成后等待外部中断的发生,当按键按下后触发了外部中断,start.S文件进入IRQ_Handler:

保护现场后跳转到C语言中的system_irqhandler(unsigned int gicciar)

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第39张图片

进入后通过gicciar寄存器的0~10位判断具体的中断ID号,根据ID号进入对应的中断服务函数

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第40张图片

正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第41张图片

 正点原子嵌入式Linux裸机开发教程——外部中断实验思路回顾、总结_第42张图片

中断服务函数内就是当按键按下后蜂鸣器状态翻转,结束后清除中断标志位。执行完gpio1_io18_irqhandler(unsigned int gicciar, void *param)后回到start.S文件恢复现场,整个中断程序结束,重新回到while(1)循环等待下一次中断的发生。

总结

以上是我对正点原子嵌入式Linux裸机开发教程外部中断实验的思路整理。之前在学习stm32的时候没有涉及中断向量表、中断向量偏移等相关内容,这些都是ST公司帮我们事先写好的。学习完本章后,我对I.MX6ULL的GIC控制服务、中断处理流程、GPIO关于中断的寄存器都有了一个更深的理解,对C语言中的函数指针、结构体数组的知识也进行了复习、巩固。

你可能感兴趣的:(Linux,嵌入式硬件,linux,stm32,硬件工程,经验分享)