一、硬件介绍

1. 开关功能定义

  • 共 3 个开关(两红一黄),功能分工明确:
    • 中间开关:复位按钮
    • 左边开关:低功耗按钮
    • 右边开关:用户独立控制的试验按键(核心控制对象)

2. 核心电平逻辑(原理图关键信息)

  • 开关状态与电平对应关系:
    • 开关断开时:引脚输出高电平
    • 开关按下时:引脚输出低电平(代码中判断按键状态的核心依据)

二、轮询方式按键控制

轮询方式通过 “反复查询引脚电平” 判断按键状态,适用于简单、无实时性要求的场景。

1. 前期准备:手册查阅

需参考的核心文档:

  • 《IMX6ULL_MINI_V2.2 (Mini 底板原理图).pdf》(确定引脚连接)
  • 《IMX6ULL 参考手册.pdf》(配置引脚复用、电气特性、GPIO 寄存器)

2. 关键步骤:按键初始化

初始化需完成 “引脚复用→电气特性配置→GPIO 方向→时钟使能” 四步,以GPIO1_IO18(对应 UART1_CTS_B 引脚复用) 为例:

(1)引脚复用功能配置(IOMUXC)
  • 参考手册章节:Chapter 32(IOMUX Controller)
  • 核心寄存器:IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B: 低四位(0101)
  • 配置函数:IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
  • 关键位解析:
    • SION(信号监控)1:0(禁用,输入路径由功能决定)
    • MUX_MODE(复用模式)4:0101(ALT5,将引脚复用为 GPIO1_IO18)

(2)引脚电气特性配置(PAD_CTL)
  • 参考手册章节:Chapter 32:IOMUX Controller (IOMUXC)
  • 核心寄存器:IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B
  • 配置函数:IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);
  • 配置位拆解(按手册定义):
    配置项位值含义说明
    HYS(压摆率)0禁用滞后功能(输入无需开启)
    PUS(上下拉)1122KΩ 上拉(确保开关断开时为高电平)
    PUE(拉 / 保持)1选择 “拉模式”(而非保持模式)
    PKE(拉 / 保持使能)1使能拉功能
    ODE(漏极开漏)0禁用漏极开漏(输入场景无需开启)
    SPEED(速度)10中速(100MHz,满足按键检测需求)
    DSE(驱动能力)000禁用输出驱动(引脚为输入,输出驱动无效)
    SRE( slew rate)0慢摆率(输入无影响)

(3)GPIO 方向配置(输入模式)(GDIR)
  • 参考手册章节:Chapter 28(General Purpose Input/Output)
  • 核心寄存器:GPIOx_GDIR(GPIO 方向寄存器,x=1 对应 GPIO1 组)
  • 配置代码:GPIO1->GDIR &= ~(1 << 18);
    (清第 18 位,0 表示输入模式;1 为输出模式)
(4)GPIO 时钟使能(CCM)
  • 参考手册章节:Chapter 18(Clock Controller Module)
  • 核心寄存器:CCM_CCGR1(GPIO1 组共用时钟门控寄存器)
  • 功能:开启 GPIO1 组时钟(外设需时钟才能工作,默认可能关闭)

3. 运行时:按键状态检测

通过读取 GPIO 数据寄存器判断按键状态:

  • 参考手册章节:Chapter 28:General Purpose Input/Output (GPIO)
  • 核心寄存器:GPIOx_DR(GPIO 数据寄存器)
  • 检测逻辑:
    • 若 (GPIO1->DR & (1 << 18)) != 0:开关断开(高电平)→ 按键未按下
    • 若 (GPIO1->DR & (1 << 18)) == 0:开关按下(低电平)→ 按键触发

4. 轮询方式的致命问题:漏查

(1)问题场景

当主程序承担大量、复杂、耗时的业务(如数据处理、多设备控制)时,轮询周期被拉长,可能错过按键触发的 “短暂低电平”(即漏查)。

(2)模拟验证

delay(0x7FFFFF);模拟耗时业务,此时按键按下的低电平可能在 delay 期间结束,轮询无法检测到。

(3)典型风险场景

实时性要求高的场景(如汽车刹车信号检测、工业急停按钮),漏查会导致严重安全事故。

三、中断方式按键控制

中断可让 CPU“优先处理紧急任务(如按键)”,处理完后返回原业务,解决轮询漏查问题。

1. 中断核心概念

  • 定义:CPU 可打断当前执行的任务,转去处理更紧急的中断请求,处理完成后恢复现场并继续原任务
  • 本场景中断源:GPIO 外部中断(EINT,由按键按下触发)
  • 角色分工:
    • Kernel(内核):被中断的 “原任务执行者”
    • 外设(GPIO):发出中断请求的 “触发者”

---中断相关寄存器                  I  开头

这些寄存器是 NXP i.MX 系列(如 i.MX6ULL、i.MX RT1062 等)通用 I/O(GPIO)模块的核心寄存器,从上到下依次为

  1. GPIOx_DR:Data Register(数据寄存器)

    • 功能:读写 GPIO 引脚的电平状态(输出模式下写值、输入模式下读值)。
  2. GPIOx_GDIR:Direction Register(方向寄存器)

    • 功能:配置引脚为输入(位设为0)或输出(位设为1)。
  3. GPIOx_PSR:Pin Status Register(引脚状态寄存器)

    • 功能:实时反映物理引脚的当前电平(与DR可能存在差异,推荐读取PSR获取实际状态)。
  4. GPIOx_ICR1:Interrupt Configuration Register 1(中断配置寄存器 1)

    • 功能:配置低 16 位引脚的中断触发方式(上升沿、下降沿、高电平或低电平)。
  5. GPIOx_ICR2:Interrupt Configuration Register 2(中断配置寄存器 2)

    • 功能:配置高 16 位引脚的中断触发方式(与ICR1功能一致,仅对应引脚范围不同)。
  6. GPIOx_IMR:Interrupt Mask Register(中断屏蔽寄存器)

    • 功能:控制是否使能引脚的中断(对应位设为1则允许中断,0则屏蔽)。
  7. GPIOx_ISR:Interrupt Status Register(中断状态寄存器)

    • 功能:记录哪些引脚发生了中断(写1可清除中断标志)。
  8. GPIOx_EDGE_SEL:Edge Select Register(边沿选择寄存器)

    • 功能:选择引脚是否使用边沿触发(设为1时,ICR1/ICR2配置无效,仅响应边沿;设为0时,使用ICR1/ICR2的配置)。

这些寄存器共同实现了 GPIO 的输入输出控制、中断配置与状态管理,是嵌入式开发中操作 GPIO 的核心工具。

2. 中断处理流程(6 步)

  1. 中断请求:外设(GPIO)检测到按键按下,发出中断信号。
  2. 中断检查:CPU 判断是否允许响应中断(需未被屏蔽)。
  3. 优先级判断:若存在多个中断,优先处理高优先级请求。
  4. 保护现场:保存当前 CPU 寄存器状态(确保后续能恢复原任务)。
  5. 执行中断服务函数(ISR):处理中断逻辑(如按键触发的业务)。
  6. 恢复现场:恢复保存的寄存器状态,回到原任务继续执行。

3. 关键组件:中断控制器 GIC

GIC(Generic Interrupt Controller,通用中断控制器)是 ARM 架构中管理中断的核心模块,负责中断分发、优先级控制。

(1)参考文档
  • 《ARM Generic Interrupt Controller (ARM GIC 控制器) V2.0.pdf》
  • 《IMX6ULL 参考手册.pdf》Chapter 3.2(Cortex A7 interrupts)
  • 《MCIMX6Y2.h》(定义 IRQn_Type 中断编号)
(2)GIC V2.0 核心特性
  • V2.0设计可以为8个内核提供中断控制服务,但我们使用的IMX6ULL只有一个内核,图中所示只有processor 0
  • 每个内核能够相应1020个中断源,其中0~15是SGI,16~31是PPI,能够作为外设中断源的是SPI32~1019
  • 支持 8 个 CPU 核心(IMX6ULL 仅用 1 个核心,对应 processor 0)。
  • 共 1020 个中断源,按类型分为 3 类:
    中断类型范围特点与用途
    SGI0~15软件中断(Software-generated),用于多核通信
    PPI16~31私有中断(Private),每个 CPU 核心独有
    SPI32~1019共享中断(Shared),外设中断专用(如 GPIO)

Distributor(分发器):

  • (1)SGI(Software-generated Interrupt),软件中断:

    由软件触发引起的中断,通过向寄存器GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。

  • (2)PPI(Private Peripheral Interrupt),私有中断:

    我们说了 GIC 是支持多核的,每个核肯定有自己独有的中断。这些独有的中断肯定是要指定的核心处理,因此这些中断就叫做私有中断;

  • (3)SPI(Shared Peripheral Interrupt),共享中断:

    (注意!不是 SPI 总线那个中断),这类中断泛指所有

(3)GIC 核心模块
  1. Distributor(分发器)
    • 管理所有中断源(SGI/PPI/SPI)。
    • 功能:中断屏蔽、优先级设置、向目标 CPU 分发中断。
  2. CPU Interface(CPU 接口)
    • 连接 GIC 与 CPU 核心。
    • 功能:传递中断请求给 CPU、确认中断处理完成。
(4)IMX6ULL 中断编号对应
  • 手册定义:Cortex A7 中断编号范围 0~128。
  • 头文件定义:IRQn_Type(外设中断编号 0~159,需与 GIC 的 SPI 编号对应)。

(5) GIC相关(图)

 core_ca7.h

4. 底层支撑:协处理器 CP15--------主要使用cp10.11.15 

Cortex-A7 的协处理器 CP15(CP0~CP15)负责系统级控制,中断配置需依赖其关键寄存器。

(1)参考文档
  • 架构参考手册《Cortex-A7 Technical Reference Manual.pdf》Chapter 4(System Control)
(2)CP15 核心功能---------         (跟数据存储相关的)
  • 系统控制与配置、MMU(内存管理单元)配置、Cache 配置、虚拟化与安全、性能监控。
(3)CP15 寄存器读写指令  MRC
  • 读寄存器MRC <coproc>, <opc1>, <Rt>, <CRn>, <CRm>, {, <opc2>}
    (如读取 SCTLR 寄存器:mrc p15,0,r0,c1,c0,0
  • 写寄存器MCR <coproc>, <opc1>, <Rt>, <CRn>, <CRm>, {, <opc2>}
    (如写入 SCTLR 寄存器:mcr p15,0,r0,c1,c0,0

(4)中断相关关键寄存器
寄存器功能描述关键位 / 配置示例
c0: MIDR存储内核基本信息(如型号、版本)调试时确认内核型号
c1: SCTLR系统控制寄存器(中断向量、Cache 使能)bit13(V):0 = 向量基址 0x00000000;1=0xFFFF0000
bit12(I):1 = 使能指令 Cache
demo:
mrc p15,0,r0,c1,c0,0
bic r0,r0,#(1<<13)
orr r0,r0,#(1<<12)
mcr p15,0,r0,c1,c0,0
c12: VBAR中断向量基地址寄存器(指定中断服务表地址)demo:__get_VBAR(0x87800000);(设置基址为 0x87800000)
c15: CBAR存储 GIC 寄存器的物理基地址(定位 GIC)demo:mrc p15,4,r0,c15,c0,0(读取基地址到 r0)
(5)相关图(c0-c15)

c0 - MIDR

c12 - VBAR

 c1 - SCTLR4

5. 中断代码设计要点

中断相关寄存器组


c0 registers:
MIDR(Main ID Register):存储内核的一些基本信息


c1 registers:
SCTLR(System Control Register)
bit13:V    
bit12:I        

    
c12 registers:
VBAR(Vector Base Address Register)    

                
c15 registers:
CBAR(Configuration Base Address Register)

(1)代码编写逻辑

需严格遵循 “中断流程”,对应代码步骤(结合上面的图):

  1. 配置 GPIO 为中断触发模式(如下降沿触发:按键按下时电平从高→低)。
  2. 配置 GIC(使能对应 SPI 中断、设置优先级、绑定 CPU 核心)。
  3. 配置 CP15(设置中断向量基址 VBAR、使能中断响应)。
  4. 编写中断服务函数(ISR):处理按键逻辑(如置位标志、调用业务函数)。
  5. 使能全局中断(CPU 允许响应中断)。

(2)完整代码 (独立interrupt.c/.h) key5

main.c

key.c

interrupt.c

interrupt.h

start.S

**********************************

启动代码中添加对IRQ中断的handler函数跳转;

在_start_hander中加入对异常向量表的修改函数

(3)降低程序耦合性(遵循 OCP 原则)

OCP 原则(开放 - 关闭原则):对修改关闭,对拓展开放(避免修改原有代码即可新增功能)。

降低程序耦合性(1)满足用户基本需求(2)程序稳定可靠(3)满足OCP(open close principle)原则对代码的修改是关闭的,对代码的拓展是开放的

实现措施:

  1. 模块封装
    • 封装 GPIO 模块:提供GPIO_Init()GPIO_SetInterruptMode()等接口,屏蔽底层寄存器操作。
    • 封装中断模块:提供GIC_Init()Interrupt_Register()等接口,统一管理中断配置。
  2. 回调函数注册
    • 中断服务函数中不直接写业务逻辑,而是调用 “注册的回调函数”。
    • 示例:用户新增按键业务时,只需调用Interrupt_Register(KEY_IRQn, User_KeyCallback),无需修改中断模块代码。
  3. 稳定性保障
    • 中断服务函数需 “快进快出”(避免耗时操作,如 printf、delay)。
    • 增加中断标志位(避免中断嵌套导致的逻辑混乱)。
KEY、中断模块优化
//interrupt.c#include "interrupt.h"
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "core_ca7.h"static irq_interrupt_t interrupt_Vector_table[160] = {NULL};void system_interrupt_init(void)
{//基地址映射__set_VBAR(0x87800000);//1.GIC初始化GIC_Init();
}void system_interrupt_register(IRQn_Type irq, irq_interrupt_t handler)
{interrupt_Vector_table[irq] = handler;
}void system_interrupt_handler(IRQn_Type irq)
{if (interrupt_Vector_table[irq] != NULL){interrupt_Vector_table[irq]();}
}//key.c#include "key.h"
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "interrupt.h"
#include "led.h"void key_16_31_handler(void)
{if((GPIO1->ISR & (1 << 18)) !=0){led_nor();//中断处理GPIO1->ISR |= (1 << 18);   }
}void key_init(void)
{//复用功能 配置为GPIO1_18IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);//电气特性配置IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF0B0);//引脚方向GPIO1->GDIR &= ~(1 << 18);//中断触发方式配置GPIO1->ICR2 |= (3 << 4); //中断源屏蔽寄存器解除屏蔽GPIO1->IMR |= (1 <<18);//注册中断处理函数system_interrupt_register(GPIO1_Combined_16_31_IRQn, key_16_31_handler);//2.GIC中断使能GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);GIC_SetPriority(GPIO1_Combined_16_31_IRQn, 0);
}int key_check(void)
{return (GPIO1->DR & (1 << 18)) == 0;
}
GPIO 模块优化(支持多引脚扩展)

通过结构体参数传递 GPIO 配置,支持多按键扩展,无需重复编写代码

//gpio.c#include "gpio.h"void gpio_init(GPIO_Type *gpio, int pin, gpio_pin_t *data)
{if (data->dir == gpio_output){gpio->GDIR |= (1 << pin);if(data->def_val == 1){gpio->DR |= (1 << pin);}else{gpio->DR &= ~(1 << pin);}}else{gpio->GDIR &= ~(1 << pin);}
}int gpio_read(GPIO_Type *gpio, int pin)
{return ((gpio->DR & (1 << pin)) != 0);
}void gpio_write(GPIO_Type *gpio, int pin, int data){if (data == 0){gpio->DR &= ~(1 << pin);}else{gpio->DR |= (1 << pin);}
}//interrupt.c#include "interrupt.h"
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "core_ca7.h"static irq_interrupt_t interrupt_Vector_table[160] = {NULL};void system_interrupt_init(void)
{//基地址映射__set_VBAR(0x87800000);//1.GIC初始化GIC_Init();
}void system_interrupt_register(unsigned int irq, irq_interrupt_t handler)
{interrupt_Vector_table[irq] = handler;
}void system_interrupt_handler(IRQn_Type irq)
{if (interrupt_Vector_table[irq] != NULL){interrupt_Vector_table[irq]();}
}//key.c#include "key.h"
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "core_ca7.h"
#include "interrupt.h"
#include "led.h"void key_16_31_handler(void)
{if((GPIO1->ISR & (1 << 18)) !=0){led_nor();//中断处理GPIO1->ISR |= (1 << 18);   }
}void key_init(void)
{//复用功能 配置为GPIO1_18IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);//电气特性配置IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF0B0);//引脚方向GPIO1->GDIR &= ~(1 << 18);//中断触发方式配置GPIO1->ICR2 |= (3 << 4); //中断源屏蔽寄存器解除屏蔽GPIO1->IMR |= (1 <<18);//注册中断处理函数system_interrupt_register(GPIO1_Combined_16_31_IRQn, key_16_31_handler);//2.GIC中断使能GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);GIC_SetPriority(GPIO1_Combined_16_31_IRQn, 0);
}int key_check(void)
{return (GPIO1->DR & (1 << 18)) == 0;
}//led.c#include "led.h"
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "gpio.h"void led_init(void)
{IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0x10B0);//GPIO1->GDIR |= (1 << 3);//led_off();gpio_pin_t io_3;io_3.dir = gpio_output;io_3.def_val = 1;gpio_init(GPIO1, 3, &io_3);
}void led_on(void)
{gpio_write(GPIO1, 3, 0);
}void led_off(void)
{gpio_write(GPIO1, 3, 1);
}void led_nor(void)
{gpio_write(GPIO1, 3, !gpio_read(GPIO1, 3)); 
}

(4) 代码编写思路历程(根据框  图)

 使能

传递中断号

优先级·0最高---------越小越高

 强制内联静态内联函数


地址访问问题·

 C_IAR           基地址 + 0x200C (偏移地址)

 C_EOIR        基地址 + 0x2010 (偏移地址)

获取GIC基地址         ==== 手册

对照写------ 把GIC基地址读到R0寄存器里面(R0  base 基地址)

coproc 协处理器 

         存到R1里

c15  CBAR->

当前进度

下面是kernal

mrc p15, 0, r0, c1, c0, 0                参数对应cp1内容,修改异常向量表映射方式
bic r0, r0, #(1 << 13)                       bit13位为V清零,VBAR配置中断向量基地址
orr r0, r0, #(1 << 12)                       bit12位为I 置一,iche使能位打开
mcr p15, 0, r0, c1, c0, 0

 对照下图

  

跳转

为什么有偏移量?

四、核心对比:轮询 vs 中断

对比维度轮询方式中断方式
实时性差(易漏查)好(优先响应紧急任务)
CPU 资源占用高(持续查询)低(仅中断时占用)
适用场景简单、无实时性需求(如 LED 闪烁)实时性需求高(如刹车、急停)
代码复杂度低(无需配置中断)高(需配置 GIC、CP15)

--------------知识点梳理补充------------------

在 ARM 架构中,GIC(Generic Interrupt Controller,通用中断控制器) 是负责管理系统中断的关键组件,它统一处理来自外设、软件或其他硬件的中断请求,并将其分发到相应的处理器核心(CPU)进行处理。GIC 的存在使得多核心 ARM 系统中的中断管理更加标准化、高效化。

GIC 的核心功能

  1. 中断源管理:识别和分类系统中的各种中断(如外设中断、软件触发中断、定时器中断等)。
  2. 优先级控制:为不同中断分配优先级,确保高优先级中断优先被处理。
  3. 中断路由:将中断分发到指定的 CPU 核心(支持多核系统中中断的灵活分配)。
  4. 中断状态跟踪:记录中断的触发、处理、完成等状态,协调 CPU 与中断源的交互。

GIC 的主要版本

GIC 随着 ARM 架构的发展迭代了多个版本,每个版本新增了对多核、虚拟化等场景的支持:

  • GICv1:早期版本,支持基本的中断分发,主要用于单核心或简单多核系统(如 ARMv7 架构)。
  • GICv2:增加了对多核系统的完善支持,引入了虚拟化相关的基础功能(如安全扩展),支持最多 8 个 CPU 核心。
  • GICv3/GICv4:针对 ARMv8-A(64 位)架构设计,支持更多核心(最多 255 个),强化了虚拟化能力(如支持虚拟机直接处理中断),并引入了新的中断类型和分发机制(如 LPI,Locality-specific Peripheral Interrupt)。

GIC 的核心组件

GIC 的功能通过两个主要逻辑单元实现:

  1. Distributor(分发器)

    • 全局管理所有中断源,维护中断的使能 / 禁用状态。
    • 对中断进行优先级排序(优先级由软件配置)。
    • 根据配置将中断路由到一个或多个 CPU 核心(支持 “中断亲和性” 设置)。
  2. CPU Interface(CPU 接口)

    • 每个 CPU 核心对应一个 CPU 接口,负责与本核心交互。
    • 接收来自 Distributor 的中断请求,通知 CPU(如通过 IRQ/FIQ 信号)。
    • 处理 CPU 对中断的响应(如中断确认、处理完成通知)。

中断类型

GIC 管理的中断分为三类,以适应不同场景:

  • SGI(Software Generated Interrupt,软件生成中断):由软件通过写寄存器触发,用于核心间通信(如多核系统中核心 A 通知核心 B 处理任务)。
  • PPI(Private Peripheral Interrupt,私有外设中断):属于特定 CPU 核心的私有中断(如每个核心独立的定时器中断),仅能被对应的核心处理。
  • SPI(Shared Peripheral Interrupt,共享外设中断):由系统中的共享外设(如 UART、GPIO)产生,可被路由到任意一个或多个 CPU 核心。

工作流程简述

  1. 外设或软件产生中断请求,发送到 GIC 的 Distributor。
  2. Distributor 检查中断是否被使能、优先级是否满足,并根据路由规则选择目标 CPU。
  3. 目标 CPU 的 CPU Interface 接收中断,通过 IRQ/FIQ 信号通知 CPU。
  4. CPU 响应中断,通过 CPU Interface 向 GIC 确认中断(标记为 “处理中”)。
  5. CPU 处理完中断后,通过 CPU Interface 通知 GIC 中断处理完成,GIC 更新中断状态。

总结

GIC 是 ARM 系统中中断管理的 “中枢”,通过标准化的架构支持多核、虚拟化等复杂场景,确保中断高效、有序地被处理,是嵌入式系统、服务器等 ARM 设备正常运行的核心组件之一。

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

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

相关文章

【QT随笔】什么是Qt元对象系统?Qt元对象系统的核心机制与应用实践

【QT随笔】什么是Qt元对象系统&#xff1f;Qt元对象系统的核心机制与应用实践 之所以写下这篇文章&#xff0c;是因为前段时间自己面试的时候被问到了&#xff01;因此想借此分享一波&#xff01;&#xff01;&#xff01;本文主要详细解释Qt元对象系统的概念、作用及实现机制…

从技术视角解析加密货币/虚拟货币/稳定币的设计与演进

随着加密货币行情的持续走高&#xff0c;除了资产价值&#xff0c;我想试着从底层程序设计与架构角度解析比特币、以太坊、稳定币以及新兴公链的核心技术方案。作者在2018年设计实施了基于区块链技术的金融项目&#xff0c;并荣获了国家课题进步奖&#xff0c;对加密货币及场景…

[MySQL]Order By:排序的艺术

[MySQL]Order By&#xff1a;排序的艺术 1. 简介 在数据库管理中&#xff0c;数据的排序是一项至关重要的操作。MySQL 的 ORDER BY 子句为我们提供了强大而灵活的功能&#xff0c;用于对查询结果进行排序。无论是按照字母顺序排列名称&#xff0c;还是根据日期或数值进行升序…

【工具代码】使用Python截取视频片段,截取视频中的音频,截取音频片段

目录 ■截取视频方法 1.下载 ffmpeg-8.0-essentials_build 2.配置到环境变量 3.python代码 4.运行 5.效果 ■更多 截取视频中的音频 截取音频 Sony的CR3图片&#xff0c;转换为JPG ■截取视频方法 1.下载 ffmpeg-8.0-essentials_build "https://www.gyan.de…

Three.js 平面始终朝向相机

instanceMesh需要让实例像粒子一样始终朝向相机 可以如下处理shaderexport const billboarding // billboarding函数的GLSL实现 // 参数: // - position: 顶点动态位置偏移 // - positionLocal: mesh的position // - horizontal: 水平方向是否朝向相机 // - vertical: 垂直方…

旗讯 OCR 识别系统深度解析:一站式解决表格、手写文字、证件识别难题!

在数字化办公日益普及的今天&#xff0c;“纸质文档转电子”“图片信息提取” 等需求愈发频繁&#xff0c;但传统手动录入不仅效率低下&#xff0c;还容易出现数据错误。近期发现一款实用性极强的工具 —— 旗讯数字 OCR 识别系统&#xff0c;其覆盖多场景的识别功能、极简操作…

MissionPlanner架构梳理之(十四)日志浏览

概述和目的 Mission Planner 中的日志浏览系统提供了加载、查看、分析和解读 ArduPilot 驱动的飞行器生成的飞行日志的工具。飞行日志包含飞行操作期间记录的关键遥测数据&#xff0c;使用户能够查看飞行性能、诊断问题并从过去的飞行中获取见解。 本页记录了日志浏览系统的架…

机器学习shap分析案例

在进行数据分析和机器学习时经常用到shap&#xff0c;本文对shap相关的操作进行演示。波士顿数据集链接在这里。 SHAP Analysis Guide Set up 导入必要包 import pandas as pd import numpy as np import lightgbm as lgb import matplotlib import matplotlib.pyplot as p…

网络编程相关函数

1. 套接字操作相关1.1 socketint socket(int domain, int type, int protocol);参数说明int domain协议族&#xff0c;常用 AF_INET&#xff08;IPv4&#xff09;、AF_INET6&#xff08;IPv6&#xff09;int type套接字类型&#xff0c;SOCK_DGRAM&#xff08;UDP&#xff09;、…

ESLint 自定义 Processor(处理器)

ESLint 自定义 Processor&#xff08;处理器&#xff09; &#x1f539; 什么是 Processor&#xff1f; 在 ESLint 中&#xff0c;Processor&#xff08;处理器&#xff09;是一种扩展机制&#xff0c;允许处理非标准 JavaScript/TypeScript 文件。默认情况下&#xff0c;ESLin…

C++语法 | static静态|单例模式

这里写目录标题static 关键字静态局部变量 vs 局部变量静态全局变量 vs 全局变量静态成员变量 vs 成员变量静态成员函数单例模式static 关键字 在此之前, 先了解一下 static 关键字 静态局部变量 vs 局部变量 在静态局部变量中&#xff0c;变量不会在函数调用结束后销毁&…

KEDA/HPA/VPA 三件套:ABP 后台作业的事件驱动伸缩

&#x1f680; KEDA/HPA/VPA 三件套&#xff1a;ABP 后台作业的事件驱动伸缩 &#x1f4da; 目录&#x1f680; KEDA/HPA/VPA 三件套&#xff1a;ABP 后台作业的事件驱动伸缩0. TL;DR ✨1. 背景与目标 &#x1f3af;2. 架构与协作机制 &#x1f9e9;2.1 系统总览&#xff08;组…

webRTc 为何深受直播实现的青睐?

WebRTC(Web Real-Time Communication)之所以在直播场景中备受青睐,核心原因在于它天然契合了现代直播对低延迟、实时互动、跨平台兼容性的核心需求,同时大幅降低了实时音视频开发的门槛。具体来说,其优势体现在以下几个方面: 1. 超低延迟,满足实时互动需求 传统直播协…

HarmonyOS迷宫游戏鸿蒙应用开发实战:从零构建随机迷宫游戏(初版)

在鸿蒙应用开发中&#xff0c;游戏类应用能很好地锻炼 UI 布局、状态管理与逻辑交互能力。本文将以一个随机迷宫游戏为例&#xff0c;详细拆解从首页设计到迷宫生成、角色控制、通关判定的完整开发流程&#xff0c;带你掌握 ArkUI 框架的核心应用技巧。一、项目整体架构本次开发…

石头科技出海升级:全球电商业财一体化与OMS实践

石头科技作为智能清洁设备领域的独角兽&#xff0c;2023 年海外收入占比超过 60%&#xff0c;产品销往全球 60 多个国家。然而&#xff0c;智能硬件出海的复杂性&#xff0c;让企业在业财管理上面临前所未有的挑战。智能硬件业财痛点 产品生命周期管理&#xff1a;研发、生产到…

《URP管线中后处理效果的创新应用与优化实践》

硬件性能的飞速提升与玩家对画面品质的高要求形成了相互推动的态势,而渲染效果作为游戏视觉体验的核心载体,直接决定了玩家对游戏的第一印象与沉浸感。后处理效果作为URP管线的“点睛之笔”,通过在渲染流程末尾对最终图像进行二次加工,能够模拟真实世界的光学现象(如光线散…

【Java 底层】JVM 垃圾回收机制深度剖析:从对象生死判定到收集器实战

【Java 底层】JVM 垃圾回收机制深度剖析&#xff1a;从对象生死判定到收集器实战 【Java 底层】JVM 垃圾回收机制深度剖析&#xff1a;从对象生死判定到收集器实战 Java 之所以被称为 “开发效率利器”&#xff0c;很大程度上得益于其自动内存管理机制 —— 开发者无需手动分配…

网络问题排查

网络连通性测试&#xff1a;ping ip持续性监测&#xff1a;ping -t ipnetstat 可以查看网络连接状态&#xff0c;可以看到显示系统的网络连接&#xff0c;路由表&#xff0c;接口等信息。netstat -nult 回车-t:显示的是tcp的连接-u:显示udp的连接-l:只显示监听状态的端口-n:显示…

tuple/dict/list 这三个数据类型在取值时候的区别

tuple&#xff08;元组&#xff09;、dict&#xff08;字典&#xff09;、list&#xff08;列表&#xff09;在取值时的区别。 1. list&#xff08;列表&#xff09; &#x1f449; 列表就是“一串有顺序的东西”&#xff0c;像排队的人。 取值方式&#xff1a;用 下标&#xf…

深度解析大模型服务性能评测:AI Ping平台助力开发者精准选型MaaS服务

深度解析大模型服务性能评测&#xff1a;AI Ping平台助力开发者精准选型MaaS服务 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff…