良许Linux教程网 干货合集 MCU普通GPIO与高速GPIO的差异

MCU普通GPIO与高速GPIO的差异

今天我要向大家介绍的是i.MXRT芯片上的普通GPIO和高速GPIO之间的差异。

GPIO是MCU上最简单、最常用的外设模块之一。当一些原生功能外设接口模块无法满足项目设计需求时,我们经常会考虑使用GPIO来软件模拟实现相应功能,这时GPIO本身的性能显得尤为重要。

在早期的 i.MXRT1015/1020/1024/1050型号上,GPIO都是普通性能(虽然相比一般低端的MCU来说已经非常优秀了)。考虑到i.MXRT是一种性能强大的芯片,需要更强的GPIO功能,因此在后续的i.MXRT1010/1060/1064/1160/1170型号上,出现了高速GPIO(HSGPIO)。

一、HSGPIO是什么?

HSGPIO是High-Speed GPIO的缩写,有时也称为紧耦合GPIO或单时钟周期GPIO。简单来说,它是指其模块(IP)的时钟源速度高于普通GPIO的时钟源,因此我们可以以更高的频率访问其模块寄存器。下表列出了i.MXRT各型号上HSGPIO的分布情况:

型号 普通GPIO 高速GPIO
i.MXRT1010 GPIO1、GPIO5 GPIO2
i.MXRT1060/1064 GPIO1 – GPIO5 GPIO6 – GPIO9
i.MXRT1160/1170 GPIO1 – GPIO13 CM7_GPIO2、CM7_GPIO3

我们以 i.MXRT1060 为例,翻看其参考手册 CCM 时钟模块章节,可以看到普通 GPIO1-5 的时钟源是 IPG_CLK_ROOT、而高速 GPIO6-9 的时钟源则是 AHB_CLK_ROOT:

image-20231114220147216
image-20231114220147216

在 i.MXRT1060 上 IPG_CLK_ROOT 最高频率是 150MHz、而 AHB_CLK_ROOT 即内核频率,可到 600MHz,所以单从时钟源角度来看,HSGPIO 访问性能应是 GPIO 的四倍:

image-20231114220238930
image-20231114220238930

二、共享 PAD 设计

从芯片内部来说,GPIO 与 HSGPIO 模块是独立的,但是因为芯片外部引脚(PAD)资源有限,因此部分 HSGPIO 是与 GPIO 模块共享 PAD 的,最终 I/O 实际性能其实受限于同一个物理 PAD 特性。

我们以封装最简单的 i.MXRT1010 为例,下图最左侧列出了全部的 PAD,其中 GPIO_SD[13:0] 是 HSGPIO 专用引脚,而 GPIO[13:0]、GPIO_AD[14:0] 则是 GPIO 与 HSGPIO 复用引脚,当这些 GPIO/HSGPIO 复用引脚被配置为 GPIO 功能时,它们既可以映射到 GPIO1(普通GPIO),也可以映射到 GPIO2(HSGPIO):

  • Note:如果已经将 GPIO_SD[13:0] 配置为了 GPIO2,则不要再将 GPIO[13:0] 配置为 HSGPIO,会发生冲突。
image-20231114220246429
image-20231114220246429

具体 GPIO 映射功能是由 IOMUXC_GPR26 寄存器来控制的(注意这是个软复位不置位的寄存器)。比如当 GPIO_11 被配置为了 GPIOMUX_IO11 功能时,那么 IOMUXC_GPR26[11] 决定了其映射关系:

IOMUXC_GPR26[11] = 0,则 GPIO_11 对应 GPIO1[11],为普通 GPIO  
IOMUXC_GPR26[11] = 1,则 GPIO_11 对应 GPIO2[11],为 HSGPIO
image-20231114220249979
image-20231114220249979

下表列出了 i.MXRT 各型号上 GPIO/HSGPIO 切换控制关系:

型号 PAD切换控制寄存器 ALT功能名 对应切换GPIO
i.MXRT1010 IOMUXC_GPR->GPR26 GPIO_MUX GPIO1与GPIO2
i.MXRT1060/1064 IOMUXC_GPR->GPR26 IOMUXC_GPR->GPR27 IOMUXC_GPR->GPR28 IOMUXC_GPR->GPR29 GPIO_MUX1 GPIO_MUX2 GPIO_MUX3 GPIO_MUX4 GPIO1与GPIO6 GPIO2与GPIO7 GPIO3与GPIO8 GPIO4与GPIO9
i.MXRT1160/1170 IOMUXC_GPR->GPR40、41 IOMUXC_GPR->GPR42、43 GPIO_MUX2 GPIO_MUX3 GPIO2与CM7_GPIO2 GPIO3与CM7_GPIO3

三、PAD 运行速度

前面讲了,不管是使能了普通 GPIO 还是 HSGPIO,最终都是由同一个物理 PAD 来输出信号,因此 I/O 实际性能最终受限于这个 PAD 最大运行速度。

继续以 i.MXRT1010 为例,每个 PAD 在 IOMUXC 模块里都有一个专门配置电气属性的寄存器 IOMUXC_SW_PAD_CTL_PAD_xxIO,选取 GPIO_11 的相应配置寄存器为例,组合其中 SRE、DSE、SPEED 位可以得到不同运行速度(具体组合值可在参考手册 GPIO 章节搜索 Operating Frequency 小节查看),不过我们能看到 PAD 最大运行速度是 200MHz:

image-20231114220253579
image-20231114220253579

在 i.MXRT1010 数据手册里,我们还可以看到更具体的 I/O 翻转时间测试:

image-20231114220257441
image-20231114220257441

四、HSGPIO 示例代码

基于上面的理论知识,我们改造一下 i.MXRT1010 SDK 里的 \driver_examples\gpio\led_output 例程,加入如下 HSGPIO 相关代码,同样可以达到闪烁 LED 灯的功能。

介绍了这么多,如果只是用 HSGPIO 控制小灯闪烁,似乎看不出性能差异,下一篇文章,作者将用示波器为大家实测 GPIO 与 HSGPIO 极限翻转频率,再提前剧透一下,GPIO->DR_TOGGLE 和 GPIO->DR 寄存器实现 I/O 翻转效率还不一样哦。

bool is_normal_gpio = false;

int main(void)
{
    BOARD_ConfigMPU();
    BOARD_InitBootClocks();

    /* Define the init structure for the output LED pin*/
    gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};

    CLOCK_EnableClock(kCLOCK_Iomuxc);      
    IOMUXC_SetPinMux(IOMUXC_GPIO_11_GPIOMUX_IO11, 0U); 
    if (is_normal_gpio)
    {
        // GPIO1
        IOMUXC_GPR->GPR26 &= ~(1u else
    {
        // GPIO2
        IOMUXC_GPR->GPR26 |= (1u while (1)
    {
        SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        if (is_normal_gpio)
        {
            //GPIO1->DR_TOGGLE = (1u DR ^= (1u else
        {
            //GPIO2->DR_TOGGLE = (1u DR ^= (1u 

至此,i.MXRT上的普通GPIO与高速GPIO差异便介绍完毕了。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部