Blog:
NXP iMX7 异构双核心开发调试

Wednesday, October 31, 2018

简介

在工业领域,很多时候会遇到实时任务和主控界面同时需要的场景,比如工业自动化的控制器等,通常情况下传统做法是分别使用两个独立的处理器,比如一个 Cortex-M4 Arm 处理器来完成实时任务,另外再使用一个 Cortex-A 系列的 Arm 处理器来处理主控界面和命令控制,两个处理器之间再通过某种通讯总线来互联互通,比如串口,SPI之类。

这样做的好处是两个处理器相对分隔独立,但缺点也很明显,系统复杂性提高,数据面和控制面要单独建立,正式基于此 NX P提出了一个新的思路,就是在一个芯片中集成这两个功能核心。

而本文所演示的 Arm 平台来自于 Toradex Apalis iMX7 Arm 嵌入式平台,这是一个基于 NXP iMX7 Arm 处理器的 Arm 计算机模块,在这个芯片中,NXP 将 Cortex-A7 Arm 核心和Cortex-M4 Arm 核心集成到了同一个芯片里面,并且两个核心共享存储和外设资源,这使得对于上面提到的应用模式可以更精巧,高效的实现,接下来本文会基于这个平台进行一个简单的应用开发以及调试示例。

准备

Colibri iMX7S Arm 核心版配合 Colibri Evaluation Board,分别连接 A7 核心默认调试串口 UART1(载板X27)和 M4 核心默认调试串口 UART2(载板X25上)到开发主机方便调试,另外由于 iMX7S 只支持一个 USB 接口,需要通过载板 X30 连接一个 USB Hub 后来扩展键盘鼠标外设。更多关于 Colibri iMX7 的说明请参考 DatasheetLinux 开发上手指南

Colibri iMX7 A7 核心系统使用集成 Q t运行库的 Linux BSP V2.7 版本,如何编译和部署集成 Qt image 以及配置 Qt 开发环境请参考这里

另外,由于本文演示示例使用到了载板上面的 LED 和按键资源,需要连接如下:
X10 SODIMM-106 -> X21 LED3
X10 SODIMM-135 -> X21 LED1
X10 SODIMM-133 -> X21 SW6
X10 SODIMM-127 -> X21 LED2

SEGGER J-Link 仿真器,USB 一端连接开发主机,JTAG一端连接载板 X13。


Colibri iMX7 M4核心FreeRTOS基本资料

Colibri iMX7 架构基本说明请参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7

本示例中 M4 核心运行 FreeRTOS v 8系统,相关的源代码和 sampl e程序请从下面 git下载:
http://git.toradex.cn/cgit/freertos-toradex.git/

基本的 SD K配置和编译请参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Linux_support

编译好的 M4 firmware 如何在 Colibri iMX7 上面加载运行请参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Running_a_Firmware_on_CortexM4

几个自带的 sample 代码简单说明请参考如下:
https://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Examples


Colibri iMX7 M4核心调试环境配置

在上一章节编译部分资料中有提到编译自带 sample code 只需要执行项目中的 build_all.sh 脚本,就可以生成 release 和 debug 项目,然后进入 debug 项目目录,打开“build_debug.sh” 脚本,可以看到通过 “-G” 参数指定了编译系统,这里默认是 “Eclipse CDT4 - Unix Makefiles”,支持的是 Eclipse 指定了,因此本文示例就基于 Eclipse 进行调试。

由于Ubuntu 16.04 系统自带的 Eclipse 版本比较低,不支持后续需要的 plugin,因此需要手动安装最新版本的 Eclipse:

  • 首先安装最新版本的openjdk
$ sudo add-apt-repository ppa:openjdk-r/ppa
$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk
  • 从下面地址下载最新的 Eclipse CPP,解压后可以直接运行,无需安装。

http://www.eclipse.org/downloads/packages/

  • 下载安装 J-Link software and documentation pack,安装好第一次运行,会自动检查 J-Link firmware 并升级到最新版本。

https://www.segger.com/products/debug-probes/j-link/

  • 运行 Eclipse CPP,安装 J-Link GDB plugin
// Main menu -> Help -> install new software
// 输入下面地址
https://dl.bintray.com/gnu-mcu-eclipse/updates/ 
// 在列表里面安装下面plugin
GNU ARM C/C++ J-Link Debugging
  • 在 Eclipse 中导入需要 debug 的项目

选择 File -> Import -> General -> Existing Projects into Workspace。
在 “Select root directory”,输入项目“armgcc/debug”文件夹目录地址,此时会自动识别出已经编译好的 debug 项目,完成项目导入,比如本次示例项目名字为 gpio-freertos,导入如下:

  • 在 Eclipse 中进行debug GDB 参数配置

打开 Run –> Debug Configurations,可以看到左边侧栏中 GDB SEGGER J-Link Debugging 项目下一般会自动出现刚才导入的项目,右边是对应的一些选项。
Main 选项卡,一些基本名字等信息

  • Debugger 选项卡

需要注意的地方:

  1. Device name,Colibri iMX7 对应就是这个名字,具体的列表可以参考这里
  2. Interface 选择使用的仿真器接口,我这里使用的是JTAG的
  3. Other options,非常关键,-scriptfile 指定的文件请从这里下载使用即可,其他参数一样就行,当然熟悉配置的话也可以进行修改。
  4. GDB Client Setup -> Executable,设定为 SDK 目录下的 bin/arm-none-eabi-gdb 文件
  • Startup 选项卡

需要注意的地方:

  1. 取消 Enable flash breakpoints
  2. 添加命令行 monitor reset 0
  3. 勾选 RAM application (reload after each reset/restart)
  • 至此,GDB 配置完毕,点击 Debug 按钮即可进行 debug 了。


Colibri iMX7 M4 核心示例程序

本程序主要实现三个并行任务:

  1. LED1, LED2 和 LED3 的跑马灯任务,时间间隔从最小 100ms 到最大 1000ms,每档间隔为 100ms。
  2. 按键中断任务,每按键一次,跑马灯的时间间隔增加 100ms,如果已经到达 1000ms 上限,再次按键则回到 100ms 初始值。同时在每次跑马灯时间间隔更改后,给 A7 核心系统发消息通知。
  3. 和 A7 核心通讯任务,当接收到 A7 发来的跑马灯时间间隔指令后,按指令配置跑马灯时间间隔,同时配置完成后给 A7 核心发消息通知。

具体代码请见如下 git 地址

https://github.com/simonqin09/iMX7_M4_Runniung_LED_Demo/tree/master/gpio_freertos

代码中对应上面三个任务分别由三个 task 实现

  1. 跑马灯 – ToggleTask
  2. 按键 – SwitchTask
  3. 通讯 – StrEchoTask

ToggleTask 就是简单的通过 vTaskDelay 实现了跑马灯的间隔时间

SwitchTask 通过 GPIO中 断响应,来捕获按键同时更新间隔时间,并通知 A7

StrEchoTask 主要通过 OPAMP/Rpmsg 实现和A7消息的接收,另外通过 Semaphore 来实现几个 task 之间的切换,关于 Semaphore 的使用是异构双核架构下 M4 编程的重点,具体可以参考下面 FreeRTOS 官方文档说明:
https://www.freertos.org/a00113.html


Colibri iMX7 A7 核心示例程序

在展示 A7 程序代码之前需要先进行一些关于 A7 Linux 系统的说明:

由于 iMX7 A7 和 M4 是共享外设,因此在开发前需要先区分好 M4 所需要的外设,同时在 A7 Linux 的 device tree 中将这些外设 disable,以免产生冲突,比如本示例,主要就使用了几个GPIO 资源,以及 M4 调试串口,因此需要在 A7 device tree 中确保未使用对应的 GPIO 和串口资源,具体关于 device tree 的修改编译这里就不详述了,具体可以参考这里。当然,如果只是临时测试,也可以直接在 uboo t中配置,详细可以参考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Running_a_Firmware_on_CortexM4


如果需要 M4 和 A7 通过 Rpmsg 进行通信,需要在 A7 Linux 下加载相关驱动,目前 Toradex Linux BSP V2.7 版本已经包含了驱动,只需要通过下面方式加载即可:

modprobe imx_rpmsg_tty>

另外,如果需要开机自动加载,可以增加一个 systemd 自启动项目来实现。

A7 Rpmsg 通讯的 Qt 应用代码如下:
https://github.com/simonqin09/iMX7_M4_Runniung_LED_Demo/tree/master/qt-rpmsg

程序分为两个线程,主线程 mainwindow 实现主要图形界面显示,同时实现发送消息功能;另外一个子线程主要负责实时获取 M4 发来的消息并显示在主界面的对应位置。

由于 Rpmsg Linux 驱动加载后,会虚拟出一个串口设备,因此基本的发送接收就是 Linux 下串口的基本操作,具体说明可以参考这里。


完整程序的部署测试

首先在 uboot 下通过 SD 卡或者 tftp 将编译好的 M4 核心 firmware 下载保存到 imx7 flash 里面并开机自动加载,通过 SD 卡相关命令可以参考这里

# ubi part ubi
# tftp ${loadaddr} gpio_freertos.elf
# ubi write ${loadaddr} m4firmware ${filesize}
# setenv m4boot 'ubi read ${loadaddr} m4firmware && bootaux ${loadaddr}'
# saveenv

然后进入 Linux,创建两个开机自启动服务,一个用于加载 imx_rpmsg_tty 驱动,另外一个用于加载 Qt 应用程序 qt-rpmsg

script to start imx_rpmsg_tty

$ cd /home/root
$ vi rpmsg
#!/bin/bash
modprobe imx_rpmsg_tty
exit 0

system service file to autorun rpmsg on startup

$ cd /etc/systemd/system
$ vi rpmsg-load.service
[Unit]
Description=load Rpmsg driver
After=multi-user.target
[Service]
Type=simple
ExecStart=/home/root/rpmsg
[Install]
WantedBy=multi-user.target
$ systemctl enable rpmsg-load.service


关于 Qt 应用 qt-rpmsg 的开机自动加载请参考这里说明,这里就不赘述。

重新启动,可以看到在开机马上 uboo t启动瞬间 LED 跑马灯已经开始运转,证明 M4 firmware 已经运行起来,然后 Linux 启动后 Qt 应用起来,可以对跑马灯时间间隔进行增加和减少操作,同时按键更改跑马灯时间间隔的结果也会即时反馈到应用界面上来。

总结

通过上述示例可见,通过 iMX7 这样异构多核架构的处理器,可以更简洁高效的实现原来需要两个分立处理器来完成的任务,简化的硬件设计,软件开发也相对更统一,数据面分享可以直接通过内存共享非常方便,相信未来会有越来越多的嵌入式应用采用这样的方案。

Author: 秦海,技术销售工程师,韬睿(上海)
Share this on:

Leave a comment

Please login to leave a comment!
Have a Question?