IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【Linux】ARM篇8--中断实验 -> 正文阅读

[系统运维]【Linux】ARM篇8--中断实验



一、前言

本篇使用华清远见的FS4412开发板,进行中断实验,知识包括CPU与硬件的交互方式、中断的原理、中断的实现,本篇通过中断信号的产生中断信号的传递中断程序的实现来对中断进行详细讲解。


二、准备工作

  • FS4412开发板,我用的是华清远见的FS4412开发板
  • ubuntu下linux操作系统(包含交叉编译工具
  • serial-com8程序烧入执行工具
  • 开发板电路原理图、芯片手册
  • 开发程序模板

开发板资料、交叉编译工具、程序烧入工具下载(包含教程)
开发板可选择到华清远见官网进行租赁。
工程模板文件下载


三、CPU与硬件的交互方式

  • 轮询
    CPU执行程序时不断地询问硬件是否需要其服务,若需要则给予其服务,若不需要一段时间后再次询问,周而复始
  • 中断
    CPU执行程序时若硬件需要其服务,对应的硬件给CPU发送中断信号,CPU接收到中断信号后,将当前的程序暂停下来,转而去执行中断服务程序,执行完成后再返回到被打断的点继续执行
  • DMA
    硬件产生数据后,硬件控制器可将产生的数据直接写入到存储器中,整个过程无需CPU的参与

四、轮询方式实现按键实验

1、电路原图

在这里插入图片描述
在这里插入图片描述


2、按键的实现

【Linux】ARM篇四–简单使用汇编点亮LED灯这篇文章中以讲述了GPIO寄存器,这里不在讲述,直接上代码,实验现象在文章最末。

/*
 * @Author: 修成真
 * @Date: 2022-04-22 18:55:45
 * @LastEditTime: 2022-04-22 18:58:46
 */
#include "exynos_4412.h"

#define LED2_ON (GPX2.DAT |= (1 << 7))    //LED2亮
#define LED2_OFF GPX2.DAT &= (~(1 << 7))  //LED2灭

int main()
{
	int i = 1;
	/* 设置按键引脚为输入模式 */
	GPX1.CON &= (~(0xF << 8));

	/* 配置LED2的引脚为输出模式 */
	GPX2.CON |= (0x1 << 28);

	while(1)
	{
		/*不断检查按键是否按下,按键按下LED电平翻转*/
		if(!(GPX1.DAT & (1 << 2)))  
		{
			if(i % 2 == 1)
				LED2_ON;
			else
				LED2_OFF;
			while(!(GPX1.DAT & (1 << 2))); //等待手松开按键
			i++;

		}
		else
		{
		
		}
	}
	return 0;
}

五、RAM中断实现原理

在这里插入图片描述

由外设硬件产生中断信号,中断信号经过中断控制器传递给CPU处理。

  • Exynos4412外设硬件产生的中断被视为FIQ或者IRQ的异常信号
  • Exynos4412总共160个中断,包括16个软件生成中断(SGIs)、16个私有外围中断(PPIs)和 128个支持共享外围中断(spi)
  • Exynos4412有四个CPU处理器,下面中断实验统一将中断信号发送给CPU0

关于RAM的异常处理,在这篇文章中有详细讲解:【Linux】ARM篇二–寄存器组织与异常处理


六、GPIO中断

外设硬件中断的产生方式 可以通过控制相应寄存器产生,这里已GPIO外部引脚中断为例,配置中断的产生。

1、GPX1CON

按键k3GPX1_2引脚,配置相应位,使引脚为中断模式。
在这里插入图片描述


2、EXT_INT41CON寄存器

功能:中断触发方式设置
在这里插入图片描述
40-GPX0, 41-GPX1, 42-GPX2, 43-GPX3
在这里插入图片描述
GPX1_2引脚对应的是EXT_INT41CON[2],设置该四位为下降沿触发,(根据按键原理图,引脚接高电平,按键按下时,变为引脚电平变为低电平,所以为下降沿)。


3、EXT_INT41_MASK寄存器

功能:中断触发开关
在这里插入图片描述
40-GPX0, 41-GPX1, 42-GPX2, 43-GPX3
在这里插入图片描述

  • 0:外设中断触发使能
  • 1:外设触发屏蔽

因此配置程序为:

/* 配置key2引脚为中断模式 */
GPX1.CON |= (0xF << 8);

/* 配置中断触发方式,下降沿触发 */
EXT_INT41_CON = EXT_INT41_CON & (~(0x7)) | (0x2 << 8); 

/* 打开外设中断开关 */
EXT_INT41_MASK &= (~(1 << 2));

七、中断控制器

外设产生的中断信号需要通过中断控制器,才能将信号发送给CPU。

有人会问,为啥不直接把信号传递给CPU?

主要是中断控制器有这些功能:

  • 多个中断同时产生时,可对这些中断挂起排队,然后按照优先级依次发送给CPU处理
  • 可以为每一个中断分配一个优先级
  • 一个中断正在处理时若又产生其它中断,可将新的中断挂起,待CPU空闲时再发送
  • 可以为每一个中断选择一个CPU处理
  • 可以为每一个中断选择一个中断类型(FIQ或IRQ)
  • CPU接收到中断信号后并不能区分是哪个外设产生的,此时CPU可查询中断控制器
  • 来获取当前的中断信号是由哪个硬件产生的,然后再进行对应的处理
    可以打开或禁止每一个中断

可以在(4412手册完整版)SEC_Exynos 4412 SCP_Users Manual_Ver.0.10.00_Preliminary,第749页,找到对应外设中断信号的ID
在这里插入图片描述

在这里插入图片描述


1、ICDDCR寄存器

功能:中断的总开关在这里插入图片描述

  • 0 : 忽略外部所用中断
  • 1 : 监控外部中断

2、ICDISER寄存器

功能:对应外设中断通道开关

在这里插入图片描述
在这里插入图片描述

  • 0 :关闭对应通道中断
  • 1 :打开对应通道中断

一个寄存器只有32位,但是我们有160个中断,因此用了5个寄存器来分配相应的中断位。(根据中断ID号寻找对应的位)
在这里插入图片描述


3、ICDIPTR寄存器

功能:选择哪个CPU处理中断
在这里插入图片描述
在这里插入图片描述

  • 只有寄存器只有0-7控制,每一位控制一个寄存器的选择,因此可支持8个CPU处理(8核),对应着CPU0-CPU8
  • 置1时,选择该位对应的寄存器处理中断,例如:值为0x3时,中断被发送到处理器0和处理器1。
  • 一个寄存器可以控制4个外设中断的选择,有160中断,因此需要40个寄存器控制
    对应表如下:
    在这里插入图片描述

本实验中断控制器配置程序为:

/* 打开外设与中断处理器之间的通道开关 */
ICDDCR |= 1;

/* 打开对应外设通道中断开关 */
ICDISER.ICDISER1 |= (1 << 26);

/* 选择对应CPU处理中断 CPU0 */
ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xFF << 16)) | (0x01 << 16);

/* 打开中断处理器与CPU之间的通道开关 */
CPU0.ICCICR |= 1;

八、中断的实现

ARMCPU对中断的处理跟ARM本身对异常的相应有关,详情看【Linux】ARM篇二–寄存器组织与异常处理RAM异常响应部分。
因此根据异常响应原理,我们在启动文件中,改变和添加相应的代码:
在这里插入图片描述
在这里插入图片描述
相应代码:

//外部硬件中断处理
IRQ_handler:
/* 恢复跳转地址 */
SUB LR, LR, #4

/* 保存现场,将寄存器内的值进行压栈操作 */
STMFD sp!, {R0-R12, LR}

/* 跳转到中断执行函数 */
BL do_IRQ

/* 恢复到中断之前的状态,并跳转回中断之前的位置 */
LDMFD sp!, {R0-R12, PC}^

1、ICCIAR寄存器

功能:CPU向中断控制器中获得对应中断ID号
在这里插入图片描述
0~9位存放着中断ID号。


2、EXT_INT41_PEND寄存器

功能:中断信号进入中断控制器后,会将相应的挂起并将信号发给CPU,挂起状态需要手动清除,否则会不断将信号发送给CPU。
在这里插入图片描述

  • 相应位置1,清除挂起状态。

3、ICCEOIR寄存器

功能通知中断控制器CPU已经执行完中断
在这里插入图片描述

  • 0~9位 :写入中断ID。

因此,在interface.c里写中断执行函数:

void do_IRQ()
{
	unsigned int interrupt_id = 0;
	interrupt_id = CPU0.ICCIAR & 0x3FF;  //获得中断id
	switch(interrupt_id)  //选择执行相应的外设中断
	{
		case 0:
			break;
		case 1:
			break;
			// ... ...
		case 58:
			flag++;
			printf("%d\n", flag);
			if(flag%2 == 1)
				LED2_ON;
			else
				LED2_OFF;
			/* 取消挂起状态,相应位置1 */
			EXT_INT41_PEND = (1 << 2);   

			/* 通知中断控制器CPU已经执行完中断 */
			CPU0.ICCEOIR = CPU0.ICCEOIR & (~0x3FF) | 58;
			break;
			// ... ...
		case 159:
			break;
		default:
			break;
	}
}

九、完整代码与烧入

1、中断完整代码

#include "exynos_4412.h"

#define LED2_ON GPX2.DAT |= (1 << 7)
#define LED2_OFF GPX2.DAT &= (~(1 << 7))
#define LED3_ON GPX1.DAT |= (1 << 0)
#define LED3_OFF GPX1.DAT &= (~(1 << 0))

int flag = 0;

void delay(unsigned int i)
{
	while(i--);
}

void do_IRQ()
{
	unsigned int interrupt_id = 0;
	interrupt_id = CPU0.ICCIAR & 0x3FF;  //获得中断id
	switch(interrupt_id)  //选择执行相应的外设中断
	{
		case 0:
			break;
		case 1:
			break;
			// ... ...
		case 58:
			flag++;
			printf("%d\n", flag);
			if(flag%2 == 1)
				LED2_ON;
			else
				LED2_OFF;
			/* 取消挂起状态,相应位置1 */
			EXT_INT41_PEND = (1 << 2);   

			/* 通知中断控制器CPU已经执行完中断 */
			CPU0.ICCEOIR = CPU0.ICCEOIR & (~0x3FF) | 58;
			break;
			// ... ...
		case 159:
			break;
		default:
			break;
	}
}

void key3_init()
{
	//外设中断配置
	/* 配置key2引脚为中断模式 */
	GPX1.CON |= (0xF << 8);

	/* 配置中断触发方式,下降沿触发 */
	EXT_INT41_CON = EXT_INT41_CON & (~(0x7)) | (0x2 << 8); 

	/* 打开外设中断开关 */
	EXT_INT41_MASK &= (~(1 << 2));

	//中断处理器配置
	/* 打开外设与中断处理器之间的通道开关 */
	ICDDCR |= 1;

	/* 打开对应外设通道中断开关 */
	ICDISER.ICDISER1 |= (1 << 26);

	/* 选择对应CPU处理中断 CPU0 */
	ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xFF << 16)) | (0x01 << 16);

	/* 打开中断处理器与CPU之间的通道开关 */
	CPU0.ICCICR |= 1;
	
}

int main()
{
	/* 配置LED2、LED3的引脚为输出模式 */
	GPX2.CON |= (0x1 << 28);
	GPX1.CON |= (0x1 << 0);
	
	key3_init();

	while(1)
	{
		LED3_ON;
		delay(1000000);
		LED3_OFF;
		delay(1000000);
	}
	return 0;
}

2、程序烧入步骤

1.输入make生成.bin文件
在这里插入图片描述


2.将.bin文件复制到共享文件夹

在这里插入图片描述

在这里插入图片描述

输入:

cp ARM_LED.bin /mnt/hgfs/cca

将文件复制到cc文件夹


3.打开serial-com8,连接开发板(COM2接口),烧入程序
①查看端口
在这里插入图片描述
②打开serial-com8设置
在这里插入图片描述
在这里插入图片描述
③接通开发板电源,迅速按enter键,使其快速进入裸机模式。
在这里插入图片描述
④烧入程序
在这里插入图片描述
输入:

loadb 40008000
在这里插入图片描述

选择可执行文件烧入
在这里插入图片描述
烧入成功:
在这里插入图片描述


⑤执行程序
输入:

go 40008000


十、实验现象

1、轮询按键实验现象

在这里插入图片描述

2、中断按键实验现象

在这里插入图片描述


  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-23 11:09:45  更:2022-04-23 11:09:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 20:46:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码