N11 ARM-irq

一、复习进线程

进程间通信:无名管道、有名管道、共享内存、信号(信号量/消息队列)、套接字。

共享内存不自带同步互斥机制:

  • 多个进程同时读写会造成数据混乱
  • 必须配合 信号量 / 互斥锁 来控制访问顺序

线程:互斥锁、读写锁、自旋锁(忙 等待)、信号量(同步)

cs 复制代码
读写锁
// 共享数据
int shared_data = 0;
// 读写锁
pthread_rwlock_t rwlock;

// 写线程函数:写者互斥,与读者也互斥
void* writer(void* arg) {
    int id = *(int*)arg;
    // 加写锁
    pthread_rwlock_wrlock(&rwlock);
    printf("写线程 %d 获取写锁,开始修改数据...\n", id);
    shared_data++;
    sleep(1); // 模拟写操作耗时
    printf("写线程 %d 修改完成,shared_data = %d,释放写锁\n", id, shared_data);
    // 释放写锁
    pthread_rwlock_unlock(&rwlock);
    return NULL;
}

// 读线程函数:读者之间共享,与写者互斥
void* reader(void* arg) {
    int id = *(int*)arg;
    // 加读锁
    pthread_rwlock_rdlock(&rwlock);
    printf("读线程 %d 获取读锁,读取数据:shared_data = %d\n", id, shared_data);
    sleep(1); // 模拟读操作耗时
    printf("读线程 %d 读取完成,释放读锁\n", id);
    // 释放读锁
    pthread_rwlock_unlock(&rwlock);
    return NULL;
}

自旋锁轻量级锁 ,比互斥锁更快,适合锁内操作极短的场景,也是共享内存同步常用的高性能锁。

cpp 复制代码
pthread_spinlock_t spin_lock;

网络编程:

ISO七层模型:应用、表示、会话、传输、网络、链路、物理

四层模型:应用、传输、网络、链路接口

MAC地址(网卡硬件地址) IP地址(区分主机) 端口(区分进程)

TTL = 数据包最多跳多少个路由器,到 0 就死。

DHCP(动态主机配置协议)

  • IP 地址
  • 子网掩码
  • 默认网关
  • DNS 服务器地址

Static:静态 IP 配置
网段:A、B、C、D、E

子网掩码:255.255.255.0

IP 地址 切成两段:

  • 网络位 → 标识这个网段
  • 主机位 → 标识这个网段里的某台设备

然后判断:两台设备的网络位是否相同 → 相同 = 同一局域网;不同 = 跨网段。

划分网段为1的位必须一致才属于同一局域网。

网络号(子网掩码中为1的位)主机号(子网掩码中为0的位)。

同一网段指的是网络号相同的IP(相互连通)。

二、ARM中断

1、设置异常向量表地址为0(为0则可以重映射) //start.S

中断初始化:

1.重映射异常向量表基地址

2.初始化GIC
中断源:key_init()

引脚相关:配置引脚功能及方向 GPIODIR

设置中断触发方式、使能中断 GPIO_ICR GPIO_IMR

GIC中断使能 GIC_EnableIRQ(IRQn_Type IRQn)

GIC中断优先级设置 GIC_SetPriority(IRQn Type IRQn, uint32_t priority)

清中断标志:GPIO_ISR**(GPIO_IMR |= (1<<pin)**;

cs 复制代码
get GIC--IAR   // 读取 GIC 的 IAR 寄存器,获取当前中断号
deal irq        // 根据中断号调用对应的 C 语言处理函数
set GIC--EOIR   // 向 GIC 的 EOIR 寄存器写入,告知中断处理完成
数组名 用途 对应中断类型
irq_handler_array 通用中断处理函数表 普通外设中断(UART、Timer、I2C、IOMUXC 等独立中断号)
irq_gpio_handler_array GPIO 专用中断处理函数表 GPIO 分组中断(如 GPIO1_IO18_IRQ 这类引脚级中断号)

ARM 中断处理汇编(IRQ 入口)

cs 复制代码
_irq_handler:
    sub lr, lr, #4  修正返回地址:IRQ 异常返回时LR多4,必须减 4 才能正确返回 */
    stmfd sp!, {r0-r12, lr}   保存通用寄存器r0~r12和lr到IRQ 模式栈(满减栈) */
    
    mrc p15, 4, r1, c15, c0, 0  从 CP15 协处理器读取 GIC 基地址 → r1 */
    add r1, r1, #0x2000         计算 GIC CPU 接口基地址 = GIC 基 + 0x2000 */
    ldr r0, [r1, #0xc]      读取 GIC_IAR(中断确认寄存器)→ r0,获取中断号 */
    stmfd sp!, {r0,r1}          保存 r0(中断号)、r1(GIC 地址)到栈 */

    cps #0x1f     /* 切换到系统模式(System Mode),允许嵌套中断 / 运行 C 函数 */

    stmfd sp!, {r0-r12, lr}     保存系统模式下的寄存器环境 */
    bl system_irq_handler       调用 C 语言中断处理函数(真正业务逻辑) */
    ldmfd sp!, {r0-r12, lr}     恢复寄存器,从 C 函数返回 */

    cps #0x12                   切回 IRQ 模式,继续完成硬件中断收尾 */

    ldmfd sp!, {r0, r1}         恢复之前保存的 GIC 地址 r1、中断号 r0 */
    str r0, [r1, #0x10]     写GIC_EOIR(中断结束寄存器),通知中断控制器:处理完成*/
    
    ldmfd sp!, {r0-r12, pc}^ 
     恢复所有寄存器,^ 表示同时恢复SPSR→CPSR,真正返回被中断的程序 */

ARM 处理器的复位初始化代码

cs 复制代码
_reset_handler:
    /* DDR 地址范围:0x80000000 ~ 0xA0000000(512MB 内存空间)*/
    
    cpsid i                    关闭全局中断 IRQ,防止初始化阶段被打断 */
    
    ldr sp, =0x81000000         初始化【系统模式】栈指针,栈顶地址 0x81000000 
                                栈空间大小:16MB,用于系统模式运行 */

     配置 CP15 协处理器 c1 寄存器(开启/关闭缓存相关)*/
    mrc p15, 0, r1, c1, c0, 0    读取 CP15 控制寄存器 c1 → r1 */
    orr r1, r1, #(1 << 12)      /* 置位第12位:使能 I-Cache 指令缓存 */
    bic r1, r1, #(1 << 13)      /* 清零第13位:禁止 D-Cache 数据缓存 */
    mcr p15, 0, r1, c1, c0, 0    将配置写回 CP15 寄存器生效 */

    cps #0x12                    切换 CPU 工作模式 → IRQ 中断模式 */
  
    
    ldr sp, =0x82000000         初始化【IRQ 中断模式】栈指针,栈顶 0x82000000 
                                栈空间大小:16MB,专门给中断服务程序使用 */

    cps #0x1f                   切换 CPU 工作模式 → 系统模式(System Mode)*/

    ldr sp, =0x83000000         再次初始化【系统模式】栈指针,栈顶 0x83000000 
                                栈空间大小:16MB,给 C 语言 main 函数运行 */

    cpsie i                     开启全局中断 IRQ,允许中断触发 */
    
    bl main                   

IMX6ULL 按键中断初始化

cs 复制代码
按键中断初始化函数:配置GPIO为下降沿/上升沿中断输入
void key_irq_init(void)
{
     1. 设置引脚复用:将 UART1_CTS_B 复用为 GPIO1_IO18 功能
    0 表示复用功能为普通GPIO(无其他复用)
    IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);

     2. 配置引脚电气属性:上拉、禁止开路输出、速度中等、驱动能力等
     0x10b0 是IMX官方推荐的按键输入配置值
    IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0x10b0);

     3. 配置GPIO1_IO18为输入模式
     GDIR:方向寄存器,0=输入,1=输出
     ~(1<<18) 把第18位清零 → 输入
    GPIO1->GDIR &= ~(1 << 18);

     4. 配置中断触发方式:ICR2 控制 GPIO16~31
     (0x3 << 4):GPIO1_IO18 对应第4位开始,设置为 11 = 双边沿触发(上升+下降沿)
     00=低电平 01=高电平 10=下降沿 11=上升沿
    GPIO1->ICR2 |= (0x3 << 4);

     5. 使能GPIO1_IO18中断
     IMR:中断屏蔽寄存器,1=使能中断,0=屏蔽中断
    GPIO1->IMR |= (1 << 18);
}
相关推荐
cjy0001112 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
wefly20172 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
zhenxin01222 小时前
Spring Boot实现定时任务
java
小江的记录本3 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34163 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
luanma1509803 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默3 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
卓怡学长3 小时前
m289在线交友系统
java·spring·tomcat·maven·intellij-idea·hibernate
kyriewen113 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript