大家好,我是痞子衡,是正經(jīng)搞技術的痞子。今天痞子衡給大家介紹的是i.MXRT1xxx的系統(tǒng)中斷延遲時間。
在 《Cortex-M系統(tǒng)中斷延遲及其測量方法簡介》 一文里,痞子衡介紹了 Cortex-M 中斷延遲的基本概念及一種用 GPIO 模塊來測量中斷延遲時間的方法,今天我們就在 i.MXRT1xxx 系列芯片上用這種方法實測一下中斷延遲:
恩智浦 i.MXRT1xxx 系列目前有很多型號,都是基于 Cortex-M7 內(nèi)核,主頻從 500MHz 到 1GHz 不等。拿該系列第一款型號 i.MXRT1050 來說,在其官方主頁可以看到其標稱中斷延遲時間低至 20ns。
在 《Cortex-M系統(tǒng)中斷延遲》 一文第一小節(jié)里我們知道 Cortex-M7 的標準中斷延遲是 12 - 14 個內(nèi)核時鐘周期,i.MXRT1050 主頻是 600MHz ,理論計算可得 (1s / 600MHz) * 12 = 20ns,所以 i.MXRT1050 上這 20ns 的中斷延遲是符合 ARM 標準的。

現(xiàn)在我們在芯片上實測一下,痞子衡把 i.MXRT1011/1021/1052/1062/1176 這五個型號均測了一遍,測試代碼可以基于其各自 SDK 包。
以 i.MXRT1052 為例,選用 \SDK_2.10.0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\gpio\input_interrupt 例程為模板(注意選擇 debug build,即代碼鏈接在 TCM 里,滿足零等待內(nèi)存的測試需求),按 《Cortex-M系統(tǒng)中斷延遲》 一文第二小節(jié)設計思想修改主函數(shù)如下(關于 GPIO 中斷使用可以參考 《以i.MXRT1xxx的GPIO模塊為例談談中斷處理函數(shù)(IRQHandler)的標準流程》 一文):
Note1: 為了結果的準確性,痞子衡同時測試了多個不同類型的 GPIO 中斷,因為部分 i.MXRT 型號中包含普通 GPIO 和 HSGPIO,并且有些 GPIO 事件既可以觸發(fā) Combined 型中斷,也可以觸發(fā)獨立的中斷。 Note2: 輸出信號用的 GPIO 類型對于本次測試不重要,無論選擇普通 GPIO 還是 HSGPIO 去翻轉,其翻轉時長不影響最終測試結果。
uint32_t?s_pin_low??=?0x000000;
uint32_t?s_pin_high?=?0x800000;
////////////////////////////////////////////////////////////////////////////////
//?User?Button?SW8?-?Pin4?in?RT1050-EVKB
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?Interface,?J24-2?in?RT1050-EVKB
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);????
}
////////////////////////////////////////////////////////////////////////////////
//?TP26
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);
}
現(xiàn)在我們來看 5 個 i.MXRT 型號的詳細測試結果,根據(jù)測試結果,我們得出如下結論:
結論1:不同類型 GPIO(普通GPIO/HSGPIO)或者不同類型的 GPIO 中斷(Combined 型/獨立型),其中斷延遲結果幾乎是一樣的(但是 i.MXRT1170 除外)。 結論2:i.MXRT1020/1050 上測出的 GPIO 中斷延遲接近 ARM 標準值,但是 i.MXRT1010/1060/1170 上測出的 GPIO 中斷延遲大于 ARM 標準值(猜測是 GPIO 模塊設計導致的延遲較大,并不是內(nèi)核本身延遲大)。 結論3:本次方法測出的 GPIO 中斷延遲不是一個固定值,存在約 3 個內(nèi)核時鐘周期的波動(多次測量觀測到),原因可能是 PAD 信號跳變與 NVIC IRQ 信號置起的同步時機差異。

| 系統(tǒng)時鐘配置 | PAD | GPIO | IRQ | t1 | t2 | td | 中斷延遲時鐘數(shù) |
|---|---|---|---|---|---|---|---|
| Core: 500MHz ? ? ? ? ? ?IPG: 125MHz | GPIO_01 | GPIO1[1] | GPIO1_Combined_0_15_IRQn | 74 - 78ns | 33ns | 41 - 45ns | 20 - 23 cycles |
| GPIO2[1] | GPIO2_Combined_0_15_IRQn | ||||||
| GPIO_SD_05 | GPIO2[5] |

| 系統(tǒng)時鐘配置 | PAD | GPIO | IRQ | t1 | t2 | td | 中斷延遲時鐘數(shù) |
|---|---|---|---|---|---|---|---|
| Core: 500MHz ? ? ? ? ? ?IPG: 125MHz | GPIO_AD_B0_06 | GPIO1[6] | GPIO1_Combined_0_15_IRQn | 92 - 96ns | 64ns | 28 - 32ns | 14 - 16 cycles |
| GPIO1_INT6_IRQn | |||||||
| SNVS_WAKEUP | GPIO5[0] | GPIO5_Combined_0_15_IRQn |

| 系統(tǒng)時鐘配置 | PAD | GPIO | IRQ | t1 | t2 | td | 中斷延遲時鐘數(shù) |
|---|---|---|---|---|---|---|---|
| Core: 600MHz ? ? ? ? ? ?IPG: 150MHz | GPIO_AD_B0_02 | GPIO1[2] | GPIO1_Combined_0_15_IRQn | 78 - 82ns | 54ns | 24 - 28ns | 14 - 17 cycles |
| GPIO1_INT2_IRQn | |||||||
| SNVS_WAKEUP | GPIO5[0] | GPIO5_Combined_0_15_IRQn |

| 系統(tǒng)時鐘配置 | PAD | GPIO | IRQ | t1 | t2 | td | 中斷延遲時鐘數(shù) |
|---|---|---|---|---|---|---|---|
| Core: 600MHz ? ? ? ? ? ?IPG: 150MHz | GPIO_AD_B0_02 | GPIO1[2] | GPIO1_Combined_0_15_IRQn | 62 - 66ns | 27ns | 35 - 39ns | 21 - 24 cycles |
| GPIO1_INT2_IRQn | |||||||
| GPIO6[2] | GPIO6_7_8_9_IRQn | ||||||
| SNVS_WAKEUP | GPIO5[0] | GPIO5_Combined_0_15_IRQn |

| 系統(tǒng)時鐘配置 | PAD | GPIO | IRQ | t1 | t2 | td | 中斷延遲時鐘數(shù) |
|---|---|---|---|---|---|---|---|
| Core: 996MHz ? ? ? ? ? ?BUS: 240MHz | GPIO_AD_01 | GPIO2[31] | GPIO2_Combined_16_31_IRQn | 52 - 54ns | 29ns | 23 - 25ns | 23 - 25 cycles |
| CM7_GPIO2[31] | CM7_GPIO2_3_IRQn | ||||||
| WAKEUP_DIG | GPIO13[0] | GPIO13_Combined_0_31_IRQn | 47 - 50ns | 18 - 21ns | 18 - 21 cycles | ||
至此,i.MXRT1xxx的系統(tǒng)中斷延遲時間痞子衡便介紹完畢了,掌聲在哪里~~~