找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4406

积分

0

好友

612

主题
发表于 4 小时前 | 查看: 3| 回复: 0

《Cortex-M系统中断延迟及其测量方法简介》 一文中,我们曾介绍过 System Design 中 Cortex-M 中断延迟的基本概念及一种使用 GPIO 模块测量中断延迟的通用方法。今天,我们就将这个理论方法付诸实践,在恩智浦 i.MXRT1xxx 系列芯片上进行一次实际测量。

一、官方指标与理论背景

恩智浦的 i.MXRT1xxx 系列微控制器均基于 Arm Cortex-M7 内核,主频覆盖 500MHz 到 1GHz 不等。以该系列的首款型号 i.MXRT1050 为例,在其官方介绍页面上,赫然标注着“低至 20ns 的中断延迟”这一关键指标。

i.MX RT1050官方特性介绍,显示20ns中断延迟

这个 20ns 的数值是如何得出的呢?根据 Cortex-M7 内核的 计算机基础 设计,其标准中断延迟为 12 至 14 个内核时钟周期。i.MXRT1050 的主频为 600MHz,因此理论计算得到的最小延迟为:(1秒 / 600,000,000 Hz) * 12 ≈ 20ns。由此可见,官方宣传的 20ns 完全符合 ARM 给出的标准值。

那么,在实际的硬件和软件环境下,我们能否测出这个数值?不同型号之间的表现又是否一致呢?接下来,我们通过代码和示波器来寻找答案。

二、测试环境搭建与代码实现

我们选取了 i.MXRT1011、i.MXRT1021、i.MXRT1052、i.MXRT1062 和 i.MXRT1176 这五个有代表性的型号进行实测。测试代码基于各型号的官方 SDK 包构建。

以 i.MXRT1052 为例,我们选用 \SDK_2.10.0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\gpio\input_interrupt 例程作为基础模板。请注意:编译时应选择 debug 配置,确保代码链接在 TCM(紧耦合存储器)中运行,以满足零等待内存访问的测试前提,避免存储器的访问延迟干扰测量结果。

核心思路是使用一个 GPIO 引脚作为外部中断触发源,并在其中断服务程序(ISR)的第一条指令处,立即翻转另一个 GPIO 引脚的电平。通过示波器测量触发信号边沿与输出信号边沿之间的时间差,即可得到中断延迟时间。

以下是按照此思想修改后的主要 C/C++ 代码:

uint32_t s_pin_low  = 0x000000;
uint32_t s_pin_high = 0x800000;

////////////////////////////////////////////////////////////////////////////////
// 使用 EVKB 板上的用户按键 SW8 (GPIO5_IO00) 触发中断
void GPIO5_Combined_0_15_IRQHandler(void)
{
    GPIO2->DR = s_pin_low;
    GPIO2->DR = s_pin_high;
    GPIO_PortClearInterruptFlags(GPIO5, 1U << 0);
    __DSB();
}

void init_gpio5_0(void)
{
    gpio_pin_config_t din_config = {kGPIO_DigitalInput, 0, kGPIO_IntFallingEdge};       
    IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); 
    GPIO_PinInit(GPIO5, 0, &din_config);
    NVIC_EnableIRQ(GPIO5_Combined_0_15_IRQn);
    GPIO_PortEnableInterrupts(GPIO5, 1U << 0);    
}

////////////////////////////////////////////////////////////////////////////////
// 使用 Arduino 接口 J24-2 (GPIO1_IO02) 触发中断,测试两种中断类型
void GPIO1_Combined_0_15_IRQHandler(void)
{
    GPIO2->DR = s_pin_low;
    GPIO2->DR = s_pin_high;
    GPIO_PortClearInterruptFlags(GPIO1, 1U << 2);
    __DSB();
}

void GPIO1_INT2_IRQHandler(void)
{
    GPIO2->DR = s_pin_low;
    GPIO2->DR = s_pin_high;
    GPIO_PortClearInterruptFlags(GPIO1, 1U << 2);
    __DSB();
}

void init_gpio1_2(void)
{
    gpio_pin_config_t din_config = {kGPIO_DigitalInput, 0, kGPIO_IntFallingEdge};
    IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U); 
    GPIO_PinInit(GPIO1, 2, &din_config);
    NVIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);
    //NVIC_EnableIRQ(GPIO1_INT2_IRQn); // 用于测试独立中断
    GPIO_PortEnableInterrupts(GPIO1, 1U << 2);    
}

////////////////////////////////////////////////////////////////////////////////
// 初始化用于输出测量信号的 GPIO2_IO23
void init_gpio2_23(void)
{
    gpio_pin_config_t dout_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
    IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_GPIO2_IO23, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_07_GPIO2_IO23, 0x70F9U); 
    GPIO_PinInit(GPIO2, 23, &dout_config);
    GPIO2->DR |= 0x800000; // 初始化为高电平
}

int main(void)
{
    BOARD_ConfigMPU();
    BOARD_InitBootClocks();
    CLOCK_EnableClock(kCLOCK_Iomuxc);           
    CLOCK_EnableClock(kCLOCK_IomuxcSnvs);     

    init_gpio5_0();
    init_gpio1_2();
    init_gpio2_23();

    while (1);
}

测试说明:

  1. 为了结果的全面性,我们同时测试了多个不同的 GPIO 中断源。因为部分 i.MXRT 型号包含普通 GPIO 和高速 GPIO(HSGPIO),且有些 GPIO 事件既可触发“组合型”中断,也可触发“独立型”中断。
  2. 用于输出测量信号的 GPIO 类型(普通或高速)对本次测试结果无本质影响,其自身翻转时间极短,可忽略不计。

三、五款芯片实测数据与分析

通过对五款 i.MXRT 型号的详细测试,我们得到了以下波形图与数据表格,并可以总结出几点关键结论:

核心结论:

  1. 中断类型影响小:对于大多数型号,使用普通 GPIO 或 HSGPIO,以及“组合型”或“独立型”中断,测得的中断延迟时间几乎相同(i.MXRT1170 除外,其不同域的中断存在差异)。
  2. 实测值与理论值的差异:i.MXRT1020 和 i.MXRT1050 的实测延迟接近 ARM 标准理论值。而 i.MXRT1010、i.MXRT1060 和 i.MXRT1170 的实测值则明显大于理论值。这提示我们,最终的中断延迟不仅取决于内核,还可能受到芯片内部 GPIO 模块设计、互联总线延迟等因素的影响。
  3. 延迟存在波动:测量发现,GPIO 中断延迟并非一个固定值,存在大约 3 个内核时钟周期的波动。这可能是由于外部 PAD 的信号跳变与内部 NVIC 中断请求信号的同步时机存在微小随机性导致的。

3.1 i.MXRT1011 实测结果

i.MXRT1011中断延迟示波器测量波形

系统时钟配置 PAD GPIO IRQ t1 t2 td 中断延迟时钟数
Core: 500MHz
IPG: 125MHz GPIO_01 GPIO1[1] GPIO1_Combined_0_15_IRQn 74 - 78ns 33ns 41 - 45ns 20 - 23 cycles
GPIO_01 GPIO2[1] GPIO2_Combined_0_15_IRQn
GPIO_SD_05 GPIO2[5] GPIO2_Combined_0_15_IRQn

3.2 i.MXRT102x 实测结果

i.MXRT102x中断延迟示波器测量波形

系统时钟配置 PAD GPIO IRQ t1 t2 td 中断延迟时钟数
Core: 500MHz
IPG: 125MHz GPIO_AD_B0_06 GPIO1[6] GPIO1_Combined_0_15_IRQn 92 - 96ns 64ns 28 - 32ns 14 - 16 cycles
GPIO_AD_B0_06 GPIO1[6] GPIO1_INT6_IRQn
SNVS_WAKEUP GPIO5[0] GPIO5_Combined_0_15_IRQn

3.3 i.MXRT105x 实测结果

i.MXRT105x中断延迟示波器测量波形

系统时钟配置 PAD GPIO IRQ t1 t2 td 中断延迟时钟数
Core: 600MHz
IPG: 150MHz GPIO_AD_B0_02 GPIO1[2] GPIO1_Combined_0_15_IRQn 78 - 82ns 54ns 24 - 28ns 14 - 17 cycles
GPIO_AD_B0_02 GPIO1[2] GPIO1_INT2_IRQn
SNVS_WAKEUP GPIO5[0] GPIO5_Combined_0_15_IRQn

3.4 i.MXRT106x 实测结果

i.MXRT106x中断延迟示波器测量波形

系统时钟配置 PAD GPIO IRQ t1 t2 td 中断延迟时钟数
Core: 600MHz
IPG: 150MHz GPIO_AD_B0_02 GPIO1[2] GPIO1_Combined_0_15_IRQn 62 - 66ns 27ns 35 - 39ns 21 - 24 cycles
GPIO_AD_B0_02 GPIO1[2] GPIO1_INT2_IRQn
GPIO_AD_B0_02 GPIO6[2] GPIO6_7_8_9_IRQn
SNVS_WAKEUP GPIO5[0] GPIO5_Combined_0_15_IRQn

3.5 i.MXRT117x 实测结果

i.MXRT117x中断延迟示波器测量波形

系统时钟配置 PAD GPIO IRQ t1 t2 td 中断延迟时钟数
Core: 996MHz
BUS: 240MHz GPIO_AD_01 GPIO2[31] GPIO2_Combined_16_31_IRQn 52 - 54ns 29ns 23 - 25ns 23 - 25 cycles
GPIO_AD_01 CM7_GPIO2[31] CM7_GPIO2_3_IRQn
WAKEUP_DIG GPIO13[0] GPIO13_Combined_0_31_IRQn 47 - 50ns 29ns 18 - 21ns 18 - 21 cycles

总结

通过本次对 i.MXRT1xxx 系列五款芯片的系统中断延迟实测,我们不仅验证了 GPIO 测量方法的可行性,还获得了不同型号芯片在真实环境下的性能数据。数据显示,虽然都基于 Cortex-M7 内核,但不同型号芯片的中断延迟表现存在差异,这提醒开发者在设计高实时性系统时,除了关注内核理论指标,还需结合具体芯片的实测数据进行综合评估。希望这些实测数据和分析能在 云栈社区 帮助到更多从事嵌入式实时系统开发的工程师。




上一篇:Cortex-M中断延迟详解:嵌入式实时系统的原理与实测方法
下一篇:i.MXRT GPIO中断处理函数(IRQHandler)标准流程详解与避坑指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-20 12:13 , Processed in 0.488309 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表