datasheet

ZLG周立功单片机

文章数:1218 被阅读:1022397

账号入驻

i.MX RT飞行学习板——如何让C代码在M7上极速飞奔?

2018-11-06
    阅读数:


牡丹虽好,仍需绿叶扶持;RT虽快,仍需优化。本文将分享在i.MX RT飞行学习板中的软件优化办法,让C代码在ARM Cortex-M7内核上极速飞奔!

01

概述



i.MX RT飞行学习板,是真的会飞的处理器学习板!它的核心是恩智浦公司的跨界处理器i.MX RT1052, 基于ARM Cortex-M7内核,主频达600 MHz!对于电机驱动,虽然速度惊人,但是这个学习板要同时运行“4无刷电机FOC驱动 + 飞控算法”,所以依然不是轻易的事情。


牡丹虽好,仍需绿叶扶持,下面将分享多种优化手段,让C代码在i.MX RT上极速飞奔,实现这个“单芯片无人机”。先上段热身视频。

  

视频1 热身视频



02

加快代码速度的秘诀



1、选择硬件浮点


重要而简单的第一步是:在编译器中选择“硬件双精度浮点”,图1是在KEIL中的选择配置。


图1 双精度浮点


选择“硬件双精度浮点”的作用是,当C代码需要双精度、单精度浮点运算,编译器就选择最优的浮点指令,速度最快!如果选择“硬件单精度浮点”,单精度浮点运算就用单精度浮点指令,但双精度浮点运算只能结合多条单精度指令完成,速度较慢。如果不选择任何硬件浮点,编译器仅能用定点指令完成浮点运算,速度非常慢。


但要注意,不是任意处理器都支持“硬件浮点”,即便同样是ARM Cortex-M7内核,有些半导体厂家为了降低成本,会裁掉“双精度浮点”单元,只留下“单精度浮点”。而i.MX RT支持完整的单、双精度浮点单元。得益于这个优势,飞行学习板中的ZLG-Soar飞控软件,全部核心代码都使用双精度浮点指令,不单止精度高、而且速度超快,在相同主频下,比定点指令的Cortex-M3快20倍以上!


2、关键代码RAM中运行


将代码放在ITCM相连的RAM中运行,速度最快!


Cortex-M7的中ITCM(Instruction-Tightly Coupled Memories)是专门的指令总线。我们在i.MX RT1052中分配了256Kbytes的内部RAM在ITCM上,而且和Flash相比,内部RAM没有明显的读取延时,所以代码在这段RAM中运行,速度是最快的,没有更快!


程序清单1是飞行学习板在KEIL中的分散加载的配置,全部只读RO数据(即代码和CONST变量等)放在0x00000400地址开始的ITCM RAM里面。KEIL编译后,其实全部原始数据都是存在Flash中,但 KEIL自动在main函数前插入一段Flash函数,该函数将相关的代码从Flash复制到RAM,最后将PC指针改到RAM。这样代码就从RAM开始运行。


程序清单1 ITCM RAM分散加载


如果代码很大,无法全部复制到RAM中运行,那么可以修改分散加载,仅将必要的代码放在RAM中运行,其他代码在Flash中运行。


3、关键算法写成宏定义


在ZLG-FOC电机矢量控制库中,全部核心算法都写成宏定义的形式,如程序清单2的Clarke变换。


程序清单2 宏定义算法


如果写成C函数,那么上层代码调用时,一般先进行入栈操作、保护现场,接着跳转到该函数运行,然后调用返回指令回到上层代码,最后进行出栈操作、恢复现场。这个过程必然会延长争分夺秒的算法执行时间。


可能有的人会说:在函数前面声明inline,函数不就直接嵌入到上层代码中,省去这些啰嗦过程吗?其实不一定,编译器也是很无奈的,KEIL和IAR的编译手册都说得很明白:根据代码调用与被调用的复杂程度,能嵌进去的,编译器就帮忙嵌进去,不能嵌进去的,只能按普通函数那样处理!


但如果将算法写成宏定义,那么编译会100%保证代码会被直接嵌入到上层代码中!只是对于过长的代码,宏定义编写不方便,这时候可以将代码分拆成多个宏定义组合使用,或者仅把最必要的部分写成宏定义。


4、尽量用C,少用汇编


尽量用C,少用汇编?晚上加班眼花,写反了吧?没写错,“汇编比C快”是好多年前、奔腾电脑时代的事情!现在是人工智能、大数据的时代,KEIL和IAR 的C编译器经过几十年的发展,都变得非常聪明了(GCC笔者使用不多,不敢莽加评论)。首先,人脑能想到的最优指令,C编译器很多时候也能想到,可能比人脑想得更优!再者,用汇编写代码,即便绞尽脑汁,顶多就单个函数速度最优,仅此而已!而C编译器还会“综合统筹”,例如,前后重复的代码,它会合拼在一起;废话、没用的代码,它会删除;函数反复跳转时的出入栈过程,它会想办法减少……再配合上面提到的“算法写成宏定义”,C代码的运行速度将更快!


就如我们敬爱的周工教导说:猪脑不如人脑、人脑不如电脑,i.MX RT在极速飞奔下就是很好的体现。


5、巧妙浮点出入栈


图2显示了Cortex-M7的浮点寄存器,S0-S31是浮点的通用寄存器,其他是控制或状态等寄存器。如果软件使能了浮点单元,那么在中断发生后,M7默认会将S0-S15、FPSCR等17个浮点寄存器硬件入栈,中断完成后硬件出栈。虽然说是“硬件”,其实硬件也要花时间一个一个寄存器弄的,只不过比软件处理,省了调用指令的时间。

 

图2 Cortex-M7浮点寄存器


这里提出一个问题:假如有10个中断程序轮流产生,处理器就自动对17个浮点寄存器出入栈操作,但如果仅只有一个中断使用了浮点指令,其他9个都不使用,那么大部分浮点出入栈的操作都是浪费时间的!


如何解决这个问题呢?


ARM提出一种LAZY模式(其实一点都不懒),在中断发生后,硬件只给17个浮点寄存器预留堆栈空间,但不入栈,只有中断函数调用了第一条浮点指令前(例如浮点加、减、乘、除),硬件才补充入栈;中断完成后,如果真的发生过硬件浮点入栈,才会相应地出栈。这样大大提高了浮点出入栈的效率!这种LAZY模式够聪明吧,真不知ARM怎样起名的,可能懒的极端就是聪明吧。


6、代码清晰、聪明


图3中的两条蛇在树上互相纠缠,分不清尾巴是谁的。写代码也同样道理,如果习惯性地想到一点写一点、写前不规划、写后懒修改,就像图3左边的代码,一堆if/else,逻辑模糊、难懂、难改,运行速度没保证。而右边的代码是经过分析推理的聪明办法,用switch case替代一堆if/else,逻辑清晰、易懂、易改,运行速度有保证! 

 

图3 清晰聪明的代码


前面介绍了很多在i.MX RT上加快代码速度的方法,但都是辅助的,最核心的还是:花点心思规划代码要怎样写,代码要清晰、聪明。



03

总结



牡丹虽好,仍需绿叶扶持,RT虽快,但仍需优化才能发挥到极致的速度,将不可能的事情变为现实!就如我们ZLG的i.MX RT飞行学习板,是业界唯一的“4无刷电机FOC +飞控算法”的无人机方案。


11月初期的广州还是茵茵绿草,我们踏青放飞去。

  

视频2 踏青放飞


ZLG飞行学习板在上海的中国进口博览会NXP展台展出


欢迎莅临2018上海进口博览会


恩智浦展位


一起体验AI-IoT未来科技吧!


3H-3A4-002


时间:2018年11月5日-11月10日



任何疑惑可添加ZLG官方客服微信号咨询:zlgmcu-888



周立功单片机介绍


广州周立功单片机科技有限公司成立于1999年,专注于芯片分销业务与增值服务,是国际半导体进入中国首选的合作品牌。

自主研发产品:嵌入式工业自动化与通讯网络产品和解决方案、嵌入式测量测试仪器、嵌入式系统集成开发环境、楼宇自动化产品和解决方案、嵌入式系统教学产品等;

公司经营理念:为客户提供完整的供应保证系统及深具行业水准的市场化产品以体现、创造、赢得价值。

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: TI培训

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved