痞子衡嵌入式:实测i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

痞⼦衡嵌⼊式:实测i.MXRT1010上的普通GPIO与⾼速GPIO极限
翻转频率
⼤家好,我是痞⼦衡,是正经搞技术的痞⼦。

今天痞⼦衡给⼤家介绍的是i.MXRT1010上的普通GPIO与⾼速GPIO极限翻转频率。

上⼀篇⽂章,痞⼦衡从原理上介绍了 i.MXRT1xxx 系列⾥普通 GPIO 和 HSGPIO 差异,今天我们就来实测它们的极限翻转频率,看看它们实际表现差别到底有多⼤。

本次选择的测试芯⽚是 i.MXRT1010,这颗芯⽚从功能上来说是⽬前 i.MXRT1xxx 系列⾥的⼩兄弟,但别⼩看它,因为是后⾯推出的型号,恩智浦的设计团队为它在某些⽅⾯做了特殊的性能优化,包括 HSGPIO 性能。

话不多说,开测:
⼀、测试准备⼯作
1.1 测试板卡及测试点
选定的板卡是恩智浦官⽅ MIMXRT1010-EVK,板卡上连接 LED 灯的是 GPIO_11,翻看芯⽚参考⼿册,这个 PAD 既可以配到普通GPIO(GPIO1[11])也可以配到 HSGPIO(GPIO2[11]),正是理想的 PAD,我们就选择这个 PAD 做测试。

此外,最终 I/O 输出波形形态跟外围驱动电路也有关联,所以这⾥也有必要交待清楚:
Note:所⽤⽰波器型号是 Tektronix MDO3024, 带宽 200MHz, 采样率 2.5GS/s
1.2 I/O 翻转测试代码
测试⼯程我们可以直接在 \SDK_2.11.0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\gpio\led_output 例程上修改,为了尽⼒展⽰ GPIO 极限性能,不受其他瓶颈因素⼲扰,这⾥选择代码执⾏性能最⾼的⼯程 build(即代码段在 ITCM ⾥,数据段在 DTCM ⾥)。

I/O 初始化代码很简单,在⽂章⾥都介绍清楚了。

这⾥仅有⼀点注意,为了统⼀最终 I/O 输出效果,不管是⽤于普通 GPIO 还是HSGPIO,我们都直接将测试 PAD 配置到最快的 200MHz 运⾏频率(PAD ⽀持的 50/100/150/200MHz 运⾏频率配置不同主要是对信号幅值响应表现有影响,不过痞⼦衡实测这四种速度配置对于 100MHz 的 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_11_GPIOMUX_IO11, 0U);
// Fast Slew Rate, R0/7, 200MHz
IOMUXC_SetPinConfig(IOMUXC_GPIO_11_GPIOMUX_IO11, 0x70F9U);
if (useNormalGpio)
{
// GPIO1
IOMUXC_GPR->GPR26 &= ~(1u << 11);
GPIO_PinInit(GPIO1, 11, &led_config);
}
else
{
// GPIO2
IOMUXC_GPR->GPR26 |= (1u << 11);
GPIO_PinInit(GPIO2, 11, &led_config);
}
}
在 GPIO 模块⾥跟电平输出控制相关的寄存器有两个,⼀个是 DR 寄存器,另⼀个是 DR_TOGGLE 寄存器,都可⽤于实现输出电平翻转。

有如下代码所⽰的三种常见电平翻转⽅法,在低翻转频率情况下,这三种⽅法是等效的,但是在极限翻转频率情况下,这三种⽅法表现不完全⼀致,下⼀节实测结果会告诉你:
void io_test_run(void)
{
io_test_init(false);
while (1)
{
// 电平翻转⽅法⼀:异或位操作
//GPIO2->DR ^= 0x800;
// 电平翻转⽅法⼆:直接赋值切换位
//GPIO2->DR = 0x800;
//GPIO2->DR = 0x000;
// 电平翻转⽅法三:利⽤ TOGGLE 位
GPIO2->DR_TOGGLE = 0x800;
}
}
1.3 芯⽚系统时钟配置
⼀⽂⾥讲了,普通 GPIO 时钟源是 IPG Bus,⽽ HSGPIO 时钟源是 AHB Bus,因此测试⼯程⾥ AHB/IPG 时钟配置会影响最终 I/O 翻转极限频率。

下图是 i.MXRT1010 内核结构⾥的 HSGPIO 通路,它和 i.MXRT1060/1170 内核结构⾥ HSGPIO 通路其实有点⼩区别,这也是i.MXRT1010 上的优化之处。

led_output 例程⾥的默认系统时钟配置,AHB/Core 时钟来⾃于 PLL6 - 500MHz,AHB_PODF 设 0 (即不分频),⽽ IPG Bus 时钟源固定来⾃于 AHB/Core,且只能在其基础上做 1/2/3/4 分频,我们知道 IPG Bus 最⾼仅⽀持 150MHz,因此在这种情况下 IPG_PODF 只能设3(四分频),IPG 时钟实际是 125MHz,显然 HSGPIO 访问可以得到最优性能,但普通 GPIO 达不到最优性能。

PLL6, CCM_ANALOG->PLL_ENET[ENET_500M_REF_EN] = 1'b1,固定 500MHz
CCM->CBCMR[PRE_PERIPH_CLK_SEL] = 2'b11,derive clock from PLL6
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
为了测试普通 GPIO 的最优性能,我们需要同时再测试⼀种新的系统时钟配置,AHB/Core 时钟源选⽤ PLL2_PFD3,将这个源配置为452.6 MHz,AHB_PODF 依旧设 0,这样 IPG_PODF 设 2(三分频)可以得到 150.8MHz 的 IPG 时钟,这时普通 GPIO 访问可以得到最优性能,不过 HSGPIO 访问就要损失点性能了。

PLL2,CCM_ANALOG->PFD_528[PFD3_FRAC] = 21,即 528MHz*18/PFD3_FRAC = 452.57MHz
CCM->CBCMR[PRE_PERIPH_CLK_SEL] = 2'b10,derive clock from PLL2 PFD3
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'b10,divide by 3
⼆、测试波形结果
准备⼯作都做完了,现在就是⽰波器连上板卡开始实测了,根据组合,⼀共有时钟配置(x2)* I/O 类型(x2)* 翻转⽅法(x3)总计12 个结果,这⾥仅贴出 HSGPIO 在 500MHz AHB/Core 时钟频率下的三种翻转⽅法所得到的波形结果,全部测试结果见最后⼀节。

⾸先是 GPIO->DR 寄存器异或位操作得到的波形结果,为了减少 while(1) 的执⾏对翻转频率的影响(毕竟这⼀句 B.N 跳转指令也是要消耗 CPU 周期的),我们在 while(1) ⾥加⼗次翻转代码,统计结果时取 5/10 个波形周期求平均,最终得到翻转频率为 22.946 MHz,效果似乎⼀般。

汇编窗⼝来看,这句 C 代码异或操作被翻译成了三条指令,先 LDR 指令读出 GPIO->DR 寄存器当前值,然后 EOR 指令做异或操作,最后再 STR 指令写⼊ GPIO->DR 寄存器,应该是 LDR 回读指令耗时较长。

再来看 GPIO->DR_TOGGLE 置位操作和 GPIO->DR 的直接写⼊操作结果,实测下来发现这两种⽅法得到的翻转频率是⼀样的(从汇编窗⼝来看两种翻转⽅法都是仅⼀条 STR 指令搞定),都是 250MHz,效果虽好,但有点过头,因为波形⾥看到的不是标准幅值 3.3V 的⽅波(暂不确定是不是 200MHz 带宽的⽰波器瓶颈),⽽是减半幅值(约 1.6V )的正弦波,也不排除 PAD 最⼤运⾏速度是 200MHz,它只能保证在低于 200MHz 的情况下有很好的电压幅值响应表现(包括翻转斜率),超过这个频率,波形频率值不受影响,但电压幅值响应表现不能保证。

为了验证是不是⽰波器瓶颈,痞⼦衡找了台更⾼性能的 Tektronix MSO5204(带宽 2GHz, 采样率 10GS/s),复测了⼀下这个 250MHz 的信号,得到结果略有改善,但幅度⼀样有衰减(2.34V),还是 PAD 本⾝限制。

三、完整结果统计
现在我们来看⼀下全部的结果,因为三种 I/O 翻转⽅法⾥有两种效果是⼀样的,所以我们省略了 GPIO->DR 直接写⼊这种⽅法的结果,最终得到了 8 个结果。

根据实测结果,我们得到了如下结论:
总结1: PAD配置⾥的运⾏频率并不限制最终输出翻转频率,只是⽆法保证超过设置频率后的波形幅值响应表现(包括翻
转斜率)
总结2:置位 GPIO->DR_TOGGLE 寄存器可获得最佳 I/O 翻转性能
总结3:普通 GPIO 翻转频率约是时钟源 IPG Bus 的 1/7.5,极限翻转频率是 20.614MHz
总结4: HSGPIO 翻转频率约是时钟源 AHB Bus 的 1/2,极限翻转频率是 250MHz
AHB/Core时钟频率IPG总线时钟频率I/O PAD配置I/O翻转⽅法普通GPIO极限翻转频率⾼速GPIO极限翻转频率
500MHz125MHz Fast Slew, 200MHz异或GPIO->DR 5.214MHz
标准幅度⽅波
22.946MHz
标准幅度⽅波
500MHz125MHz Fast Slew, 200MHz置位GPIO->DR_TOGGLE 15.533MHz
标准幅度⽅波
250MHz
减半幅度正弦波
452.6MHz150.8MHz Fast Slew, 200MHz异或GPIO->DR 6.309MHz
标准幅度⽅波
18.864MHz
标准幅度⽅波
452.6MHz150.8MHz Fast Slew, 200MHz置位GPIO->DR_TOGGLE
20.614MHz226.244MHz
标准幅度⽅波减半幅度正弦波
四、⼀个有趣的问题
最后再留⼀个开放问题,在痞⼦衡旧⽂⾥提到过 ARM Errata 838869 ,即在 Cortex-M4/7 上,如果 CPU 执⾏速度远远⾼于 GPIO 外设寄存器写⼊速度,如果代码逻辑⾥涉及 GPIO 寄存器回读,⼀般需要在 GPIO 寄存器写⼊操作后额外插⼊ DSB 指令来保证同步。

我们现在在 500MHz AHB/Core 时钟频率下 HSGPIO 翻转代码⾥额外插⼊ DSB 指令,看看有什么影响,结果翻转频率从 250MHz ⼀下⼦降到了 35.8MHz。

⾄此,i.MXRT1010上的普通GPIO与⾼速GPIO极限翻转频率痞⼦衡便介绍完毕了,掌声在哪⾥~~~
欢迎订阅
⽂章会同时发布到我的、、、平台上。

微信搜索"痞⼦衡嵌⼊式"或者扫描下⾯⼆维码,就可以在⼿机上第⼀时间看了哦。

相关文档
最新文档