你见过的MCU最高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 输出波形形态跟外围驱动电路也有关联,所以这里也有必要交待清楚:

9aaeddcef6828568ced4b058e3120227.png

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, 200MHzIOMUXC_SetPinConfig(IOMUXC_GPIO_11_GPIOMUX_IO11, 0x70F9U);if (useNormalGpio){// GPIO1IOMUXC_GPR->GPR26 &= ~(1u << 11);GPIO_PinInit(GPIO1, 11, &led_config);}else{// GPIO2IOMUXC_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 上的优化之处。

dd1ab06d8ac5b4b3fb3719b68d52fcac.png

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 访问就要损失点性能了。

04c1a809693bd9a057cd7559fd83f0d2.png

二、测试波形结果

准备工作都做完了,现在就是示波器连上板卡开始实测了,根据组合,一共有时钟配置(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 回读指令耗时较长。

9fe8a4da133509773059fa9da262435a.png

45678a86b232b7dc69aeea1af98c09ba.png

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

54af98b7200fae7a88d66e7ce18e4881.png

5c561e04f7adfd101dc0f2b5db1e6b90.png

fdc34a7a9d78b722ac5f43114024b463.png

三、完整结果统计

现在我们来看一下全部的结果,因为三种 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极限翻转频率
500MHz125MHzFast Slew, 200MHz异或GPIO->DR5.214MHz
           标准幅度方波
22.946MHz
           标准幅度方波
500MHz125MHzFast Slew, 200MHz置位GPIO->DR_TOGGLE15.533MHz
           标准幅度方波
250MHz
           减半幅度正弦波
452.6MHz150.8MHzFast Slew, 200MHz异或GPIO->DR6.309MHz
           标准幅度方波
18.864MHz
           标准幅度方波
452.6MHz150.8MHzFast Slew, 200MHz置位GPIO->DR_TOGGLE20.614MHz
           标准幅度方波
226.244MHz
           减半幅度正弦波

四、一个有趣的问题

最后再留一个开放问题,在痞子衡旧文 《以GPIO模块为例谈谈中断处理函数(IRQHandler)的标准流程》 里提到过  ARM Errata 838869 ,即在 Cortex-M4/7 上,如果 CPU 执行速度远远高于 GPIO 外设寄存器写入速度,如果代码逻辑里涉及 GPIO 寄存器回读,一般需要在 GPIO 寄存器写入操作后额外插入 DSB 指令来保证同步。

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

df16c12d97daa5958559014a58d7036f.png

2ae392408c61b5cca41929b05b7d2d3d.png

至此,i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率痞子衡便介绍完毕了,掌声在哪里~~~


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

django中的admin组件之自定义组件的增删改查的完善

昨天我们将自定义列放在类我们自定义的Bookconfig配置类内&#xff0c;但是这样就写死了&#xff0c;因为当我们访问publish表的时候应该也有这样的自定义列&#xff0c;所以我们应该将我们的自定义列放在默认的配置表里面。应该怎么做&#xff1f; 当我们的自定义列挪到默认配…

“制造商和技术支持商”

1.用优化工具。 2.system32中的OEMINFO.ini和OEMLOGO.bmp文件 转载于:https://blog.51cto.com/honglingjin2011/537680

青春是一列不再回头的火车…

高中那年&#xff0c;我表姐对我说&#xff1a;“不要老想着出去打工赚钱&#xff0c;好好读书&#xff0c;将来肯定有用&#xff0c;也不要想着现在日子长得很&#xff0c;等你像我这样结婚生子后&#xff0c;一天一眨眼就过完了。”当时听了没有多大感觉&#xff0c;如今深以…

Android Service学习之AIDL, Parcelable和远程服务

AIDL的作用由于每个应用程序都运行在自己的进程空间&#xff0c;并且可以从应用程序UI运行另一个服务进程&#xff0c;而且经常会在不同的进程间传递对象。在Android平台&#xff0c;一个进程通常不能访问另一个进程的内存空间&#xff0c;所以要想对话&#xff0c;需要将对象分…

我和周立功的聊天

算起来&#xff0c;我和周工认识也有7年了&#xff0c;7年前我在中兴&#xff0c;偶然一次加了周工的微信&#xff0c;有一次年末&#xff0c;周立功在推广他们的示波器&#xff0c;广哥拉我进周立功的示波器技术支持群微信群&#xff0c;说是周工要给大家发红包。那时候&#…

Python 37 进程池与线程池 、 协程

一&#xff1a;进程池与线程池 提交任务的两种方式&#xff1a; 1、同步调用&#xff1a;提交完一个任务之后&#xff0c;就在原地等待&#xff0c;等任务完完整整地运行完毕拿到结果后&#xff0c;再执行下一行代码&#xff0c;会导致任务是串行执行 2、异步调用&#xff1a;提…

CISCO PIX防火墙的配置

硬件防火墙&#xff0c;是网络间的墙&#xff0c;防止非法侵入&#xff0c;过滤信息等&#xff0c;Cisco PIX防火墙操作系统跟Cisco IOS相似,都是用命令行的方式来进行操作。用配置线从电脑的COM2连到防火墙的console口&#xff0c;进入PIX操作系统采用windows系统里的“超 级终…

在腾讯做嵌入式是怎么样的

昨天发朋友圈&#xff0c;是我帮忙同学拍的几张照片&#xff0c;自己觉得拍的不错&#xff0c;点赞的人还挺多的&#xff0c;就想着聊聊在腾讯做嵌入式软件开发的情况。我面试的BSP驱动开发工程师&#xff0c;入职后也从事这方面的事情&#xff0c;但是并不仅仅是BSP驱动。现在…

Mongoexport导出数据,Mongoimport导入数据,mongodump备份数据,mongorestore恢复恢复

一&#xff1a;Mongoexport导出数据  1,导出json数据    mongoexport -d db -c collection -o save-file.dat 2,导出CSV数据 mongoexport -d db -c collection --typecsv -f field1,field2 -o save-file.dat 说明&#xff1a;db目标数据库&#xff0c;collection目标集合…

NFS无法启动根文件系统的解决

为了调试驱动&#xff0c;整了一天的NFS启动根文件系统出了各种问题&#xff0c;后来还是一一解决&#xff0c;不过还不太完美&#xff0c;因为不能使用交换机&#xff0c;我只能用PC和目标板直连&#xff0c;导致我上网很麻烦 无法挂载问题一&#xff1a; IP-Config: Cannot a…

聊聊身边的嵌入式,为什么老司机都爱后视镜

为什么老司机都爱后视镜有句话形容我们老司机的成长过程&#xff0c;叫&#xff1a;一年虎&#xff0c;二年狼&#xff0c;三年变成小绵羊。如果你不懂这句话的意思&#xff0c;证明你还不是一个合格的老司机。如果没和别人发生过亲(Gua)密(Ceng)接(Shi)触(Gu)&#xff0c;算得…

HDU 2187 悼念512汶川大地震遇难同胞——老人是真饿了

http://acm.hdu.edu.cn/showproblem.php?pid2187 Problem Description时间&#xff1a;2008年5月16日&#xff08;震后第4天&#xff09;地点&#xff1a;汶川县牛脑寨人物&#xff1a;羌族老奶奶【转载整理】牛脑寨是一个全村600多人的羌族寨子&#xff0c;震后几天&#xff…

C语言中sizeof详解——面试C/C++

C面试sizeof详解 1、定义 sizeof是C语言的一种单目操作符&#xff0c;它并不是函数。sizeof操作符以字节形式给出了其操作数所占存储空间的大小。操作数可以是一个表达式或括在括号内的类型名。操作数所占存储空间的大小由操作数的类型决定。作用就是返回一个对象或者类型所占…

第六次周赛

失望…… B题其实很简单&#xff0c;完全有能力出&#xff0c;我和luyi陷在我一个错误的树DP模型中…… 其实就是几个简单的组合数&#xff0c;谁可以都会的问题。 PROBLEM B 1 #include <iostream>2 #include <algorithm>3 #include <cstring>4 #include &l…

博主日常工作中使用的shell脚本分享

前言&#xff1a;今天给大家分享一篇在我工作中常用的一个shell脚本&#xff0c;里面有一些我们常用到的shell操作。该脚本用于本地电脑和服务器交互上&#xff0c;实现以下功能&#xff1a;自动拉取自己个人电脑上的源码到服务器上yocto包的源码文件夹。自动运行compile 、str…

JSON数据提取

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。JSON在数据交换中起到了一个载体的作用&#xff0c;承载着相互传递的数据。JSON适用于进行数据交互的场景&#xff0c;比如网站前…

C语言面试大集合

1、static有什么用途&#xff08;至少说明两种&#xff09;&#xff1f; &#xff08;1&#xff09;限制变量的作用域 &#xff08;2&#xff09;设置变量的存储域 2、引用与指针有什么区别&#xff1f; &#xff08;1&#xff09;引用必须被初始化&#xff0c;指针不必。 &am…

ARP 地址解析协议

目的 作用是IP地址和MAC地址关联。只要有TCP/IP协议的机器中会有一张ARP表&#xff0c;在windows系统中 运行-----cmd------arp –a&#xff0c;就可以看到当前所连接的设备的ip地址和对应的MAC地址。 所谓地址解析&#xff08;address resolution&#xff09;就是主机在发送前…

陆奇给工程师们的5个建议

大家好&#xff0c;我是写代码的篮球球痴今天分享的文章是陆奇以前在百度一次内部演讲给工程师们提的5点要求&#xff0c;个人觉得对很多人非常有益&#xff0c;大家可以耐心一读。至于陆奇是谁&#xff0c;可以直接搜索&#xff0c;借微软CEO斯蒂芬鲍尔默对他的评价 : 陆奇集资…

leetcode 764.Largest Plus Sign

根据题意的话就是在非0的地方开始寻找上下左右分别能够走到的最大步长的。 那么使用暴力的方法竟然leetcode还是给过了。 class Solution { public:int orderOfLargestPlusSign(int N, vector<vector<int>>& mines) {int res0;vector<vector<int>>…