当前位置: 首页 > news >正文

NXP iMX8MM Cortex-M4 核心 GPT Capture 测试

By Toradex秦海

1). 简介

NXP i.MX8 系列处理器均为异构多核架构 SoC,除了可以运行 Linux 等复杂操作系统的 Cortax-A 核心,还包含了可以运行实时操作系统比如 FreeRTOS 的 Cortex-M 核心,本文就演示通过 NXP i.MX8MM 处理器集成的 Cortex-M4 核心来运行 GPT (General Purpose Timer) 输入采集功能模块的测试。

I.MX8M Mini 处理器 GPT 模块硬件比较简单,如下框图,可以实现 Capture 捕获输入功能和 Compare 定时输出功能。

NXP iMX8MM Cortex-M4 核心 GPT Capture 测试_web333.png

本文所演示的ARM平台来自于Toradex 基于NXP i.MX8M Mini ARM处理器的Verdin iMX8MM ARM嵌入式平台。

2. 准备

a). Verdin i.MX8MM ARM核心版配合Verdin Development Board,连接调试串口(载板X66)到开发主机方便调试,X66 连接了4个串口,其中第三个是 Cortex-M4 核心的默认调试串口,第四个是 Cortex-A53 核心的默认调试串口。

b). 为了测试 GPT 输入捕获, 相应的需要一个PWM 波发生设备,这里使用Toradex 基于NXP i.MX8M Plus ARM处理器的Verdin i.MX8MP 核心板配合 Dahlia Board 作为PWM output使用。同样连接调试串口(载板X18)到开发主机方便调试。

c). Verdin i.MX8MP Cortex-A53 核心系统使用Toradex Yocto Linux BSP6, 更多说明请参考这里。

d). 参考如下将 Verdin i.MX8MP PWM1 连接到 Verdin i.MX8MM GPT1 Capture 管脚,同时为了阻断载板其他电路干扰,将 Verdin Development Board X6 Pin_24 的跳线帽去掉。

Dahlia Board X20 Pin_9 -> Verdin Development Board X5Pin_24 SODIMM_252

3). Verdin i.MX8MM M4核心FreeRTOS基本资料

a). Verdin i.MX8MM HMP(Heterogeneous Multi-core Processing) 架构基本说明请参考如下:

https://developer.toradex.cn/software/cortex-m/hmp-memory-areas-on-toradex-soms/ 

b). 参考如下说明下载配置 NXP 用于开发 Cortex-M 核心的 MCUXpresso SDK

https://developer.toradex.cn/software/cortex-m/setting-up-sdk-toolchain/ 

c). Verdin i.MX8MM 编译运行 M4 firmware 操作流程请参考如下文章

https://developer.toradex.cn/software/real-time/freertos/freertos-on-the-cortex-m4-of-a-verdin-imx8mm

d). MCUXpresso SDK 包含的 sample 示例应用可以参考如下 SDK 源位置

-----------------------------

$cd <SDK_root>/boards/evkmimx8mm/

$ tree -L 2

.

├── cmsis_driver_examples

│   ├── ecspi

│   ├── enet

│   ├── i2c

│   └── uart

├── demo_apps

│   ├── hello_world

│   └── sai_low_power_audio

├── driver_examples

│   ├── ecspi

│   ├── enet

│   ├── gpio

│   ├── gpt

│   ├── i2c

│   ├── pdm

│   ├── pwm

│   ├── rdc

│   ├── sai

│   ├── sdma

│   ├── sema4

│   ├── tmu

│   ├── uart

│   └── wdog

├── evkmimx8mm.png

├── freertos_examples

│   ├── freertos_event

│   ├── freertos_generic

│   ├── freertos_hello

│   ├── freertos_mutex

│   ├── freertos_queue

│   ├── freertos_sem

│   ├── freertos_swtimer

│   └── freertos_tickless

├── multicore_examples

│   ├── rpmsg_lite_pingpong_rtos

│   └── rpmsg_lite_str_echo_rtos

└── project_template

    ├── board.c

    ├── board.h

    ├── BOARD_Project_Template_evkmimx8mm.cmake

    ├── clock_config.c

    ├── clock_config.h

    ├── peripherals.c

    ├── peripherals.h

    ├── pin_mux.c

    └── pin_mux.h

-----------------------------

4). Verdin i.MX8MM Cortex-M4核心FreeRTOS GPT Capture示例驱动开发

a). Verdin i.MX8MM MCUXpresso SDK 已经包含一个简单的 GPT Capture sample驱动,本文基于此 sample 进行修改测试。

-----------------------------

$cd <SDK_root>/boards/evkmimx8mm/driver_examples/gpt/capture

$ tree -L 1

.

├── armgcc

├── board.c

├── board.h

├── clock_config.c

├── clock_config.h

├── empty_rsc_table.c

├── fsl_iomuxc.h

├── gpt_capture.c

├── gpt_capture_v3_14.xml

├── pin_mux.c

├── pin_mux.h

└── readme.md

-----------------------------

b). 首先先确认 pin_mux 定义以及其他 i.MX8MM 初始化基本配置,如果需要可以进行修改

./ pin_mux.h/pin_mux.c 用于确定项目中使用的管脚定义,本文中使用的正好就是示例默认的 GPT1 Capture1 管脚,因此无需修改。如果用到其他管脚,就需要进行修改,支持的所有管脚定义可以参考 fsl_iomuxc.h 文件。

-----------------------------

/* FUNCTION ************************************************************************************************************

 *

 * Function Name : BOARD_InitPins

 * Description   : Configures pin routing and optionally pin electrical features.

 *

 * END ****************************************************************************************************************/

void BOARD_InitPins(void) {                                /*!< Function assigned for the core: Cortex-M4[m4] */

    IOMUXC_SetPinMux(IOMUXC_SAI3_RXFS_GPT1_CAPTURE1, 0U);

    IOMUXC_SetPinMux(IOMUXC_UART4_RXD_UART4_RX, 0U);

...

-----------------------------

./ board.h/board.c 用于 i.MX8MM M4 核心基本初始化配置,本文不做修改。

./ clock_config.h/clock_config.c 用于 i.MX8MM M4 核心基本时钟配置,本文不做修改。

c). GPT Capture 功能实现

./ 本文 GPT Capture 功能定义

GPT1 capture1 管脚输入一个给定频率(如 1k Hz )和占空比(如  50% ) 的PWM 信号,通过捕获输入上升/下降沿中断,分别获得相邻两次中断的 GPT Counter 计数器的计数,并以此来计算输入 PWM 信号的半波周期。

./ GPT Capture 功能基本都是通过 gpt_capture.c 文件代码来实现,默认 sample 是捕获上升沿中断后,打印中断当时的 GPT Counter 计数数值。

./ 为了实现本文定义的捕获功能,首先增加如下全局变量定义

-----------------------------

/*******************************************************************************

 * Variables

 ******************************************************************************/

volatile bool gptIsrFlag_Start = false;

volatile bool gptIsrFlag_Finish = false;

volatile uint8_t gptIsrFlag_Overflow = 0;

volatile uint32_t captureVal = 0;

volatile uint32_t captureVal_Last = 0;

-----------------------------

// gptIsrFlag_Start 定义为第一次捕获中断开始标志

// gptIsrFlag_Finish 定义为第二次捕获中断结束标志

// gptIsrFlag_Overflow 定义为 GPT Counter 溢出标志计数

// captureVal 定义为第二次中断 GPT Counter 数值

// captureVal_Last 定义为第一次中断 GPT Counter 数值

./ GPT Interrupt 函数修改如下:

首先处理计数器溢出情况,如果中断发生时候已经发生溢出,则增加 gptIsrFlag_Overflow 溢出标志计数的数值;然后通过 gptIsrFlag_Start / gptIsrFlag_Finish 标志位来分别处理第一次和第二次中断,获取第一次和第二次中断时候的 GPT Counter 数值,同时分别翻转 GPT Capture Interrupt 模式。

-----------------------------

void EXAMPLE_GPT_CAPTURE_IRQHandler(void)

{

    /* GPT Counter Overflow processing */

    if (GPT_GetStatusFlags(DEMO_GPT_BASE, kGPT_RollOverFlag) != false)

    {

        if (gptIsrFlag_Start == true)

        {

           gptIsrFlag_Overflow ++;

        }

        GPT_ClearStatusFlags(DEMO_GPT_BASE, kGPT_RollOverFlag);

    }

    if (GPT_GetStatusFlags(DEMO_GPT_BASE, kGPT_InputCapture1Flag) != false)

    {

        if(gptIsrFlag_Finish != true)

        {

           /* First time IRQ */

           if (gptIsrFlag_Start == false)

           {

               captureVal_Last = GPT_GetInputCaptureValue(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL);

               /* Switch Interrupt mode to falling edge */

               GPT_SetInputOperationMode(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL, kGPT_InputOperation_FallEdge);

               gptIsrFlag_Start = true;

           }

           /* Second time IRQ */

else

{

               captureVal = GPT_GetInputCaptureValue(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL);

               /* Switch Interrupt mode to rising edge */

               GPT_SetInputOperationMode(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL, kGPT_InputOperation_RiseEdge);

               gptIsrFlag_Start = false;

               gptIsrFlag_Finish = true;

   }

      }

      GPT_ClearStatusFlags(DEMO_GPT_BASE, BOARD_GPT_CHANNEL_FLAG);

   }

   SDK_ISR_EXIT_BARRIER;

}

-----------------------------

./ Main 主函数修改如下:

-----------------------------

int main(void)

{

        uint64_t int_Peroid = 0;

        uint32_t time_Ms = 0;

        uint32_t time_Us = 0;

gpt_config_t gptConfig;

...

GPT_GetDefaultConfig(&gptConfig);

    /* Initialize GPT module */

    GPT_Init(DEMO_GPT_BASE, &gptConfig);

...

/* Setup input capture on a gpt channel */

    GPT_SetInputOperationMode(DEMO_GPT_BASE, BOARD_GPT_INPUT_CAPTURE_CHANNEL, kGPT_InputOperation_RiseEdge);

...

    /* Enable GPT Overflow interrupt */

    GPT_EnableInterrupts(DEMO_GPT_BASE, kGPT_RollOverFlagInterruptEnable);

...

while (true)

    {

        /* Check whether occur 2nd interupt */

        if (true == gptIsrFlag_Finish)

        {

            /* GPT counter diff value between 2 IRQs */

            int_Peroid = gptIsrFlag_Overflow * (uint64_t) 0xffffffff;

            int_Peroid = int_Peroid + captureVal;

            int_Peroid = int_Peroid - captureVal_Last;

            /* transfer counter value to peroid */

            time_Us = (uint32_t) ((int_Peroid / 24) % 1000);

            time_Ms = (uint32_t) ((int_Peroid / 24) / 1000);

            PRINTF("\r\n interval between 2 rising edge =%u ms and %u us\r\n", time_Ms, time_Us);

            gptIsrFlag_Overflow = 0;

            gptIsrFlag_Finish = false;

        }

        else

        {

            __WFI();

        }

    }

}

-----------------------------

// 通过 GPT_GetDefaultConfig 函数获取默认的 GPT Capture 配置,参考 docs 目录下的 MCUXpresso SDK API Reference Manual_MIMX8MM6.pdf 文档,可以查到默认配置如下,如果需要也可以修改这个配置

-----------------------------

config->clockSource = kGPT_ClockSource_Periph;

config->divider = 1U;

config->enableRunInStop = true;

config->enableRunInWait = true;

config->enableRunInDoze = false;

config->enableRunInDbg = false;

config->enableFreeRun = false;

config->enableMode = true;

-----------------------------

// 通过 GPT_SetInputOperationMode 函数将 GPT Capture 模式初始配置为上升沿触发

// 为了处理 GPT Counter Overflow,使能对应中断

// while 函数循环执行当  gptIsrFlag_Finish 第二次中断采集结束标志位声明后,打印捕获的输入 PWM 波的半波周期。如果有溢出发生,则需要考虑增加相应的 0xffffffff 溢出计数次数。这里需要说明下,由于 NXP iMX8MM SoC 也受到如下 Errata 影响,因此 GPT Clock Source 只能使用内部 24M Hz 时钟源,所以这里直接使用 24M 来算出半波周期是多少 ms 和 us 。

https://www.nxp.com.cn/docs/en/errata/IMX8X_C0_0N99Z_ER.pdf

5). Verdin i.MX8MM Cortex-M4核心FreeRTOS GPT Capture示例部署测试

a). 将上述修改后的项目参考章节 3 的相关资料编译后,复制 gpt_capture.bin 可执行文件到 Verdin i.MX8MM 核心板 Linux /home/root 目录下保存。

b). 对Verdin i.MX8MM 模块进入 U-boot 命令行,通过如下命令配置 Cortex-M4 核心 Firmware 下载和运行

-----------------------------

# setenv load_cmd "ext4load mmc 0:2"

# setenv m4image "/home/root/gpt_capture.bin"

> setenv m4image_size 17000

> setenv loadm4image "${load_cmd} ${loadaddr} ${m4image}"

> setenv m4boot "${loadm4image}; cp.b ${loadaddr} 0x7e0000 ${m4image_size}; dcache flush; bootaux 0x7e0000"

> saveenv

> run m4boot

-----------------------------

c). Verdin i.MX8MM Cortex-M4 核心运行后其调试串口打印信息

-----------------------------

GPT input capture example

Once the input signal is received the input capture half peroid is printed

-----------------------------

d). 此时在 Verdin i.MX8MP 平台通过如下脚本使能 1kHz 50% 占空比 PWM 输出 10s 时间

-----------------------------

#!/bin/sh

cd /sys/class/pwm/pwmchip0/

echo 0 > export

echo 1000000 > pwm0/period

echo 500000 > pwm0/duty_cycle

echo "normal" > pwm0/polarity

echo 1 > pwm0/enable

sleep 10

echo 0 > pwm0/enable

-----------------------------

e). 这时 Verdin i.MX8MM Cortex-M4 调试串口就会打印出对应的半波周期

-----------------------------

...

  Input Capture Half Period Value = 0ms and 500us

  Input Capture Half Period Value = 0ms and 500us

  Input Capture Half Period Value = 0ms and 500us

  Input Capture Half Period Value = 0ms and 500us

...

-----------------------------

f). 尝试将 Verdin i.MX8MP PWM 修改为 10kHz 80%/20% 占空比

-----------------------------

...

echo 100000 > pwm0/period

echo 80000 > pwm0/duty_cycle

...

-----------------------------

g). Verdin i.MX8MM Cortex-M4 输出周期会对应变化

-----------------------------

  Input Capture Half Period Value = 0ms and 80us

  Input Capture Half Period Value = 0ms and 80us

  Input Capture Half Period Value = 0ms and 80us

  Input Capture Half Period Value = 0ms and 80us

-----------------------------

h). 最后,由于 Verdin i.MX8MM GPT1 CAPTURE1 管脚在 Cortex-A53 核心 Linux 下默认是用于 WAKEUP GPIO 使用,如果需要同时运行 Verdin i.MX8MM Cortex-A53 核心和 Cortex-M4 核心,就需要在 Linux device-tree 文件中将 WAKEUP gpio-key 功能替换为其他 GPIO 管脚资源。

imx8mm-verdin.dtsi « freescale « dts « boot « arm64 « arch - linux-toradex.git - Linux kernel for Apalis and Colibri modules

6). 总结

本文简单示例了基于i.MX8MM Cortex-M4 核心 GPT Capture 功能供参考。

相关文章:

NXP iMX8MM Cortex-M4 核心 GPT Capture 测试

By Toradex秦海 1). 简介 NXP i.MX8 系列处理器均为异构多核架构 SoC&#xff0c;除了可以运行 Linux 等复杂操作系统的 Cortax-A 核心&#xff0c;还包含了可以运行实时操作系统比如 FreeRTOS 的 Cortex-M 核心&#xff0c;本文就演示通过 NXP i.MX8MM 处理器集成的 Cortex-…...

2步破解官方sublime4

sublime简要破解流程 1.下载sublime官方最新版2. 破解流程 1.下载sublime官方最新版 打开 官方网站下载 portable version 版&#xff0c;省的安装。。解压到任意位置&#xff0c;备份 sublime_text.exe 文件 2. 破解流程 打开网址把文件 sublime_text.exe 拖入网页搜索替换…...

【智能家居】东胜物联ODM定制ZigBee网关,助力能源管理解决方案商,提升市场占有率

背景 本文案例服务的客户是专业从事智能家居能源管理的解决方案商&#xff0c;其产品与服务旨在帮助用户监测、管理和优化能源消耗&#xff0c;以提高能源使用效率。 随着公司的扩张&#xff0c;为了增加市场占有率&#xff0c;他们希望找到更好的硬件服务支持&#xff0c;以…...

Python爬虫实战第三例【三】【上】

零.实现目标 爬取视频网站视频 视频网站你们随意&#xff0c;在这里我选择飞某速&#xff08;狗头保命&#xff09;。 例如&#xff0c;作者上半年看过的“铃芽之旅”&#xff0c;突然想看了&#xff0c;但是在正版网站看要VIP&#xff0c;在盗版网站看又太卡了&#xff0c;…...

解释器模式

解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于定义一种语言的文法&#xff0c;并提供一个解释器来解释该语言中的表达式。这个模式主要用于解决问题领域中存在的特定语言或表达式的解释和执行问题。它将一个问题分解成一系列的…...

【UI自动化测试】如何提高UI自动化脚本的稳定性,

设计方面&#xff1a; 用例解耦、减少用例之前的互相依赖&#xff0c;避免影响其他用例的执行&#xff1b; 用例执行过后对测试场景还原&#xff0c;避免影响其他用例的执行&#xff1b; 脚本失败后可以加入testng的重试机制&#xff0c;提高用例的稳定性&#xff1b; PO模式…...

什么叫聊天中信息传达的框架效应framing effect,或展望理论Prospect theory

什么叫聊天中信息传达的框架效应&#xff0c;或展望理论 设计不能为产品带来良好体验&#xff1f;可能是你不懂心理学 框架效应- 维基百科&#xff0c;自由的百科全书 框架(社会科学)-展望理论 - 经济百科 jingjibaike 3 Answer 框架效应The theory of framing effects…...

日常开发Git命令

场景&#xff1a; 在远程库创建分支后&#xff0c;在本地开发后-合并代码-push到远程库 命令行 #查看现在分支 git branch #切换到master分支 git checkout master #拉取远程库修改 git pull git branch #切换到修改的分支 git checkout feature/s3-use-internel-name #merg…...

嵌入式学习第二十五天!(网络的概念、UDP编程)

网络&#xff1a; 可以用来&#xff1a;数据传输、数据共享 1. 网络协议模型&#xff1a; 1. OSI协议模型&#xff1a; 应用层实际收发的数据表示层发送的数据是否加密会话层是否建立会话连接传输层数据传输的方式&#xff08;数据包&#xff0c;流式&#xff09;网络层数据的…...

实操keepalived(高可用)+Nginx(四层代理+七层代理),实现高可用、负载均衡以及动静分离

一 vrrp技术 VRRP 相关术语 VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;i通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。 协议版本: VRRPv2 (常用) 和VRRPv3:0 VRRPv2仅适用于IPv4网络&#xff0c;VRRPv3适用…...

ES6基础3

函数的扩展 基本用法 函数参数的默认值 ES6允许为函数的参数设置默认值&#xff0c;即直接写在参数定义的后面。 参数变量是默认声明的&#xff0c;所以不能用let或const再次声明。下面代码中&#xff0c;参数变量x是默认声明的&#xff0c;在函数体中&#xff0c;不能用let或c…...

HarmonyOS 数据持久化 关系型数据库之 初始化操作

上文 HarmonyOS 数据持久化之首选项 preferences 我们有说用户首选项 但它只能处理一些比较简单的数据类型结构 的持久化处理 如果是一些批量较大 结构较为复杂的数据结构 那么 首选项就无法满足了 我们就要选择 关系型数据库 通过 SQLite 组件实现的一种本地数据库&#xff0…...

伊芙丽签约实在智能,实在Agent数字员工助力品牌效能飙升

近日&#xff0c;国内知名时尚女装品牌伊芙丽与实在智能达成合作&#xff0c;引入业内领先的平台级自动化产品实在Agent数字员工——取数宝&#xff0c;自动获取天猫、淘宝、抖音等线上平台营销数据&#xff0c;开启全域化营销的“提效之旅”。 实在Agent智能体 伊芙丽集团成立…...

第十五届蓝桥杯-UART接收不定长指令的处理

学习初衷&#xff1a; 不仅仅为了比赛&#xff01; 目录 一、问题引入 二、UART常用的三种工作模式 1.UART工作在中断模式 2.UART工作在DMA模式下 3.uart工作在接收转空闲的模式下 三、获取指令中需要的数据 四、printf函数的实现 一、问题引入 问题引入&#xff1a;请…...

网络 协议 UDP编程

网络:数据传输,数据共享 1.网络协议模型: OSI协议模型 应用层 实际发送的数据 表示层 发送的数据是否加密 会话层 是否建立会话连接 传输层 数据传输的方式&#xff08;数据报、流式&#xff09…...

3505. 这也是一道排序题

一、题目 输入 10 7334774857 8461862436 540886577 5245195052 9194400521 5412986878 6694133363 1186771950 1405713915 7115286932 输出 -29430338967 二、思考 构造差分数组&#xff1a;C[i] A[i1] - A[i] 由题目条件可知&#xff1a;当A[i] A[i1] A[i-1] - A[i]时&am…...

【Redis】Redis的应用场景

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Redis ⛺️稳中求进&#xff0c;晒太阳 Redis的应用场景&#xff1a; 限流 要求10s内只能访问一次 RequestMapping("xian")public String xianLiu(String sign){String sign1 …...

计算机网络—以太网接口和链路配置

目录 1.拓扑图 2.以太网交换机基础配置 3.配置手动模式的链路聚合 4.配置静态 LACP 模式的链路聚合 5.配置文件 1.拓扑图 2.以太网交换机基础配置 华为交换机接口默认开启了自协商功能&#xff0c;需要手动配置S1与 S2上G0/0/9和G0/0/10接口的速率。 首先修改交换机的设…...

关于做副业、做自媒体:说几句扎心的话

今天在某乎看到一个问题&#xff1a;想尝试自媒体&#xff0c;想了一个月了&#xff0c;都没想好怎么起步&#xff0c;咋整呀&#xff1f; 恰好昨天陪退休老妈去探店&#xff0c;有感而发&#xff0c;就来唠一唠。 一、退休老妈的副业经历 老妈去年年初开始&#xff0c;在某…...

精通SpringBoot单元测试

引言 单元测试是软件开发中不可或缺的一部分&#xff0c;它对保障代码质量和软件的可靠性起着至关重要的作用。而SpringBoot作为一个流行的Java框架&#xff0c;为开发高效、易于部署的微服务提供了强大的支持。 单元测试的重要性&#xff1a; 确保代码正确性&#xff1a;通过…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...