痞子衡嵌入式:实测i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率。
上一篇文章 《聊聊i.MXRT1xxx上的普通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 输出波形形态跟外围驱动电路也有关联,所以这里也有必要交待清楚:
1.2 I/O 翻转测试代码
测试工程我们可以直接在 \SDK_2.11.0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\gpio\led_output 例程上修改,为了尽力展示 GPIO 极限性能,不受其他瓶颈因素干扰,这里选择代码执行性能最高的工程 build(即代码段在 ITCM 里,数据段在 DTCM 里)。
I/O 初始化代码很简单,在 《普通GPIO与高速GPIO差异及其用法》 文章里都介绍清楚了。这里仅有一点注意,为了统一最终 I/O 输出效果,不管是用于普通 GPIO 还是 HSGPIO,我们都直接将测试 PAD 配置到最快的 200MHz 运行频率(PAD 支持的 50/100/150/200MHz 运行频率配置不同有何影响,文章最后会交待):
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/6, 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与高速GPIO差异及其用法》 一文里讲了,普通 GPIO 时钟源是 IPG Bus,而 HSGPIO 时钟源是 AHB Bus,因此测试工程里 AHB/IPG 时钟配置会影响最终 I/0 翻转极限频率。下图是 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 达不到最优性能。
为了测试普通 GPIO 的最优性能,我们需要同时再测试一种新的系统时钟配置,AHB/Core 时钟源选用 PLL2_PFD3,将这个源配置为 452.6 MHz,AHB_PODF 依旧设 0,这样 IPG_PODF 设 2(三分频)可以得到 150.8MHz 的 IPG 时钟,这时普通 GPIO 访问可以得到最优性能,不过 HSGPIO 访问就要损失点性能了。
二、测试波形结果
准备工作都做完了,现在就是示波器连上板卡开始实测了,根据组合,一共有时钟配置(x2)* I/O 类型(x2)* 翻转方法(x3)总计 12 个结果,这里仅贴出 HSGPIO 在 500MHz AHB/Core 时钟频率下的三种翻转方法所得到的波形结果,全部测试结果见最后一节。
首先是 GPIO->DR 寄存器异或位操作得到的波形结果,为了减少 while(1) 的执行对翻转频率的影响(毕竟这一句指令也是要消耗 CPU 周期的),我们在 while(1) 里加十次翻转代码,统计结果时也是取 10 个波形周期,最终得到翻转频率为 22.946 MHz,效果似乎一般。汇编窗口来看,这句 C 代码异或操作被翻译成了三条指令,先 LDR 指令读出 GPIO->DR 寄存器当前值,然后 EOR 指令做异或操作,最后再 STR 指令写入 GPIO->DR 寄存器,应该是 LDR 回读指令耗时较长。

再来看 GPIO->DR_TOGGLE 置位操作和 GPIO->DR 的直接写入操作结果,实测下来发现这两种方法得到的翻转频率是一样的(从汇编窗口来看两种翻转方法都是仅一条 STR 指令搞定),都是 250MHz,效果虽好,但有点过头,因为波形里看到的不是标准幅值的方波,而是减半幅值的正弦波,这是因为 PAD 最大运行速度是 200MHz,它只能保证在低于 200MHz 的情况下有很好的电压幅值响应表现,超过这个频率,波形频率值不受影响,但电压幅值响应表现不能保证。

三、完整结果统计
现在我们来看一下全部的结果,因为三种 I/O 翻转方法里有两种效果是一样的,所以我们省略了 GPIO->DR 直接写入这种方法的结果,最终得到了 8 个结果。根据实测结果,我们得到了如下结论:
- 总结1: PAD配置里的运行频率并不限制最终输出翻转频率,只是无法保证超过设置频率后的波形幅值响应表现
- 总结2: 置位 GPIO->DR_TOGGLE 寄存器可获得最佳 I/O 翻转性能
- 总结3: 普通 GPIO 最大翻转频率是 20.614MHz,约是时钟源 IPG Bus 的 1/7.5
- 总结4: HSGPIO 最大翻转频率是 250MHz,约是时钟源 AHB Bus 的 1/2
| AHB/Core时钟频率 | IPG总线时钟频率 | I/O PAD配置 | I/O翻转方法 | 普通GPIO极限翻转频率 | 高速GPIO极限翻转频率 |
|---|---|---|---|---|---|
| 500MHz | 125MHz | Fast Slew, 200MHz | 异或GPIO->DR | 5.214MHz 标准幅度方波 |
22.946MHz 标准幅度方波 |
| 500MHz | 125MHz | Fast Slew, 200MHz | 置位GPIO->DR_TOGGLE | 15.533MHz 标准幅度方波 |
250MHz 减半幅度正弦波 |
| 452.6MHz | 150.8MHz | Fast Slew, 200MHz | 异或GPIO->DR | 6.309MHz 标准幅度方波 |
18.864MHz 标准幅度方波 |
| 452.6MHz | 150.8MHz | Fast Slew, 200MHz | 置位GPIO->DR_TOGGLE | 20.614MHz 标准幅度方波 |
226.244MHz 减半幅度正弦波 |
四、一个有趣的问题
最后再留一个开放问题,在痞子衡旧文 《以GPIO模块为例谈谈中断处理函数(IRQHandler)的标准流程》 里提到过 ARM Errata 838869 ,即在 Cortex-M4/7 上,如果 CPU 执行速度远远高于 GPIO 外设寄存器写入速度,如果代码逻辑里涉及 GPIO 寄存器回读,一般需要在 GPIO 寄存器写入操作后额外插入 DSB 指令来保证同步。
我们现在在 500MHz AHB/Core 时钟频率下 HSGPIO 翻转代码里额外插入 DSB 指令,看看有什么影响,结果翻转频率从 250MHz 一下子降到了 35.8MHz。

至此,i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:实测i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率的更多相关文章
- 痞子衡嵌入式:i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计. 痞子衡之前两篇文章 <在SBL项目实战中妙用i ...
- 痞子衡嵌入式:聊聊i.MXRT1xxx上的普通GPIO与高速GPIO差异及其用法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT上的普通GPIO与高速GPIO差异. GPIO 可以说是 MCU 上最简单最常用的外设模块了,当一些原生功能外设接口模块不能 ...
- 痞子衡嵌入式:再测i.MXRT1060,1170上的普通GPIO与高速GPIO极限翻转频率
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1060/1170上的普通GPIO与高速GPIO极限翻转频率. 按照上一篇文章 <实测i.MXRT1010上的普通GP ...
- 痞子衡嵌入式:揭秘i.MXRT1060,1010上串行NOR Flash冗余程序启动设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1060,1010上串行NOR Flash冗余程序启动设计. 工业产品设计里经常会有冗余程序/备份程序设计的需求,因为在工业 ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU特性介绍(2)- RT1052DVL6性能实测
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的性能. 在前面的文章 i.MXRT微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2017年推出的新 ...
- 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性介绍(2)- RT685EVKA性能实测(Dhrystone)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的性能. 在前面的文章 i.MXRTxxx微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2018 ...
- 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU特性那些事(2)- RT1052DVL6性能实测(CoreMark)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的性能. 在前面的文章 i.MXRTyyyy微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2 ...
- 痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI地址重映射(Remap)功能可安全OTA
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT部分型号上新增的FlexSPI Remap功能. OTA升级设计几乎是每个量产客户都绕不开的话题,产品发布后免不了要做固件( ...
- 痞子衡嵌入式:解锁i.MXRTxxx上FlexSPI模块自带的地址重映射(Remap)功能
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT三位数系列隐藏的FlexSPI Remap功能. 前段时间痞子衡写了一篇文章 <利用i.MXRT1060,1010上新 ...
随机推荐
- whistle手机抓包(以安卓手机为例)
环境:whistle:1.14.6 whistle手机抓包 以安卓手机为例 手机跟电脑要连同一个wifi. 1.启动whistle 使用w2 start启动whistle. 退出cmd后,whistl ...
- python numpy loadtxt
用numpy加载csv文件数据 发现python numpy loadtxt 方法和数据的结构有很大关系当我的数据有第一行文字是这样子的时候 我程序的运行结果永远都报错,编码格式也处理了统一utf-8 ...
- Windows 10、Windows Server 定时任务(定时关机)
前言 在测试过程中,有些测试机每天都需要关机,一台台很麻烦,于是想起了Windows的任务计划程序,想着试一试,就将具体过程记录一下. 过程 Windows 搜索任务计划程序 创建任务(不要选错了) ...
- OpenGL思维导图
- ls命令剖析
目录 ls命令剖析 资料翻译 SYNOPSIS 使用方式 DESCRIPTION 说明 参数的说明 -l 参数字符的解释 文件权限的解释 FILES 文件夹 实战演练 ls 命令 ls -l 命令 l ...
- FastAPI 学习之路(十一)请求体 - 嵌套模型
系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...
- v72.01 鸿蒙内核源码分析(Shell解析) | 应用窥伺内核的窗口 | 百篇博客分析OpenHarmony源码
子曰:"苟正其身矣,于从政乎何有?不能正其身,如正人何?" <论语>:子路篇 百篇博客系列篇.本篇为: v72.xx 鸿蒙内核源码分析(Shell解析篇) | 应用窥视 ...
- Longhorn 云原生容器分布式存储 - 故障排除指南
内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生容器分布式存储 - 设计架构和概念 Longhorn 云原生容器分布式存储 - ...
- PHP伪协议与文件包含漏洞1
PHP文件包含漏洞花样繁多,需配合代码审计. 看能否使用这类漏洞时,主要看: (1)代码中是否有include(),且参数可控: 如: (2)php.ini设置:确保 allow_url_fopen= ...
- 这样调优之后,单机也能扛下100W连接
1 模拟单机连接瓶颈 我们知道,通常启动一个服务端会绑定一个端口,例如8000端口,当然客户端连接端口是有限制的,除去最大端口65535和默认的1024端口及以下的端口,就只剩下1 024~65 53 ...