大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是i.MXRT1060/1170上的普通GPIO與高速GPIO極限翻轉頻率。
按照上一篇文章 《實測i.MXRT1010上的普通GPIO與高速GPIO極限翻轉頻率》 里的測試流程和方法,痞子衡今天帶大家再測試下含有 HSGPIO 模塊的 i.MXRT1060 和 i.MXRT1170 系列。從芯片整體性能上來說,它們倆都是 i.MXRT1010 的老大哥,但是老大哥未必是方方面面都碾壓小老弟的,有時候系統設計越復雜,細節之處反而越難優化。今天我們就來對比看看它們在 GPIO 上的表現:
- Note1: i.MXRT1064 跟 i.MXRT1060 是同一種 Die, GPIO 性能是一致的;i.MXRT1160 和 i.MXRT1170 在 GPIO 上性能也類似。
- Note2: 測量所用示波器型號是 Tektronix MSO5204,帶寬 2GHz, 采樣率 10GS/s。
一、i.MXRT1060(1064)上的測試
1.1 測試板卡及測試點
選定的板卡是恩智浦官方 MIMXRT1060-EVK,這次我們選了 Arduino J22 接口的 Pin3,即 GPIO_AD_B0_11,這個 PAD 既可以配到普通 GPIO(GPIO1[11]) 也可以配到 HSGPIO(GPIO6[11]),默認外圍可選功能電路上的電阻都是 DNP 狀態,因此這個 PAD 是懸空的:
1.2 I/O 翻轉測試代碼
測試工程我們可以直接在 \SDK_2.11.0_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\gpio\led_output 例程上修改,為了盡力展示 GPIO 極限性能,不受其他瓶頸因素干擾,這里選擇代碼執行性能最高的工程 build(即代碼段在 ITCM 里,數據段在 DTCM 里)。I/O 測試代碼很簡單:
void io_test_init(bool useNormalGpio)
{
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
CLOCK_EnableClock(kCLOCK_Iomuxc);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_11_GPIO1_IO11, 0U);
// Fast Slew Rate, R0/7, 200MHz
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_11_GPIO1_IO11, 0x10F9U);
if (useNormalGpio)
{
// GPIO1
IOMUXC_GPR->GPR26 &= ~(1u << 11);
GPIO_PinInit(GPIO1, 11, &led_config);
}
else
{
// GPIO6
IOMUXC_GPR->GPR26 |= (1u << 11);
GPIO_PinInit(GPIO6, 11, &led_config);
}
}
void io_test_run(void)
{
io_test_init(false);
while (1)
{
GPIO6->DR_TOGGLE = 0x800;
}
}
1.3 芯片系統時鍾配置
《普通GPIO與高速GPIO差異及其用法》 一文里講了,普通 GPIO 時鍾源是 IPG Bus,而 HSGPIO 時鍾源是 AHB Bus,因此測試工程里 AHB/IPG 時鍾配置會影響最終 I/O 翻轉極限頻率。下圖是 i.MXRT1060 內核結構里的 HSGPIO 通路。
led_output 例程里的默認系統時鍾配置,AHB/Core 時鍾來自於 PLL1,將這個源配置為 1200 MHz,ARM_PODF 設 1(兩分頻),AHB_PODF 設 0 (即不分頻),IPG Bus 時鍾源固定來自於 AHB/Core,且只能在其基礎上做 1/2/3/4 分頻,我們知道 IPG Bus 最高僅支持 150MHz,因此在這種情況下 IPG_PODF 只能設 3(四分頻),最終 AHB 時鍾是 600MHz,IPG 時鍾是 150MHz,HSGPIO 和 GPIO 訪問可以同時得到最優性能(這點設計上是優於 i.MXRT1010 的)。
PPL1, CCM_ANALOG->PLL_ARM[DIV_SELECT] = 100,即 24MHz*DIV_SELECT/2 = 1200MHz
CCM->CACRR[ARM_PODF] = 3'b001,divide by 2
CCM->CBCMR[PRE_PERIPH_CLK_SEL] = 2'b11,derive clock from divided PLL1
CCM->CBCDR[PERIPH_CLK_SEL] = 1'b0,derive clock selected by CCM->CBCMR[PRE_PERIPH_CLK_SEL]
CCM->CBCDR[AHB_PODF] = 3'b000,divide by 1
CCM->CBCDR[IPG_PODF] = 2'b11,divide by 4
1.4 I/O 翻轉測試結果
現在我們來看一下測試結果,根據實測結果,我們得到了如下結論:
- 總結1: PAD配置里的運行頻率並不限制最終輸出翻轉頻率,實際輸出的波形幅值響應表現跟外圍電路關系較大。
- 總結2: 置位 GPIO->DR_TOGGLE 寄存器可獲得最佳 I/O 翻轉性能
- 總結3: 普通 GPIO 翻轉頻率約是時鍾源 IPG Bus 的 1/8,極限翻轉頻率是 18.69MHz
- 總結4: HSGPIO 翻轉頻率約是時鍾源 AHB Bus 的 1/4,極限翻轉頻率是 149.24MHz
- 總結5: i.MXRT1060 的 GPIO 性能跟 i.MXRT1010 差不多,但是 HSGPIO 性能比 i.MXRT1010 差很多。
AHB/Core時鍾頻率 | IPG總線時鍾頻率 | I/O PAD配置 | I/O翻轉方法 | 普通GPIO極限翻轉頻率 | 高速GPIO極限翻轉頻率 |
---|---|---|---|---|---|
600MHz | 150MHz | Fast Slew, 200MHz | 異或GPIO->DR | 6.289MHz 標准幅度方波 |
22.99MHz 標准幅度方波 |
600MHz | 150MHz | Fast Slew, 200MHz | 置位GPIO->DR_TOGGLE | 18.69MHz 標准幅度方波 |
149.24MHz 標准幅度正弦波 |
二、i.MXRT1170(1160)上的測試
2.1 測試板卡及測試點
選定的板卡是恩智浦官方 MIMXRT1170-EVK,板卡上連接 LED 燈的是 GPIO_AD_04,翻看芯片參考手冊,這個 PAD 既可以配到普通 GPIO(GPIO9[3] 或者 GPIO3[3]) 也可以配到 HSGPIO(CM7_GPIO3[3]),我們選擇這個 PAD 做測試。
與此同時,作為比較,還多選了一個 GPIO_AD_01 腳作為測量點 2,這個 PAD 既可以配到普通 GPIO(GPIO9[0] 或者 GPIO3[0]) 也可以配到 HSGPIO(CM7_GPIO3[0]),外圍電路接近於懸空。
此外,最終 I/O 輸出波形形態跟外圍驅動電路也有關聯,所以這里也有必要交待清楚:
2.2 I/O 翻轉測試代碼
測試工程我們可以直接在 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\driver_examples\gpio\led_output\cm7 例程上修改,為了盡力展示 GPIO 極限性能,不受其他瓶頸因素干擾,這里選擇代碼執行性能最高的工程 build(即代碼段在 ITCM 里,數據段在 DTCM 里)。I/O 測試代碼很簡單:
void io_test_init(bool useNormalGpio)
{
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
CLOCK_EnableClock(kCLOCK_Iomuxc);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0x000eU);
if (useNormalGpio)
{
// GPIO3
IOMUXC_GPR->GPR42 &= ~(1u << 3);
GPIO_PinInit(GPIO3, 3, &led_config);
}
else
{
// CM7_GPIO3
IOMUXC_GPR->GPR42 |= (1u << 3);
GPIO_PinInit(CM7_GPIO3, 3, &led_config);
}
}
void io_test_run(void)
{
io_test_init(false);
while (1)
{
CM7_GPIO3->DR_TOGGLE = 0x8;
}
}
特別提醒的是在 i.MXRT1170 IOMUXC 模塊 SW_PAD_CTL 控制寄存器里取消了 SPEED 配置,並且 DSE 配置也從 3bit 減少到 1bit,這點跟 i.MXRT1010/1060 上設計不一樣:
2.3 芯片系統時鍾配置
《普通GPIO與高速GPIO差異及其用法》 一文里講了,普通 GPIO 時鍾源是 IPG Bus(在 i.MXRT1170 里叫 BUS_CLK),而 HSGPIO 時鍾源是 AHB Bus(在 i.MXRT1170 里叫 M7_CLK),因此測試工程里 AHB/IPG 時鍾配置會影響最終 I/O 翻轉極限頻率。下圖是 i.MXRT1170 內核結構里的 HSGPIO 通路。
- Note1: GPIO1 - 6 時鍾源是 BUS_CLK,該總線最高頻率 240MHz
- Note2: GPIO7 - 12 時鍾源是 BUS_LPSR_CLK,該總線最高頻率 160MHz
- Note3: GPIO13 時鍾源是 RCOSC_32K
led_output 例程里的默認系統時鍾配置,M7_CLK 時鍾來自於 ARM_PLL,將這個源配置為 996 MHz。BUS_CLK 時鍾來自於 SYS_PLL3,固定 480MHz,BUS_ROOT 配置里做了兩分頻,最終 M7_CLK 時鍾是 996MHz,BUS_CLK 時鍾是 240MHz(相較於 i.MXRT1010/1060 的最大 150MHz 有所提升),HSGPIO 和 GPIO 訪問可以同時得到最優性能。此外,i.MXRT1170 的系統時鍾設計是最靈活也最簡單的。
ARM_PLL, 即 24MHz*DIV_SELECT/2/POST_DIV = 996MHz
ANADIG_PLL->ARM_PLL_CTRL[DIV_SELECT] = 166,
ANADIG_PLL->ARM_PLL_CTRL[POST_DIV_SEL] = 2'b00,Divide by 2
// 0 - CLOCK Root M7
CCM->CLOCK_ROOT[0].CONTROL[MUX] = 3'b100,PLL_ARM_CLK
CCM->CLOCK_ROOT[0].CONTROL[DIV] = 8'h00,Divider selected clock by DIV + 1.
SYS_PLL3, ANADIG_PLL->SYS_PLL3_CTRL[SYS_PLL3_GATE] = 1'b0,固定 480MHz
// 2 - CLOCK Root Bus
CCM->CLOCK_ROOT[2].CONTROL[MUX] = 3'b100,SYS_PLL3_CLK
CCM->CLOCK_ROOT[2].CONTROL[DIV] = 8'h01,Divider selected clock by DIV + 1.
2.4 I/O 翻轉測試結果
現在我們來看一下測試結果,根據實測結果,我們得到了如下結論:
- 總結1: 置位 GPIO->DR_TOGGLE 寄存器可獲得最佳 I/O 翻轉性能
- 總結2: 普通 GPIO 翻轉頻率約是時鍾源 BUS_CLK 的 1/14,極限翻轉頻率是 17.12MHz
- 總結3: HSGPIO 翻轉頻率約是時鍾源 M7_CLK 的 1/4,極限翻轉頻率是 248.87MHz
- 總結4: i.MXRT1170 的 GPIO 性能跟 i.MXRT1010/1060 差不多,HSGPIO 性能跟 i.MXRT1010 差不多。
M7_CLK時鍾頻率 | BUS_CLK時鍾頻率 | I/O PAD配置 | I/O翻轉方法 | 普通GPIO極限翻轉頻率 | 高速GPIO極限翻轉頻率 |
---|---|---|---|---|---|
996MHz | 240MHz | Fast Slew | 異或GPIO->DR | 7.058MHz 標准幅度方波 |
41.24MHz 標准幅度方波 |
996MHz | 240MHz | Fast Slew | 置位GPIO->DR_TOGGLE | 17.12MHz 標准幅度方波 |
248.87MHz 1/4幅度正弦波 |
至此,i.MXRT1060/1170上的普通GPIO與高速GPIO極限翻轉頻率痞子衡便介紹完畢了,掌聲在哪里~~~
歡迎訂閱
文章會同時發布到我的 博客園主頁、CSDN主頁、知乎主頁、微信公眾號 平台上。
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。