"); //-->
1). 简介
FreeRTOS是广泛使用的开源实时操作系统, 被众多芯片厂商包括NXP所支持, 本文就展示在NXP iMX7 ARM处理器上面的M4核心上面部署FreeRTOS.
NXP iMX7 ARM处理器是NXP最新推出的异构双核处理器, 主核心为单核或者双核Cortex-A7,通常运行Linux/WinCE操作系统来作为嵌入式应用主程序界面环境; 副核心为Cortex-M4, 通常运行实时操作系统来为嵌入式应用提供高效可靠的实时应用处理. 一个简略的iMX7芯片框图如下所示.

由上图可见, 多种类型的内存可供使用, 包括M4专属的内存空间 (Tightly Coupled Memory, TCM), 虽然很小但是CPU可以无延迟访问; 多个OCRAM区域 (On-Chip RAM, 通常是SRAM), 同样访问非常快而且提供相对大的容量; 最后就是DRR3主内存空间. 出于性能考虑, 请尽可能优先使用片内内存资源.
另外, M4有两个总线连接到AXI/AHB interconnect, 一个负责数据传输,另一个负责指令传输, 因此为了最好的性能优化, 我们需要将数据放置与连接数据总线的区域,而指令代码放置与连接指令总线的区域. 例如, 对于TCM, 则放置代码于TCML空间, 而放置数据于TCMU空间.
然后关于Resource Domain Controller (RDC), 对于iMX7,由于Cortex-A7和Cortex-M4核心内存和外设的访问都是共享且平等的,为了保证不产生资源冲突,通过这个控制器来从硬件层面对指定内存和外设的访问权限进行保护. RDC 允许定义最多4个resource domains, 并将不同的内存和外设资源指定到这些resource domain中. 默认情况下, A7核心和相关外设被指定于domain 0, 当FreeRTOS firmware运行后, M4核心以及相关外设最初也是domain 0, 但马上被重新指定到domain 1. 因此如果一个外设需要被M4使用, 但同时A7 Linux kernel也使用了, 就需要修改A7 Linux Device Tree来禁止这个外设 (详细操作方法请见这里).
本文就基于Toradex Colibri iMX7 (基于NXP iMX7 SoC) ARM计算机模块搭配Colibri Eva Board开发板来演示编译和部署FreeRTOS应用. 区别与传统的MCU处理器, firmware通常从内置的NOR Flash加载, Colibri iMX7则并没有这样的配置, 而是将firmware存放于外部存储设备中如SD卡或者模块上的Nand Flash, 同时这些存储并不是 “memory mapped”, 因此CPU无法直接执行存储在这里的firmware, 而是要先被加载到内存区域后才能被执行.
对于Colibri iMX7, 系统总是由Cortex-A7核心来启动, 先执行内部boot ROM后启动如U-boot这样的boot loader, 然后由boot loader从上述的存储设备加载firmware到内存,最后在触发Cortex-M4核心去执行这个firmware. 而如果需要更新或者替换firmware,只需要更改存储设备上面的firmware镜像即可.
2). 准备
a). 硬件准备
./ Colibri iMX7计算机模块和Colibri Eva Board开发板
./ Ubuntu Linux开发主机
b). 软件准备
./ iMX7模块Cortex-A7核心运行Toradex Embedded Linux release V2.6 Beta2
./ Ubuntu Linux开发主机
FreeRTOS source code
交叉编译ToolChain - Linaro ARM Embedded, 4.9 2015-Q3 update - 从这里下载
3). 配置
a). 下载FreeRTOS for Colibri iMX7
------------------------
$ git clone -b master-1.0.1 git://git.toradex.com/freertos-toradex.git freertos-colibri-imx7/
$ cd freertos-colibri-imx7/
------------------------
b). 解压缩交叉编译工具
------------------------
$ tar xjf gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2
//如果开发主机是Ubuntu 64bit 操作系统,则需要安装下面32bit支持包
$ sudo dpkg --add-architecture i386
$ sudo apt-get update
$ sudo apt-get install libc6:i386 libncurses5:i386
//测试gcc运行
$ cd .../gcc-arm-none-eabi-4_9-2015q3/bin/
$./arm-none-eabi-gcc --version
//安装 make 和 Cmake 工具
$ sudo apt-get install make cmake
------------------------
4). 编译FreeRTOS
FreeRTOS 的 examples 目录下提供了诸多例程,在编译前需要先设置叉编译工具路径的环境变量ARMGCC_DIR, 然后运行armgcc子目录下准备好的编译脚本即可进行编译.
------------------------
$ export ARMGCC_DIR=.../gcc-arm-none-eabi-4_9-2015q3/
$ cd .../freertos-colibri-imx7/examples/imx7_colibri_m4/demo_apps/hello_world/armgcc
$ ./build_all.sh
------------------------
编译好的可执行文件位于armgcc下的release和debug子目录下, 可以加载到M4核心上面运行了.
5). 在M4核心上面运行Firmware
a). M4的固件程序在Colibri iMX7 A7核心Linux系统U-Boot中进行加载, 将编译好的 hello_world.bin程序放到SD卡根目录 (FAT32格式) ,并连接到开发板上.
------------------------
Colibri iMX7 # fatload mmc 0:1 0x7F8000 hello_world.bin
...
Colibri iMX7 # dcache flush
Colibri iMX7 # bootaux 0x7F8000
## Starting auxiliary core at 0x007F8000 ...
------------------------
b). FreeRTOS 默认使用 UARTB 作为其调试输出串口, 波特率设置115200 8N1。A7 Linux 默认device tree设置也会访问UARTB, 为了防止出现冲突, 推荐在device tree 中禁用 UARTB(设置status参数)。也可以在 U-Boot 中添加下面参数,临时禁用 UARTB。
------------------------
Colibri iMX7 # setenv fdt_fixup 'fdt addr ${fdt_addr_r} && fdt rm /soc/aips-bus@30800000/spba-bus@30800000/serial@30890000'
Colibri iMX7 # saveenv
------------------------
c). Linux会自动关闭不使用设备的时钟,但A7核心Linux无法知道哪些时钟在M4核心上面被使用,因此需要添加下面内核参数来保证M4相关时钟正常。
------------------------
Colibri iMX7 # setenv defargs clk_ignore_unused
------------------------
d). 通过另外一个窗口连接UARTB, 可以收到hello world程序运行后的打印输出
------------------------
$ sudo minicom -D /dev/ttyUSB1 -b 115200
Welcome to minicom 2.7
......
Port /dev/ttyUSB1, 11:52:46
Press CTRL-A Z for help on special keys
Hello World!
------------------------
e). 自动启动加载 M4 上运行的程序
// 运行下面命令将SD卡上面的程序文件复制到系统为M4程序单独提供的ubi分区空间
------------------------
Colibri iMX7 # ubi part ubi
...
Colibri iMX7 # fatload mmc 0:1 ${loadaddr} hello_world.bin
...
Colibri iMX7 # ubi write ${loadaddr} m4firmware ${filesize}
------------------------
// 设置启动变量,之后U-Boot会在开机启动Linux前先启动M4程序
------------------------
Colibri iMX7 # setenv m4boot 'ubi read 0x7F8000 m4firmware && dcache flush && bootaux 0x7F8000'
Colibri iMX7 # saveenv
------------------------
6). M4 程序示例
除了上面测试的hello world, 在examples目录中还有很多示例程序.
a). GPIO示例
// 例程位置: .../examples/imx7_colibri_m4/driver_examples/gpio_imx/
// 同上述方法编译后生成应用: gpio_imx_example.bin
// 例程中使用EXT_IO1作为按键输入, EXT_IO0作为输出控制LED; 在Colibri 评估板上面, 利用X21将对应Pin脚和组件相连:
------------------------
EXT_IO0 => X21-LED1
EXT_IO1 => X21-SW6
------------------------
// 在Uboot运行程序, 由于A7 Linux Device Tree也定义了这几个GPIO, 因此测试只在U-Boot环境下进行.
------------------------
====================== GPIO Example ========================
=================== GPIO Interrupt =====================
The (EXT_IO1) button is configured to trigger GPIO interrupt
Press the (EXT_IO1) button 3 times to continue.
Button pressed 1 time.
Button pressed 2 time.
Button pressed 3 time.
================= GPIO Functionality==================
The button state is now polled.
Press the button to switch LED on or off
Button pressed 1 times
Button pressed 2 times
...
------------------------
b). RPMsg示例 - M4和A7通讯
// 例程位置: .../examples/imx7_colibri_m4/demo_apps/rpmsg/str_echo_freertos/
// 同上述方法编译后生成应用: rpmsg_str_echo_freertos_example.bin
// A7 Linux kernel对应module 源文件: drivers/rpmsg/imx_rpmsg_tty.c
// U-Boot执行如下命令
------------------------
fatload mmc 0:1 0x7F8000 rpmsg_str_echo_freertos_example.bin
reading rpmsg_str_echo_freertos_example.bin
20860 bytes read in 21 ms (969.7 KiB/s)
Colibri iMX7 # dcache flush
Colibri iMX7 # bootaux 0x7F8000
## Starting auxiliary core at 0x007F8000 ...
Colibri iMX7 # run ubiboot
------------------------
// M4 串口输出
------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
RPMSG Init as Remote
------------------------
// A7 Linux下执行下面命令
------------------------
$ modprobe imx_rpmsg_tty
[ 184.656763] imx_rpmsg_tty rpmsg0: new channel: 0x400 -> 0x0!
[ 184.663331] Install rpmsg tty driver!
$ stty -F /dev/ttyRPMSG -echo
$ exec 3<> /dev/ttyRPMSG
$ echo Test >&3
$ cat <&3
Test
^C
$ exec 3>&-
------------------------
// M4串口对应输出
------------------------
RPMSG String Echo FreeRTOS RTOS API Demo...
RPMSG Init as Remote
Name service handshake is done, M4 has setup a rpmsg channel [0 ---> 1024]
Get Message From Master Side : "Test" [len : 4]
Get New Line From Master Side
------------------------
// 如需将Linux kernel module 设置为开机自动加载
------------------------
$ echo imx_rpmsg_tty > /etc/modules-load.d/rpmsg_tty.conf
------------------------
// 另外关于RPMsg还有其他如pingpong demo, 可以自行测试.
7). 总结
本文对iMX7 异构双核架构进行了说明, 并基于Toradex Colibri iMX7 模块演示了在M4核心上面运行FreeRTOS例程以及A7和M4核心通过RPMsg通信例程, 相信对NXP iMX7架构以及应用有了一个初步的了解, 其非常适合用于同时有人机交互和实时控制的工业应用场景, 同时非常低的功耗也使得整个嵌入式系统的稳定可靠性有了很好的保证.
参考文档
http://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
宏基董事长施振荣称要控制中国大陆IT制造业
[推荐]国家半导体公司 模拟技术大学 运算放大器学习资料-低速通用运放
Rapidus宣布推出一套AI设计工具
[推荐]音频小辞典
1000米小型立体声调频发射机
TI更易用的精密电压参考IC
[单板EMC设计翻译文章](几乎全部)
新研究探讨可穿戴鲨鱼驱避装置
自制感光电路板制作PCB的过程(2)
Anthropic让AI代理技能成为开放标准
自动置零放大器使高精度电路的设计变得容易
想要与众不同?Windows Embedded帮你实现
意法半导体和SpaceX共庆星链全球互联关键技术合作十年历程
[电源设计实例]25w~500w电源和NIMHNICD 电池快速充电器-linear
DB2二十年记
京瓷的海底激光链路将距离换成千兆速度
利用高压母线转换模块 (BCM) 为LED驱动器供电
开放应用NGN的时代
IPv6带来全新的服务体验
第六届中国国际国防电子展览会介绍
美欧汽车制造商减缓电动汽车发展计划
拿下沪穗两大城市 准单向收费将攻克北京
MCP6V01热电偶自动调零参考设计
Windowns Embedded入门课程-XP Embedded开发初体验
自制感光电路板制作PCB的过程(1)
GlobalFoundries与onsemi合作开发200毫米氮化镓产品组合
用CD4040制作的电子电位器
自制感光电路板制作PCB的过程(3)
Metalens 提升显微 3D 打印精度
该阀门可将电动车快充时间缩短一半