Linux 学习记录58(ARM篇)

这篇具有很好参考价值的文章主要介绍了Linux 学习记录58(ARM篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux 学习记录58(ARM篇)

Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

一、GIC相关寄存器

1. 系统框图

Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

  1. PPI:私有外设中断号:(ID:0~15)
  2. SPI:共享外设中断号:(ID:16~31)
  3. SGI:软件产生的中断号:(ID:0~287)

总结:

GIC层一共管理288个中断号(ID:0 ~ 287),16个SGIS,16个PPIS,256个SPIS

2. 中断号对应关系

Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发
例:
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

二、GICD寄存器

1. GICD_CTLR

功能:使能CPU
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

2. GICD_ISENABLERx

功能:设置GICD层中断使能
该寄存器共有8个(0-8),用于使能GICD层的的288个中断号,每个寄存器32位,分别控制32个中断号的使能
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

计算方式 置1 为使能

int ID = 99//中断号,以外部中断号为99的ID为例
ID / 32 = 3 
使用" GICD_ISENABLER3 "寄存器即可
ID % 32 = 3
使用" GICD_ISENABLER3 "寄存器的第 "3 bit位" 即可

3. GICD_IPRIORITYRx

功能:设置GICD层中断优先级
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

计算方式
备注:设置中断优先级值的范围在:0 ~ 2^5 -1 GICD层中断优先级,需要比GICC层中断优先级高 中断优先级的值越小,代表中断优先级越高

int ID = 99//中断号,以外部中断号为99的ID为例
ID / 4 = 24 
使用" GICD_IPRIORITYR第24个"寄存器即可
ID % 4 = 3 (*8+3) =27" GICD_IPRIORITYR第24个 "寄存器的第 "27 ~ 37(27+4) bit位" 即可

4. GICD_ITARGETSRx

功能:分配给cpu0 或者 cpu1
该寄存器共有72个(0~71)个寄存器 [ 288个中断号/每个寄存器控制4个中断号的分配 ]
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

计算方式

int ID = 99//中断号,以外部中断号为99的ID为例
ID / 4 = 24 
使用" GICD_ITARGETSR第24个"寄存器即可
ID % 4 = 3 (*8) =24" GICD_ITARGETSR第24个 "寄存器的第 "24 ~ 25(24+1) bit位" 即可

5. GICD_ICPENDRx

功能:清除GICD层挂起的中断标志位
该寄存器给共有8个寄存器[ 228个中断号/每个寄存器控制32个中断号的清除 ]
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

计算方式 置1为清除

int ID = 99//中断号,以外部中断号为99的ID为例
ID / 32 = 3 
使用" GICD_ICPENDR第3个"寄存器即可
ID % 32 = 3" GICD_ICPENDR第3个 "寄存器的第 "3 bit位" 即可

三、GICC寄存器

1. GICC_PMR

功能:设置GICC层中断优先级
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

2. GICC_CTLR

功能:使能cpu中断
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

3. GICC_IAR

功能:获取中断号,这个寄存器只读
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发

4. GICC_EOIR

功能:清除获取到中断号
Linux 学习记录58(ARM篇),Linux学习记录,linux,学习,arm开发文章来源地址https://www.toymoban.com/news/detail-609401.html

四、封装函数

1. 寄存器封装

typedef unsigned          char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;

#define __IO    volatile
typedef struct{
	__IO uint32_t RTSR1; 	// EXTI rising trigger selection register 	
	__IO uint32_t FTSR1; 	// EXTI falling trigger selection register	
	__IO uint32_t SWIER1;   // EXTI software interrupt event register 
	__IO uint32_t RPR1;     // EXTI rising edge pending register
	__IO uint32_t FPR1;  	// EXTI falling edge pending register
	__IO uint32_t TZENR1;   // EXTI TrustZone enable register
	__IO uint32_t RES1[2];  
	__IO uint32_t RTSR2;    // EXTI rising trigger selection register
	__IO uint32_t FTSR2;    // EXTI falling trigger selection register
	__IO uint32_t SWIER2;   // EXTI software interrupt event register
	__IO uint32_t RPR2;     // EXTI rising edge pending register
	__IO uint32_t FPR2;	    // EXTI falling edge pending register
	__IO uint32_t TZENR2;   // EXTI TrustZone enable register
	__IO uint32_t RES2[2];
	__IO uint32_t RTSR3;    // EXTI rising trigger selection register
	__IO uint32_t FTSR3;    // EXTI falling trigger selection register
	__IO uint32_t SWIER3;   // EXTI software interrupt event register
	__IO uint32_t RPR3;     // EXTI rising edge pending register
	__IO uint32_t FPR3;     // EXTI falling edge pending register
	__IO uint32_t TZENR3;   // EXTI TrustZone enable register
	__IO uint32_t RES3[2];
	__IO uint32_t EXTICR1;	// EXTI external interrupt selection register 1
	__IO uint32_t EXTICR2;  // EXTI external interrupt selection register 2	
	__IO uint32_t EXTICR3;  // EXTI external interrupt selection register 3	
	__IO uint32_t EXTICR4;  // EXTI external interrupt selection register 4	
	__IO uint32_t RES4[4];
	__IO uint32_t C1IMR1;   // EXTI CPU1 wakeup with interrupt mask register
	__IO uint32_t C1EMR1;   // EXTI CPU1 wakeup with event mask register
	__IO uint32_t RES5[2];
	__IO uint32_t C1IMR2;   // EXTI CPU1 wakeup with interrupt mask register
	__IO uint32_t C1EMR2;   // EXTI CPU1 wakeup with event mask register
	__IO uint32_t RES6[2];
	__IO uint32_t C1IMR3;   // EXTI CPU1 wakeup with interrupt mask register	
	__IO uint32_t C1EMR3;   // EXTI CPU1 wakeup with event mask register 
	__IO uint32_t RES7[6];
	__IO uint32_t C2IMR1;   // EXTI CPU2 wakeup with interrupt mask register
	__IO uint32_t C2EMR1;   // EXTI CPU2 wakeup with event mask register
	__IO uint32_t RES8[2];
	__IO uint32_t C2IMR2;   // EXTI CPU2 wakeup with interrupt mask register
	__IO uint32_t C2EMR2;   // EXTI CPU2 wakeup with event mask register
	__IO uint32_t RES9[2];
	__IO uint32_t C2IMR3;   // EXTI CPU2 wakeup with interrupt mask register 
	__IO uint32_t C2EMR3;   // EXTI CPU2 wakeup with event mask register 
	__IO uint32_t RES10[2];
}EXTI_TypeDef;

#define  EXTI   ((EXTI_TypeDef*)0x5000D000)

typedef struct {
	volatile unsigned int CTRL;
	volatile unsigned int TYPER;
	volatile unsigned int IIDR;
	volatile unsigned int RES1[29];
	volatile unsigned int IGROUPR[9];
	volatile unsigned int RES2[23];
	volatile unsigned int ISENABLER[9];
	volatile unsigned int RES3[23];
	volatile unsigned int ICENABLER[9];
	volatile unsigned int RES4[23];
	volatile unsigned int ISPENDR[9];
	volatile unsigned int RES5[23];
	volatile unsigned int ICPENDR[9];
	volatile unsigned int RES6[23];
	volatile unsigned int ISACTIVER[9];
	volatile unsigned int RES7[23];
	volatile unsigned int ICACTIVER[9];
	volatile unsigned int RES8[23];
	volatile unsigned int IPRIORITYR[72];
	volatile unsigned int RES9[184];
	volatile unsigned int ITARGETSR[72];
	volatile unsigned int RES10[184];	
	volatile unsigned int ICFGR[18];
	volatile unsigned int RES11[46];

}GICD_TypeDef;
#define GICD  ((GICD_TypeDef*)0xA0021000)

typedef struct {
	volatile unsigned int CTRL;
	volatile unsigned int PMR;
	volatile unsigned int BRR;
	volatile unsigned int IAR;
	volatile unsigned int EOIR;
	volatile unsigned int RPR;
	volatile unsigned int HPPIR;
	volatile unsigned int ABPR;
	volatile unsigned int AIAR;
	volatile unsigned int AEOIR;
	volatile unsigned int AHPPIR;
	volatile unsigned int RES1[41];
	volatile unsigned int APR0;
	volatile unsigned int RES2[3];
	volatile unsigned int NSAPR0;
	volatile unsigned int RES3[6];
	volatile unsigned int IIDR;
	volatile unsigned int RES4[960];
	volatile unsigned int DIRDIR;

}GICC_TypeDef;
#define GICC  ((GICC_TypeDef*)0xA0022000) 

2. EXTI初始化结构体/枚举封装

typedef enum
{
    EXTI_GPIOA = 0x0,
    EXTI_GPIOB,
    EXTI_GPIOC,
    EXTI_GPIOD,
    EXTI_GPIOE,
    EXTI_GPIOF,
    EXTI_GPIOG,
    EXTI_GPIOH,
    EXTI_GPIOI,
    EXTI_GPIOJ,
    EXTI_GPIOK,
    EXTI_GPIOZ,
}EXTI_GPIOxTypedef;

typedef enum
{
    EXTI_Trigger_Rising = 0x0,//上升
    EXTI_Trigger_Falling,//下降
    EXTI_Trigger_Rising_Falling,//双边沿
}EXTI_TriggerTypedef;

typedef struct
{
    uint16_t EXTI_GPIOx;//GPIO组号
    uint16_t EXTI_Line;//中断线
    uint8_t EXTI_Trigger;//触发方式
    uint8_t EXTI_Wakeup;//是否屏蔽

}EXTI_InitTypeDef;
/*相关函数声明*/
/*外部中断初始化*/
void EXTI_Init(EXTI_InitTypeDef* EXTI_Init);
/*清除挂起标志位s*/
void EXTI_Clr_FPR1(uint16_t ID);

3. GICD初始化结构体/枚举

typedef enum
{/*和GICC共用*/
    GIC_CPU0 = 0x1,//CPU0
    GIC_CPU1,//CPU1
    GIC_CPU1_0,//CPU1和CPU0
}GIC_CPUTypedef;

typedef struct
{
   uint8_t GICD_CPU;//使能的CPU
   uint8_t GICD_Allocation_CPU;//分配CPU
   uint8_t GICD_priority;//设置优先级
   uint16_t GICD_interrupt_ID;//使能的中断号
   
}GICD_InitTypeDef;
/*相关函数声明*/
/*GICD初始化*/
void GICD_Init(GICD_InitTypeDef* GICD_Init);
/*清除挂起标志位*/
void GICD_Clr_ICPENDR(uint16_t ID);

4. GICC初始化结构体/枚举

typedef struct
{
    uint8_t GICC_priority;//设置优先级
    uint8_t GICC_CPU;//使能的CPU
}GICC_InitTypeDef;
/*相关函数声明*/
/*GICC初始化*/
void GICC_Init(GICD_InitTypeDef* GICD_Init);
/*获取中断号*/
uint32_t GICC_Get_IAR(void);
/*清除中断号*/
void GICC_Clr_EOIR(uint32_t ID);

5. EXTI函数

void EXTI_Init(EXTI_InitTypeDef* EXTI_Init)
{
    uint8_t py = 0;

    py = EXTI_Init->EXTI_Line/4;
    py++;

    switch(py)
    {
        case 1:{
            /*连接Pin到EXTI_line*/
            EXTI->EXTICR1 &= ~(0xff << ((EXTI_Init->EXTI_Line%4) *8));
            EXTI->EXTICR1 |= (EXTI_Init->EXTI_GPIOx << ((EXTI_Init->EXTI_Line%4) *8));
        }break;

        case 2:{
            /*连接Pin到EXTI_line*/
            EXTI->EXTICR2 &= ~(0xff << ((EXTI_Init->EXTI_Line%4) *8));
            EXTI->EXTICR2 |= (EXTI_Init->EXTI_GPIOx << ((EXTI_Init->EXTI_Line%4) *8));
        }break;

        case 3:{
            EXTI->EXTICR3 &= ~(0xff << ((EXTI_Init->EXTI_Line%4) *8));
            EXTI->EXTICR3 |= (EXTI_Init->EXTI_GPIOx << ((EXTI_Init->EXTI_Line%4) *8));
        }break;

        case 4:{
            /*连接Pin到EXTI_line*/
            EXTI->EXTICR4 &= ~(0xff << ((EXTI_Init->EXTI_Line%4) *8));
            EXTI->EXTICR4 |= (EXTI_Init->EXTI_GPIOx << ((EXTI_Init->EXTI_Line%4) *8));
        }break;

        default : break;
    }

    switch(EXTI_Init->EXTI_Trigger)
    {
        case EXTI_Trigger_Rising :{//上升沿
            /*设置为上升降沿触发*/
            EXTI->RTSR1 &= ~(0x1 << EXTI_Init->EXTI_Line);
            EXTI->RTSR1 |= (0x1 << EXTI_Init->EXTI_Line);
        }break;

        case EXTI_Trigger_Falling :{//下降沿
            /*设置为下降沿触发*/
            EXTI->FTSR1 &= ~(0x1 << EXTI_Init->EXTI_Line);
            EXTI->FTSR1 |= (0x1 << EXTI_Init->EXTI_Line);
        }break;

        case EXTI_Trigger_Rising_Falling :{//双边沿
            /*设置下降沿触发*/
            EXTI->FTSR1 &= ~(0x1 << EXTI_Init->EXTI_Line);
            EXTI->FTSR1 |= (0x1 << EXTI_Init->EXTI_Line);
            /*设置为上升降沿触发*/
            EXTI->RTSR1 &= ~(0x1 << EXTI_Init->EXTI_Line);
            EXTI->RTSR1 |= (0x1 << EXTI_Init->EXTI_Line);
        }break;
    }
    
    /*设置EXTI不屏蔽*/
    EXTI->C1IMR1 &= ~(0x1 << EXTI_Init->EXTI_Line);
    EXTI->C1IMR1 |= (0x1 << EXTI_Init->EXTI_Line);
    /*设置EXTI不屏蔽*/
    EXTI->C1IMR1 &= ~(0x1 << EXTI_Init->EXTI_Line);
    EXTI->C1IMR1 |= (0x1 << EXTI_Init->EXTI_Line);
}

/*清除挂起标志位s*/
void EXTI_Clr_FPR1(uint16_t ID)
{
    EXTI->FPR1 |= 0x1 << ID;
}

6. GICD函数

/*GICD初始化*/
void GICD_Init(GICD_InitTypeDef* GICD_Init)
{
    /*使能GICD*/
    GICD->CTRL &= ~(0x3);
    GICD->CTRL |= GICD_Init->GICD_CPU;

    /*设置使能寄存器*/
    GICD->ISENABLER[GICD_Init->GICD_interrupt_ID/32] |= 0x1<<(GICD_Init->GICD_interrupt_ID%32);

    /*设置中断优先级*/
    GICD->IPRIORITYR[GICD_Init->GICD_interrupt_ID/4] &= ~(0x1F << ((GICD_Init->GICD_interrupt_ID%32)*8+3));
    GICD->IPRIORITYR[GICD_Init->GICD_interrupt_ID/4] |= GICD_Init->GICD_priority << ((GICD_Init->GICD_interrupt_ID%32)*8+3);
    
    /*设置中断优先级*/
    GICD->ITARGETSR[GICD_Init->GICD_interrupt_ID/4] &= ~(0x3 << ((GICD_Init->GICD_interrupt_ID%32)*8));
    GICD->ITARGETSR[GICD_Init->GICD_interrupt_ID/4] |= GICD_Init->GICD_Allocation_CPU << ((GICD_Init->GICD_interrupt_ID%32)*8);
}
/*清除挂起标志位*/
void GICD_Clr_ICPENDR(uint16_t ID)
{
    GICD->ICPENDR[ID/32] |= 0x1 << ID%32;
}

7. GICC函数

/*GICC初始化*/
void GICC_Init(GICC_InitTypeDef* GICC_Init)
{
     /*使能CICC*/
    GICC->CTRL &= ~(0x3);
    GICC->CTRL |= GICC_Init->GICC_CPU;
    /*中断优先级设置*/
    GICC->PMR &= ~(0x1F << 3);
    GICC->PMR |= GICC_Init->GICC_priority << 3;
}

8. 使用示例

	EXTI_InitTypeDef EXTI_InitStructure;

    EXTI_InitStructure.EXTI_GPIOx = EXTI_GPIOF;
    EXTI_InitStructure.EXTI_Line = 9;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_Wakeup = 1;
    EXTI_Init(&EXTI_InitStructure);

    EXTI_InitStructure.EXTI_Line = 8;
    EXTI_Init(&EXTI_InitStructure);

    EXTI_InitStructure.EXTI_Line = 7;
    EXTI_Init(&EXTI_InitStructure);

    GICD_InitTypeDef GICD_InitStructure;

    GICD_InitStructure.GICD_CPU = GIC_CPU0;
    GICD_InitStructure.GICD_Allocation_CPU = GIC_CPU0;
    GICD_InitStructure.GICD_priority = 0;
    GICD_InitStructure.GICD_interrupt_ID = 99;
    GICD_Init(&GICD_InitStructure);

    GICD_InitStructure.GICD_priority = 1;
    GICD_InitStructure.GICD_interrupt_ID = 98;
    GICD_Init(&GICD_InitStructure);

    GICD_InitStructure.GICD_priority = 2;
    GICD_InitStructure.GICD_interrupt_ID = 97;
    GICD_Init(&GICD_InitStructure);

    GICC_InitTypeDef GICC_InitStructure;
    GICC_InitStructure.GICC_priority = 4;
    GICC_InitStructure.GICC_CPU = GIC_CPU0;
    GICC_Init(&GICC_InitStructure);

到了这里,关于Linux 学习记录58(ARM篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Linux 学习记录56(ARM篇)

    总线是完成传输的一种媒介,总线可以分为系统总线、数据总线和地址总线 系统总线是连接计算机的主要组成部分,它负责传输数据和控制信息。数据总线用于传输数据,而地址总线用于指定数据的存储位置。 串行总线同一时刻,只可以收发一位数据,并且串行总线只有一

    2024年02月15日
    浏览(28)
  • Linux 学习记录54(ARM篇)

    以STM32MP157为例 相关数据手册在文章顶部下载 (1. RCC寄存器 2.5.2 (2. GPIO寄存器 1. 模式配置寄存器 2. 输出模式配置寄存器 3. 速度配置寄存器 4. 上下拉配置寄存器 5. GPIO输出寄存器 (1. RCC寄存器配置 (2. GPIO寄存器配置

    2024年02月16日
    浏览(26)
  • 记录移植Python3到arm开发板linux系统中

    开发板情况 arm板是公司采购的工控机。主要用来 使用python3解析excel表格处理数据。 配置如下: 配置 版本 cpu imx6dl(armv7架构) 操作系统 linux3.10 python版本 2.7 项目情况 项目中最好使用 python3 。可行的有以下几种方式: 方式 优缺点 可行度 重做文件系统 订制程度比较高,后期增

    2024年02月04日
    浏览(40)
  • ARM+LINUX嵌入式学习路线

    嵌入式学习是一个循序渐进的过程,如果是希望向嵌入式软件方向发展的话,目前最常见的是嵌入式Linux方向,关注这个方向,大概分3个阶段: 1、嵌入式linux上层应用,包括QT的GUI开发 2、嵌入式linux系统开发 3、嵌入式linux驱动开发 嵌入式目前主要面向的几个操作系统是,

    2024年02月02日
    浏览(51)
  • 【Linux下6818开发板(ARM)】硬件空间挂载

    (꒪ꇴ꒪ ),hello我是 祐言 博客主页:C语言基础,Linux基础,软件配置领域博主🌍 快上🚘,一起学习! 送给读者的一句鸡汤🤔: 集中起来的意志可以击穿顽石! 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏         在嵌入式系统开发中,经常需要使用外部硬件

    2024年02月14日
    浏览(31)
  • linux下arm环境启动脚本/etc/init.d/rcS执行命令失败,踩坑记录

    记一次踩坑记录!!! 接触到一个新的系统,需要在这个系统上跑程序,测试的时候,手动执行脚本和程序都没问题,于是将执行命令写入到linux启动脚本/etc/init.d/rcS这个文件中,然后重启,等待程序起来,但是让我意想不到的是,执行到我加的命令的时候,居然报错,找不

    2024年01月21日
    浏览(31)
  • Rust在linux下交叉编译到arm开发板

    前段时间做了rust交叉编译到arm开发板,如果引入的包有些包含OpenSSL,ring...遇见了很多问题在网上也查阅很多资料,今天抽个时间做个汇总吧。 虚拟机里面安装rust环境,做到交叉编译的时候应该都已经有了,这个地方就不过多说了,网上找一下就有的 首先描述一下我的环境

    2024年02月15日
    浏览(36)
  • [ARM+Linux] 基于全志h616外设开发笔记

    修改用户密码 配置网络 nmcli dev wifi  命令扫描周围WIFI热点   nmcli dev wifi connect  xxx  password xxx 命令 连接WiFi 查看ip地址的指令: ifconfig ip addr show wlan0 SSH登录         这是企业开发调试必用方式,比串口来说不用接线,前提是接入网络并获得板子IP 地址,且系统做了SSH的

    2023年04月21日
    浏览(35)
  • 【嵌入式】Linux开发工具arm-linux-gcc安装及使用

    宿主机 执行编译、链接嵌入式软件的计算机 目标机 运行嵌入式软件的硬件平台 “本地”编译器 用来生成在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,例如 Windows 环境生成 Windows 目标代码。 交叉编译器 用来生成在其它平台上运行的目标代

    2024年01月17日
    浏览(45)
  • ARM_Linux的交叉开发以及交叉编译器

    目录 为什么要使用交叉开发 为什么要使用交叉编译 交叉编译器的安装 交叉编译器的使用 交叉开发是指在通用的电脑上吧程序编写,编译,调试好,再下载到嵌入式产品中去运行,对于一些简单的程序的话,直接在电脑上编译调试好即可,但是对于一些需要操作硬件的开发

    2024年01月23日
    浏览(38)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包