【Linux驱动-快速回顾】一文快速理解GIC内部寄存器对中断的控制

第一部分:GIC的功能和组成

1. GIC要解决的根本问题
在一个复杂的片上系统(SoC)中,有非常多的硬件模块(如定时器、串口、按键、DMA等),它们都需要在完成任务或遇到特定事件时通知CPU。同时,系统里可能有多个CPU核心。因此,必须有一个统一的、专门的硬件来管理这些中断请求。它需要解决:

  • 来源管理:管理成百上千个中断源。
  • 优先级仲裁:当多个中断同时发生时,决定哪个更重要,应该先被处理。
  • 中断路由:决定将一个中断发送给哪个CPU核心去处理。
  • 状态同步:确保CPU和中断控制器之间的状态是一致的,比如一个中断正在被处理时,就不应该再次打扰CPU。

GIC (Generic Interrupt Controller) 就是 ARM 定义的用来解决以上所有问题的标准硬件模块。

2. GIC的核心组件
根据文档,GIC 主要由两个功能模块组成,它们的职责划分非常清晰:

  • 分发器 (Distributor)

    • 职责:作为整个系统的中断“管理中心”和“仲裁中心”。
    • 具体工作
      1. 接收所有中断:系统中所有外设的中断信号线都连接到 Distributor。
      2. 配置中断属性:软件通过 Distributor 的寄存器来配置每个中断的属性,包括:
        • 优先级 (Priority):定义中断的重要程度。
        • 目标CPU (Target):指定这个中断可以发送给哪些CPU核心。
        • 触发方式 (Configuration):是电平触发还是边沿触发。
        • 使能/禁用 (Enable/Disable):控制一个中断是否被允许。
      3. 仲裁:在所有已触发且被使能的中断中,找出优先级最高的那一个。
      4. 转发:将这个最高优先级的中断,转发给其目标CPU对应的“CPU接口”。
  • CPU接口 (CPU Interface)

    • 职责:作为 Distributor 和单个CPU核心之间的“信使”。每个CPU核心都有一个自己专属的 CPU Interface。
    • 具体工作
      1. 接收中断:从 Distributor 接收已经仲裁过的、最高优先级的中断。
      2. 优先级过滤 (Masking):CPU Interface 内部可以设置一个优先级阈值。如果接收到的中断的优先级不够高(低于这个阈值 ),它就不会去打扰CPU。
      3. 通知CPU:如果中断通过了优先级过滤,CPU Interface 会向其对应的CPU核心发出一个物理的中断信号(IRQ 或 FIQ)。
      4. 提供中断信息:当CPU响应中断后,软件可以通过读取 CPU Interface 的寄存器来获知当前中断的ID号。
      5. 处理完成通信:当软件处理完中断后,通过写入 CPU Interface 的寄存器来通知 GIC。

Distributor 负责多对多(多个中断源到多个CPU)的管理和决策;
CPU Interface 负责一对一(Distributor 到单个CPU)的通信和执行。

好的,我们完全按照要求,用更直接、无修饰的语言来重新讲解第二部分。我们将严格遵循硬件和软件的交互行为,来描述一个中断从产生到处理完成的全过程。


第二部分:从中断触发到CPU处理,发生了什么?

第1步:中断源触发与Pending状态的设置
  • 物理层:外部设备(如GPIO)的信号线电平发生变化,该信号被送入GIC Distributor。
  • GIC Distributor的行为
    1. Distributor硬件逻辑检测到输入信号。
    2. 硬件查询该中断ID对应的使能寄存器(GICD_ISENABLERn)。
    3. 若该中断ID被使能,Distributor在内部状态寄存器中,将该中断ID的标志位设置为 Pending (挂起)
  • Pending状态的定义:表示一个有效的中断请求已经由GIC记录,正在等待GIC的后续处理。
第2步:优先级仲裁
  • 内部事件:Distributor的仲裁逻辑被触发。这可能在有新的中断变为Pending状态时发生。
  • GIC Distributor的行为
    1. 硬件逻辑扫描所有处于Pending状态的中断ID。
    2. 对于每一个Pending的中断ID,硬件会读取其对应的优先级寄存器(GICD_IPRIORITYRn)中的值。
    3. 硬件比较所有这些优先级值,并选择值最小(即优先级最高)的中断ID作为本次处理的目标。
  • 仲裁结果:Distributor确定了当前应该被处理的、优先级最高的中断请求。
第3步:向CPU接口转发与优先级过滤
  • 事件:Distributor已选出最高优先级的中断ID。
  • GIC Distributor的行为
    1. 硬件读取该中断ID的目标处理器寄存器(GICD_ITARGETSRn),确定目标CPU。
    2. Distributor通过内部总线,将这个最高优先级的中断ID及其优先级信息,发送给目标CPU的专属CPU Interface。
  • GIC CPU Interface的行为
    1. CPU Interface接收到来自Distributor的中断请求。
    2. 硬件执行优先级过滤:它将收到的中断的优先级,与CPU Interface内部的优先级屏蔽寄存器(GICC_PMR)的值,以及当前正在处理的中断的优先级组(如果有的话)进行比较。
    3. 只有当新中断的优先级严格高于过滤阈值时,该中断才被接受。
    4. 若中断被接受,CPU Interface会驱动连接到CPU核心的物理IRQ(或FIQ)信号线,使其变为有效电平。
第4步:CPU响应与中断确认 (Acknowledge)
  • 事件:CPU核心检测到其IRQ信号线变为有效。

  • CPU硬件的行为

    1. 若CPU的中断屏蔽位(CPSR寄存器中的I/F位)未置位,CPU将暂停当前指令的执行。
    2. 硬件自动将程序计数器(PC)和相关寄存器压入当前模式的堆栈。
    3. 硬件强制将PC设置为中断向量表中预定义的IRQ异常向量地址。
  • 软件(异常处理程序)的行为

    1. 位于异常向量地址的程序开始执行。其首要任务是执行对CPU Interface的 GICC_IAR (Interrupt Acknowledge Register) 的读操作
  • GICC_IAR的直接后果

    1. 对软件而言:该读操作返回一个32位值,其中包含了触发本次中断的硬件中断ID
    2. 对GIC硬件而言:GIC检测到对GICC_IAR的读访问,会原子地更新该中断ID的状态:清除其Pending标志位,并设置其Active标志位。
  • Active状态的定义:表示该中断已被CPU获知,并且其对应的服务程序即将或正在执行。GIC将不会再次向CPU转发同一个处于Active状态的中断请求。

    • 并发情况:若一个中断在Active期间再次被外设触发,它的状态将变为Active and Pending
第5步:中断服务程序执行
  • 事件:软件已从GICC_IAR获取了硬件中断ID。
  • 软件(操作系统)的行为
    1. 软件使用该硬件中断ID作为索引,在中断分派表中查找对应的中断服务程序(ISR)的地址。
    2. 调用该ISR。
    3. ISR执行与中断源设备相关的特定操作。
第6步:中断处理完成与中断结束 (End of Interrupt)
  • 事件:中断服务程序(ISR)已执行完毕。

  • 软件(异常处理程序)的行为

    1. 在从异常处理流程返回前,软件必须执行对CPU Interface的 GICC_EOIR (End of Interrupt Register) 的写操作,写入的值是第4步中获取的那个硬件中断ID。
  • GICC_EOIR的直接后果

    1. 对GIC硬件而言:GIC检测到对GICC_EOIR的写访问,会清除该中断ID的Active标志位。
    2. 状态转移:
      • 如果该中断状态之前是单纯的Active,现在将变为Inactive(非活动)。
      • 如果该中断状态之前是Active and Pending,现在Active位被清除后,状态将变回Pending。GIC的仲裁逻辑会立刻将这个新的Pending中断纳入下一轮仲裁。
  • CPU恢复:软件执行异常返回指令(如SUBS PC, LR, #4),CPU从堆栈中恢复之前保存的上下文,并从被中断的指令处继续执行。


省流版本

1.中断发生,Distributor检测到输入信号,提取中断ID号,使能寄存器(GICD_ISENABLERn),将该中断状态寄存器设置为挂起Pending

2.Distributor找出当前触发的优先级最高的中断

3.Distributor提取当前最高优先级中断ID的目标CPU,转发给CPU专属的CPU Interface

4.CPU Interface接收到来自Distributor中断请求,将其优先级与优先级屏蔽寄存器的值比较,符合条件则:驱动连接到CPU核心的物理IRQ(或FIQ)信号线,使其变为有效电平

5.CPU核心检测到其IRQ信号线变为有效,且CPU的中断屏蔽位未置位:
停止当前指令执行,压栈:将程序计数器(PC)和相关寄存器压入当前模式的堆栈;

6.强制将PC设置为中断向量表中预定义的IRQ异常向量地址;

7.执行对CPU Interface的 GICC_IAR (Interrupt Acknowledge Register) 的读操作
原子地更新该中断ID的状态:清除其Pending标志位,并设置其Active标志位

8.执行对应对应中断,完成后执行对CPU Interface的 GICC_EOIR (End of Interrupt Register) 的写操作

9.软件执行异常返回指令(如SUBS PC, LR, #4),CPU从堆栈中恢复之前保存的上下文,并从被中断的指令处继续执行


第三部分:上文提到的中断寄存器专讲

我们继续按照触发顺序讲解这些寄存器
这样更能清晰一些

第1步:了解GIC硬件能力 (可选,但良好驱动的实践)

在配置之前,软件可以先读取一些只读寄存器,了解当前GIC的规格。

**GICD_TYPER 了解GIC一些基础信息

(Interrupt Controller Type Register)**
作用: 读取此寄存器,可以知道:
这个GIC最多支持多少个中断 (ITLinesNumber)、
实现了多少个CPU接口 (CPUNumber)、
是否支持安全扩展 (SecurityExtn) 等。
这让驱动可以动态适应不同的硬件。
在这里插入图片描述

位域读写描述
15:11LSPIR如果GIC实现了安全扩展,则此字段的值是已实现的可锁定SPI的最大数量,范围为0(0b00000)到31(0b11111)。 如果此字段为0b00000,则GIC不会实现配置锁定。 如果GIC没有实现安全扩展,则保留该字段。
10SecurityExtnR表示GIC是否实施安全扩展: 0未实施安全扩展; 1实施了安全扩展
7:5CPUNumberR表示已实现的CPU interfaces的数量。 已实现的CPU interfaces数量比该字段的值大1。 例如,如果此字段为0b011,则有四个CPU interfaces。
4:0ITLinesNumberR表示GIC支持的最大中断数。 如果ITLinesNumber = N,则最大中断数为32*(N+1)。 中断ID的范围是0到(ID的数量– 1)。 例如:0b00011最多128条中断线,中断ID 0-127。 中断的最大数量为1020(0b11111)。 无论此字段定义的中断ID的范围如何,都将中断ID 1020-1023保留用于特殊目的
第2步:对每一个“计划使用”的中断进行单独配置
1.GICD_ICFGRn :设置中断的触发方式

(Interrupt Configuration Registers)
置该中断是电平触发 (Level-sensitive) 还是边沿触发 (Edge-triggered)。这个必须根据外设的硬件手册来设置,否则中断会行为异常
在这里插入图片描述
这里两位代表一个中断,一个GICD_ICFGRn 寄存器能配置16个中断
已知硬件中断号m怎么知道GICD_ICFGRn 的n是多少?用m整除16即可得到n
然后是哪个字段?(两位等于一个字段)
假设中断号34,34/16=2,余2,所以F=2,所以寄存器位是【22,22+1】
也就是【4,5】
Int_config[1] (高位,即 bit[5]):0 = 电平触发, 1 = 边沿触发。
Int_config[0] (低位,即 bit[4]):保留位,通常写0。

2.Distributor (分组 , GICD) GICD_IGROUPRn

(GICD_ Interrupt GROUP Registers)

在这里插入图片描述
一位即可表示是否为安全中断,一个寄存器能给32个中断置位
某一位
置位 0(通常是安全中断,FIQ)
置位 1(通常是非安全中断,IRQ)的中断分发

非安全中断:给主操作系统(如Linux)用的常规中断

  • 是什么?
    • 处理普通任务的中断。
  • 谁产生?
    • 普通的、非敏感的硬件设备。比如:网卡、普通按键、串口、触摸屏。
  • 谁处理?
    • 主操作系统,比如你手机上的Android系统或电脑上的Linux/Windows系统。
  • 有什么用?
    • 让主操作系统知道硬件发生了事。比如网卡收到数据了,Linux内核就去处理这个数据。
  • 在GIC里怎么设置?
    • 通过 GICD_IGROUPRn 寄存器,把这个中断对应的位设置为 1。

安全中断 (Secure Interrupt / Group 0 Interrupt)
安全中断是给一个独立的安全系统用的特殊中断,主操作系统(如Linux)不能处理它,也通常不知道它的存在

  • 是什么?
    • 处理高度敏感和机密任务的中断。
  • 谁产生?
    • 受保护的、敏感的硬件设备。比如:指纹传感器、加密芯片、安全定时器。
  • 谁处理?
    • 一个独立于主操作系统之外的、微型的安全系统(常被称为TEE,Trusted Execution Environment)。这个安全系统和Linux是隔离的。
  • 有什么用?
    • 处理那些绝对不能让主操作系统(比如Linux)接触到的数据。比如,指纹识别过程中的数据,必须由安全系统处理,以防被Linux上的恶意软件窃取。
  • 在GIC里怎么设置?
    • 通过 GICD_IGROUPRn 寄存器,把这个中断对应的位设置为 0。
3.优先级 (Priority) - GICD_IPRIORITYRn

在这里插入图片描述
因为设置了256个优先级,所以描述一个中断的优先级需要8位
一个寄存器32位可以设置四个中断的优先级

目标CPU (Targeting) - GICD_ITARGETSRn (主要用于SPI)

在这里插入图片描述
这个是GICV2版本下,采用位图方式(每一位代表一个目标CPU),最多只支持8核CPU。

第3步:使能/禁用中断
1.GICD_ISENABLERn (Set-Enable) / GICD_ICENABLERn (Clear-Enable)

(中断分发)
( Interrupt Set-Enable Registers)
在这里插入图片描述
每一位控制一个中断的转发,如果没有
向 GICD_ISENABLERn 的 bit 位写1来使能中断。
向 GICD_ICENABLERn 的 bit 位写1来禁用中断。
“转发” = 传递中断信号给CPU核心

中断首先由GIC接收。但GIC是否会将该中断传递(转发)给CPU核心,取决于以下条件
1.中断是否使能(由2.ICD_ISENABLERn/GICD_ICENABLERn控制)。 中断的优先级、目标CPU核心等其他配置是否满足。

第4步:配置CPU接口
1.优先级屏蔽:GICC_PMR

Interrupt Priority Mask Register
作用: 设置当前CPU的优先级“门槛”。CPU将只处理优先级高于此寄存器值的中断(即优先级数值小于PMR值)。
32位寄存器,只有前八位有效,因为前面的也是八位优先级在这里插入图片描述

2.优先级分组-GICC_BPR

Binary Point Register
在这里插入图片描述
GICC_BPR 寄存器里那3位 [2:0] 的值 (0到7),就定义了拆分的“分割点”。
这个分割点 BPR_Value 的含义是:8位优先级中,有多少位属于子优先级。
8位优先级: [ bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0 ]
在这里插入图片描述

第4步:打开总开关 (最后一步)
GICD_CTLR (Distributor Control Register)

作用: 分发器总开关。
在这里插入图片描述

把它理解为整个GIC分发器的“总电源开关”就对了。
在你把所有中断都精心配置好(设置好优先级、目标CPU、触发方式等)之后,最后一步就是打开这个总开关,GIC才能正式开始工作。

  • [0] - EnableGrp0 (使能组0)

    • 作用:控制 Group 0 中断的转发。
    • 0关闭。所有属于Group 0的中断,即使已经触发(处于pending状态),也会被GIC分发器拦住,不会被发送给任何CPU接口。就像闸门A关闭了。
    • 1打开。GIC分发器会根据优先级规则,将处于pending状态的Group 0中断正常转发给CPU接口。就像闸门A打开了。
  • [1] - EnableGrp1 (使能组1)

    • 作用:控制 Group 1 中断的转发。
    • 0关闭。所有属于Group 1的中断都会被拦住,不会被发送出去。就像闸门B关闭了。
    • 1打开。GIC分发器会根据优先级规则,将处于pending状态的Group 1中断正常转发给CPU接口。就像闸门B打开了。
GICC_CTLR (CPU Interface Control Register)

作用: 当前CPU接口的总开关。
GICC_CTLR 就是每个CPU核心自己的“中断接收器开关”。

主要功能:它到底控制了什么?

它主要控制两件大事:

  1. 全局开关:决定当前这个 CPU 核心是否要开始处理中断。
  2. 高级行为配置:微调一些中断处理的细节,比如如何结束中断、如何处理被屏蔽的信号等。

位域讲解 (Bit Fields)

我们直接按功能块来讲解最重要的几个位,这比按数字顺序更容易理解。

1. 最重要的全局开关

  • EnableGrp0 (位 0)

    • 功能Group 0 (安全中断, 通常是 FIQ) 的总开关。
    • 设置为 1: 允许当前 CPU 核心接收并处理来自 GIC 的 Group 0 中断。
    • 设置为 0: 屏蔽当前 CPU 核心的所有 Group 0 中断。即使 GIC 已经把中断信号发过来了,到这里也会被挡住。
  • EnableGrp1 (位 1)

    • 功能Group 1 (非安全中断, 通常是 IRQ) 的总开关。
    • 设置为 1: 允许当前 CPU 核心接收并处理来自 GIC 的 Group 1 中断。
    • 设置为 0: 屏蔽当前 CPU 核心的所有 Group 1 中断。

使用要点:在系统初始化时,必须根据你需要处理的中断类型,将这两位或其中一位设置为 1。这是让中断系统工作的最基本前提。

2. 中断结束行为的配置

  • EOImode (位 9)
    • 功能:控制**“中断结束”** (GICC_EOIR 寄存器) 的行为模式。
    • 背景:当你向 GICC_EOIR 写入一个值表示中断处理完毕时,GIC 硬件内部会做两件事:
      1. 优先级降低 (Priority Drop):允许其他中断可以抢占。
      2. 中断去激活 (Deactivation):将中断状态从“Active”移除。
    • EOImode = 0 (默认模式):写一次 GICC_EOIR,硬件自动完成上面两件事。简单直接。
    • EOImode = 1 (分离模式):写一次 GICC_EOIR,硬件只做第一件事(降低优先级)。你需要再向另一个寄存器 GICC_DIR 写入相同的值,才能完成第二件事(去激活)。这是一种性能优化手段,用于复杂的嵌套中断,普通应用用不到。

3. 中断信号传递的微调

  • FIQEn (位 3)

    • 功能:决定 GIC 的 CPU 接口是否要将 Group 0 的中断信号物理地传递给 CPU 的 FIQ 引脚。
    • 设置为 1: 正常传递,触发 FIQ 异常。
    • 设置为 0: 不传递。等于在软件层面掐断了 FIQ 信号线。
  • CBPR (位 4) - Control Bypass and Priority Register

    • 功能:控制 Group 0 和 Group 1 中断的优先级处理方式。
    • CBPR = 0: Group 0 和 Group 1 的中断共享同一个优先级寄存器 (GICC_PMR)。
    • CBPR = 1: Group 0 和 Group 1 使用各自独立的优先级处理逻辑。这允许你为安全中断和非安全中断设置不同的优先级屏蔽策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89470.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89470.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【IoTDB 线上小课 17】开源 ≠ 免费,3 分钟总结开源商用指南

【IoTDB 视频小课】第十七期,解答你最关心的开源商业使用问题!关于 IoTDB,关于物联网,关于时序数据库,关于开源...一个问题重点,3-5 分钟,我们讲给你听:原来开源商业化有这么多规则开…

VUE项目学习笔记 v-for绑定数据,该数据异步获取,同时需要对v-for的DOM节点进行js操作

问题描述:项目里有一个轮播图,轮播图的图片数据从服务器获取,用v-for生成DOM在页面中显示,轮播图插件会通过new Swiper给DOM添加CSS、事件等,实现轮播效果。在这里存在操作顺序问题:当服务器返回图片数据后…

Science | 如何利用“T细胞+组蛋白乙酰化”两大国自然热点?T细胞耗竭机制与代谢-表观遗传调控的新范式

CD8⁺T细胞耗竭(T cell exhaustion)是肿瘤免疫治疗的核心瓶颈,其表观遗传重塑机制(如组蛋白修饰)是当前国自然重点资助的前沿方向。耗竭T细胞(TEX)是指在慢性感染(如持续性病毒感染&…

Logback 配置的利器:深入理解<property>与<variable>

在构建现代 Java 应用程序时,日志是不可或缺的一部分。一个健壮的日志系统不仅能帮助我们监控应用程序的运行状态,还能在问题发生时提供关键的诊断信息。Logback 作为 SLF4J 的一个流行实现,以其高性能和灵活的配置而广受开发者喜爱。 然而&a…

Java中excel字典转换

✅ 背景说明EasyExcel 原生的 ExcelProperty 注解不支持 dictType(不像那样有 Excel(dictType"xxx")),所以如果你想实现字典翻译功能,就需要自己实现 Converter 接口,比如 DictConvert。✅ 什么是 DictConve…

数据结构-3(双向链表、循环链表、栈、队列)

一、思维导图二、双向循环链表的判空、尾插、遍历(反向)、尾删class Node:def __init__(self, data):self.data dataself.next Noneself.prior Noneclass circularDoublyLinkedList():def __init__(self):self.head Noneself.tail Noneself.size 0def isEmpty(self):retu…

IDEA运行Tomcat一直提示端口被占用(也查不到该端口)

首先查看是否是因为Java程序异常终止,进程没有完全释放导致。打开资源管理器,找到所有的java.exe,强制结束任务。如果仍然不行,那就极可能还是开启了hyper-V虚拟化,查看排除的tcp端口范围端口号没被占用却提示占用&…

AWS Lambda 最佳实践:构建高效无服务器应用的完整指南

引言 AWS Lambda 作为无服务器计算的核心服务,让开发者能够专注于业务逻辑而无需管理服务器。本文将通过实际案例和代码示例,分享 Lambda 开发中的关键最佳实践。 1. 函数设计原则 单一职责原则 每个 Lambda 函数应该只做一件事,这样更容易测试、维护和扩展。 # ❌ 不推…

29、鸿蒙Harmony Next开发:深浅色适配和应用主题换肤

目录 应用深浅色适配 应用跟随系统的深浅色模式 应用主动设置深浅色模式 系统默认判断规则 使用建议与限制 设置应用内主题换肤 概述 自定义主题色 设置应用内组件自定义主题色 设置应用局部页面自定义主题风格 设置应用页面局部深浅色 系统缺省token色值 应用深浅…

源鉴SCA4.9︱多模态SCA引擎重磅升级,开源风险深度治理能力再次进阶

SCA技术已成为数字供应链开源治理的关键入口。源鉴SCA深度融合悬镜原创专利级AI智能代码疫苗技术,是国内首款集源码组件成分分析、代码成分溯源分析、制品成分二进制分析、容器镜像成分扫描、运行时成分动态追踪及开源供应链安全情报预警分析等六大核心引擎为一体的…

Git语义化提交规范及提交模板设置

Git语义化提交规范(Conventional Commits) 📚 常见的语义化提交类型包括:类型含义说明feat✨ 新增功能(feature)fix🐛 修复 bugdocs📚 修改文档(如 README)st…

用TensorFlow进行逻辑回归(五)

Softmax分类#List3-50%matplotlib inlineimport numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltx1_label0 np.random.normal(1, 1, (100, 1))x2_label0 np.random.normal(1, 1, (100, 1))x1_label1 np.random.normal(5, 1, (100, 1))x2_label1 np.ran…

基于 Django + 协同过滤算法的电影推荐系统设计与实现

🎬 基于 Django 协同过滤算法的电影推荐系统设计与实现✍️ 本项目由成都理工大学宜宾校区的三位同学曾铭杨、杨皓麟、陈禧锦共同完成。项目以豆瓣电影数据为基础,通过协同过滤算法为用户构建个性化电影推荐服务,是一款集数据爬取、推荐算法…

小白全栈项目部署指南

小白全栈项目部署指南:前端后端数据库完整攻略 📖 写在前面 当你学会了基础的静态网站部署后,是不是想挑战更有趣的项目?比如一个能够注册登录、保存数据的完整应用? 这就需要学习全栈项目部署了! 别被&quo…

C# Linq 左关联查询详解与实践

在 C# 开发中,Linq(Language Integrated Query)提供了强大的数据查询能力,尤其是在处理集合间的关联操作时。本文将详细解析 C# Linq 中的左关联查询,并通过实际案例说明其用法。左关联查询基础左关联(Left…

【机器学习深度学习】LoRA 微调详解:大模型时代的高效适配利器

目录 前言 一、LoRA 的核心思想 二、LoRA 为什么高效? ✅ 1. 参数效率 ✅ 2. 内存友好 ✅ 3. 即插即用 三、LoRA 适用场景 四、LoRA 实践建议 五、LoRA 和全参数微调对比 六、 LoRA的具体定位 📌 总结 🔗 延伸阅读 前言 在大模型…

vue页面不销毁的情况下再返回,总是执行created,而不触发 activated

vue页面不销毁的情况下再返回,总是执行created,而不触发 activated 原因: 没有进行页面缓存地址和页面组件的name没对上 解决方案: 组件只有在被 包裹时才会触发 activated 和 deactivated 生命周期 如果没有被缓存,每次进入路由…

从 C# 到 Python:6 天极速入门(第二天)

作为一名资深 C# 开发者,我们在第一天已经掌握了 Python 的基础语法框架。今天我们将深入 Python 的特色语法与高级特性,通过实际项目开发场景的代码对比,理解这些特性在真实业务中的应用价值。一、简洁语法糖:项目开发中的实战应…

MyBatis 动态 SQL:让 SQL 语句随条件灵活变化

目录 1. 动态SQL 1.1. if 1.1.1. 持久层接口添加方法 1.1.2. 映射文件添加标签 1.1.3. 编写测试方法 1.2. where 1.3. set 1.4. choose、when、otherwise 1.5. foreach 1.5.1. 遍历数组 1.5.2. 遍历Collection 1.5.3. 遍历Map 2. 总结 前言 本文来讲解MyBatis的动…

AI 驱动的仪表板:从愿景到 Kibana

作者:来自 Elastic Jeffrey Rengifo 及 Toms Mura 使用 LLM 处理图像并将其转换为 Kibana 仪表板。 想获得 Elastic 认证?了解下一次 Elasticsearch Engineer 培训的举办时间! Elasticsearch 拥有众多新功能,帮助你为你的使用场景…