首页 > 技术知识 > 正文

在双核的i.MX RT1170下设计应用程序,有一个比较重要的考虑点是片内外设资源共享以及任务分配问题,同样一个任务既可以放在默认主核CM7下做,也可以放在默认从核 CM4下去完成。如果这个任务跟片内外设有关,那就得考虑该外设是否在两个核下设计与使用一致,这在项目开始前必须要调研清楚。

今天就和大家聊一聊i.MX RT1170的GPIO外设的使用,在两个核下有什么异同以及注意点。

在正文开始之前,建议大家先浏览一下我之前写的关于GPIO的两篇文章:《以i.MX RT1xxx的GPIO模块为例谈谈中断处理函数(IRQHandler)的标准流程》、《聊聊i.MX RT1xxx上的普通GPIO与高速GPIO差异及其用法》。

注:本文内容虽以i.MX RT1170为例,但同样适用i.MX RT1160。

一、从引脚看GPIO分组

先聊聊GPIO分组,目前 i.MX RT1170 芯片封装主要是BGA289,除去电源、地、时钟、专用外设引脚外,可用作通用I/O的引脚剩下174个,而芯片内部GPIO模块多达 16个(GPIO1-13、CM7_GPIO2-3),显然GPIO模块太富裕了,显得硬件I/O引脚资源有点紧张,所以不可避免地多个GPIO 模块要复用硬件 I/O引脚,复用关系如下:

GPIO1与GPIO7复用同一组I/O引脚,共32个pin。

GPIO2与GPIO8以及CM7_GPIO2复用同一组I/O引脚,共32个pin。

GPIO3与GPIO9以及CM7_GPIO3复用同一组I/O引脚,共32个pin。

GPIO4与GPIO10复用同一组I/O引脚,共32个pin。

GPIO5与GPIO11复用同一组I/O引脚,共17个pin。

GPIO6与GPIO12复用同一组I/O引脚,共16 个pin。

GPIO13独享一组I/O引脚,共13个pin。

下图是i.MX RT1170 GPIO相关的Pinmux表,其中GPIO1-6、GPIO13主要在Alt5选项里,GPIO7-12主要在 Alt10 选项里,并且大部分I/O引脚默认功能就是GPIO(见表中 DEF 一栏)。此外表中并未看到CM7_GPIO2-3选项,这是因为其和GPIO2-3共用了 Alt5选项(需进一步通过IOMUXC_GPR->GPR40-43寄存器设置)。 i.MX RT1170的GPIO外设的使用-索尼imx传感器排行

二、关于GPIO外设访问

知道了GPIO分组以及I/O引脚复用情况,那么这些GPIO模块是否可以被i.MX RT1170 两个核(CM7/CM4)对等访问呢?我们用官方例程 SDK_2.11.1_MIMXRT1170-EVKoardsevkmimxrt1170driver_examplesgpioled_output 来做测试,这个例程操作的是 MIMXRT1170-EVK 板卡上用于连接 LED 灯的引脚 GPIO_AD_04,从上一节里我们得知这个 I/O 引脚可被用作 GPIO3[3]、CM7_GPIO3[3]、GPIO9[3],因此我们编写了如下三个相应的 gpio 翻转测试函数:)。

gpio_pin_config_t s_ledConfig = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; void toggle_gpio3_3(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0U); IOMUXC_GPR->GPR42 &= ~(1u << 3); GPIO_PinInit(GPIO3, 3, &s_ledConfig); while(1) { SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); GPIO_PortToggle(GPIO3, 1u << 3); } } void toggle_cm7_gpio3_3(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0U); IOMUXC_GPR->GPR42 |= (1u << 3); GPIO_PinInit(CM7_GPIO3, 3, &s_ledConfig); while(1) { SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); GPIO_PortToggle(CM7_GPIO3, 1u << 3); } } void toggle_gpio9_3(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO9_IO03, 0U); GPIO_PinInit(GPIO9, 3, &s_ledConfig); while(1) { SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); GPIO_PortToggle(GPIO9, 1u << 3); } }

我们把上面三个函数分别加到两个核下的 led_output 工程主函数里,并且在板卡上实测,结果如下表。

据此进一步扩展结论,除了 CM7_GPIO2-3 无法在 CM4 内核下被访问外,其余 GPIO1-13 在两个核下都能被正常访问。

注:在 CM4 系统地址映射里,CM7_GPIO2_BASE 0x42008000u、CM7_GPIO3_BASE 0x4200C000u 地址都是不可访问状态。

i.MX RT1170的GPIO外设的使用-索尼imx传感器排行1

三、关于GPIO中断设计

除了 GPIO 外设一般寄存器访问之外,GPIO 中断方面是不是在 i.MX RT1170 两个核(CM7/CM4)下设计也一致呢?这得对比 MIMXRT1176_cm7.h 和 MIMXRT1176_cm4.h 头文件里关于 IRQn_Type 的定义,我将相同项去掉了,只保留差异项的定义对比如下(GPIO 相关的全部保留了):

i.MX RT1170的GPIO外设的使用-索尼imx传感器排行2

大部分外设中断号定义在两个核下都是一致的,这意味着 i.MX RT1170 两个核设计上其实是对等关系。但是 GPIO 中断这里确实是有不小的区别的:

GPIO1-5、GPIO13 中断在两个核下定义一致

GPIO6、CM7_GPIO2-3 中断仅在 CM7 核下有定义

GPIO7-12 中断仅在 CM4 核下有定义

继续以上一节操作的 MIMXRT1170-EVK 板卡上用于连接 LED 灯的引脚 GPIO_AD_04 为例测试其中断情况,编写了相关中断配置使能函数如下:

gpio_pin_config_t s_ledConfig = {kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge}; void GPIO3_Combined_0_15_IRQHandler(void) { GPIO_PortClearInterruptFlags(GPIO3, 1U << 3); SDK_ISR_EXIT_BARRIER; } void config_irq_gpio3_3(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0U); IOMUXC_GPR->GPR42 &= ~(1u << 3); NVIC_EnableIRQ(GPIO3_Combined_0_15_IRQn); GPIO_PinInit(GPIO3, 3, &s_ledConfig); GPIO_PortEnableInterrupts(GPIO3, 1U << 3); } void CM7_GPIO2_3_IRQHandler(void) { GPIO_PortClearInterruptFlags(CM7_GPIO3, 1U << 3); SDK_ISR_EXIT_BARRIER; } void config_irq_cm7_gpio3_3(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0U); IOMUXC_GPR->GPR42 |= (1u << 3); NVIC_EnableIRQ(CM7_GPIO2_3_IRQn); GPIO_PinInit(CM7_GPIO3, 3, &s_ledConfig); GPIO_PortEnableInterrupts(CM7_GPIO3, 1U << 3); } void GPIO7_8_9_10_11_IRQHandler(void) { GPIO_PortClearInterruptFlags(GPIO9, 1U << 3); SDK_ISR_EXIT_BARRIER; } void config_irq_gpio9_3(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO9_IO03, 0U); NVIC_EnableIRQ(GPIO7_8_9_10_11_IRQn); GPIO_PinInit(GPIO9, 3, &s_ledConfig); GPIO_PortEnableInterrupts(GPIO9, 1U << 3); } 我们把上面三个 config 函数分别加到两个核下的 led_output 工程主函数里,并且在板卡上实测,可以使用外部高电平强加到 GPIO_AD_04 引脚(R1855 电阻一端),然后再移除高电平以造出输入电平翻转,测试结果如下表。据此进一步扩展结论,如果希望双核下得到一致的 GPIO 使用体验,建议选择 GPIO1-5、GPIO13。

i.MX RT1170的GPIO外设的使用-索尼imx传感器排行3

审核编辑:彭静

猜你喜欢