加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

普通GPIO與高速GPIO差異在哪?

2021/11/08
2065
閱讀需 10 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是i.MXRT上的普通GPIO與高速GPIO差異。

GPIO 可以說是 MCU 上最簡(jiǎn)單最常用的外設(shè)模塊了,當(dāng)一些原生功能外設(shè)接口模塊不能滿足項(xiàng)目設(shè)計(jì)要求時(shí),我們常常會(huì)考慮使用 GPIO 來軟件模擬實(shí)現(xiàn)相應(yīng)功能,這時(shí)候 GPIO 本身性能就顯得至關(guān)重要了。

在早期的 i.MXRT1015/1020/1024/1050 型號(hào)上,GPIO 都是普通性能(注意這里的普通其實(shí)相比一般低端 MCU 來說已經(jīng)夠性能優(yōu)越了),考慮到 i.MXRT 是性能怪獸,需要配置更強(qiáng)的 GPIO,因此在后續(xù)的 i.MXRT1010/1060/1064/1160/1170 型號(hào)上,出現(xiàn)了 HSGPIO,今天痞子衡就跟大家聊一聊 GPIO 和 HSGPIO差異:

一、HSGPIO是什么?

HSGPIO 是 High-Speed GPIO 縮寫,有時(shí)候也叫緊耦合 GPIO 或者單時(shí)鐘周期 GPIO,簡(jiǎn)單說就是其模塊(IP)時(shí)鐘源速度高于普通 GPIO 時(shí)鐘源,因此我們可以以更高頻率訪問其模塊寄存器。下表列出了 i.MXRT 各型號(hào)上 HSGPIO 分布:

型號(hào) 普通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 為例,翻看其參考手冊(cè) CCM 時(shí)鐘模塊章節(jié),可以看到普通 GPIO1-5 的時(shí)鐘源是 IPG_CLK_ROOT、而高速 GPIO6-9 的時(shí)鐘源則是 AHB_CLK_ROOT:

在 i.MXRT1060 上 IPG_CLK_ROOT 最高頻率是 150MHz、而 AHB_CLK_ROOT 即內(nèi)核頻率,可到 600MHz,所以單從時(shí)鐘源角度來看,HSGPIO 訪問性能應(yīng)是 GPIO 的四倍:

 

二、共享 PAD 設(shè)計(jì)

芯片內(nèi)部來說,GPIO 與 HSGPIO 模塊是獨(dú)立的,但是因?yàn)樾酒獠?a class="article-link" target="_blank" href="/tag/%E5%BC%95%E8%84%9A/">引腳(PAD)資源有限,因此部分 HSGPIO 是與 GPIO 模塊共享 PAD 的,最終 I/O 實(shí)際性能其實(shí)受限于同一個(gè)物理 PAD 特性。

我們以封裝最簡(jiǎn)單的 i.MXRT1010 為例,下圖最左側(cè)列出了全部的 PAD,其中 GPIO_SD[13:0] 是 HSGPIO 專用引腳,而 GPIO[13:0]、GPIO_AD[14:0] 則是 GPIO 與 HSGPIO 復(fù)用引腳,當(dāng)這些 GPIO/HSGPIO 復(fù)用引腳被配置為 GPIO 功能時(shí),它們既可以映射到 GPIO1(普通GPIO),也可以映射到 GPIO2(HSGPIO):

  • Note:如果已經(jīng)將 GPIO_SD[13:0] 配置為了 GPIO2,則不要再將 GPIO[13:0] 配置為 HSGPIO,會(huì)發(fā)生沖突。

具體 GPIO 映射功能是由 IOMUXC_GPR26 寄存器來控制的(注意這是個(gè)軟復(fù)位不置位的寄存器)。比如當(dāng) GPIO_11 被配置為了 GPIOMUX_IO11 功能時(shí),那么 IOMUXC_GPR26[11] 決定了其映射關(guān)系:

IOMUXC_GPR26[11] = 0,則 GPIO_11 對(duì)應(yīng) GPIO1[11],為普通 GPIO  
IOMUXC_GPR26[11] = 1,則 GPIO_11 對(duì)應(yīng) GPIO2[11],為 HSGPIO

 

下表列出了 i.MXRT 各型號(hào)上 GPIO/HSGPIO 切換控制關(guān)系:

型號(hào) PAD切換控制寄存器 ALT功能名 對(duì)應(yīng)切換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 運(yùn)行速度

前面講了,不管是使能了普通 GPIO 還是 HSGPIO,最終都是由同一個(gè)物理 PAD 來輸出信號(hào),因此 I/O 實(shí)際性能最終受限于這個(gè) PAD 最大運(yùn)行速度。

繼續(xù)以 i.MXRT1010 為例,每個(gè) PAD 在 IOMUXC 模塊里都有一個(gè)專門配置電氣屬性的寄存器 IOMUXC_SW_PAD_CTL_PAD_xxIO,選取 GPIO_11 的相應(yīng)配置寄存器為例,組合其中 SRE、DSE、SPEED 位可以得到不同運(yùn)行速度(具體組合值可在參考手冊(cè) GPIO 章節(jié)搜索 Operating Frequency 小節(jié)查看),不過我們能看到 PAD 最大運(yùn)行速度是 200MHz:

在 i.MXRT1010 數(shù)據(jù)手冊(cè)里,我們還可以看到更具體的 I/O 翻轉(zhuǎn)時(shí)間測(cè)試:

 

四、HSGPIO 示例代碼

基于上面的理論知識(shí),我們改造一下 i.MXRT1010 SDK 里的 driver_examplesgpioled_output 例程,加入如下 HSGPIO 相關(guān)代碼,同樣可以達(dá)到閃爍 LED 燈的功能。

介紹了這么多,如果只是用 HSGPIO 控制小燈閃爍,似乎看不出性能差異,下一篇文章,痞子衡將用示波器為大家實(shí)測(cè) GPIO 與 HSGPIO 極限翻轉(zhuǎn)頻率,再提前劇透一下,GPIO->DR_TOGGLE 和 GPIO->DR 寄存器實(shí)現(xiàn) I/O 翻轉(zhuǎn)效率還不一樣哦。

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 << 11);
        // Slow Slew Rate, 100MHz
        IOMUXC_SetPinConfig(IOMUXC_GPIO_11_GPIOMUX_IO11, 0x70A0U);
        GPIO_PinInit(GPIO1, 11, &led_config);
    }
    else
    {
        // GPIO2
        IOMUXC_GPR->GPR26 |= (1u << 11);
        // Fast Slew Rate, 200MHz
        IOMUXC_SetPinConfig(IOMUXC_GPIO_11_GPIOMUX_IO11, 0x70F9U);
        GPIO_PinInit(GPIO2, 11, &led_config);
    }

    while (1)
    {
        SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        if (is_normal_gpio)
        {
            //GPIO1->DR_TOGGLE = (1u << 11);
            GPIO1->DR ^= (1u << 11);
            __DSB();
        }
        else
        {
            //GPIO2->DR_TOGGLE = (1u << 11);
            GPIO2->DR ^= (1u << 11);
            __DSB();
        }
    }
}

至此,i.MXRT上的普通GPIO與高速GPIO差異痞子衡便介紹完畢了,掌聲在哪里~~~

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會(huì)定期分享嵌入式相關(guān)文章