从C到Simulink: ARM Compiler 5 (RVDS) 为什么simulink 不能使用arm编译
先把结论说在前面:
- Simulink"在电脑上跑仿真"这件事,本质是用你电脑上的宿主编译器(Windows 上一般是 MSVC 或 MinGW/GCC)来编译 C/C++ 代码。
- ARM Compiler 5(RVDS)是一个"交叉编译器",它只能生成 ARM 芯片跑的机器码,不能生成 Windows x64 程序,所以 MathWorks 根本没有把它列为支持宿主仿真的编译器。
- 因此:Simulink 的 MEX/Simulink 仿真构建系统里,根本没有"把 ARM Compiler 当宿主编译器"这一条选项。
所以,不是你不会配,而是这条路官方压根就没支持。
一、从"编译器类型"理解:交叉编译器 vs 宿主编译器
- ARM Compiler 5(RVDS/ARMCC):
- 目标平台:ARM Cortex(例如你现在的 Cortex-M7)
- 宿主平台:通常也是 Windows,但编译出来的是 ARM 机器码
- 只能用来给板子编译固件,不能在 PC 上直接跑
- Simulink 仿真用的宿主编译器:
- 目标平台:和你 MATLAB 一样的平台(Windows x64、macOS ARM、Linux x64 等)
- 常见就是:
- Microsoft Visual C++(MSVC)
- MinGW-w64(GCC 在 Windows 上的移植)
- macOS 上的 Xcode Clang
- Linux 上的系统 GCC
MathWorks 的"支持的编译器列表"里,Windows 上支持的就是这些宿主编译器:MinGW 和 Microsoft Visual C++,并没有 ARM Compiler【turn0fetch0】。
也就是说,MEX/Simulink 仿真构建系统只认识这几家,ARM Compiler 根本不在名单里。
二、官方文档怎么说?
在 MathWorks 的"支持的编译器列表(Windows)"页面中,列出的 Simulink/MEX 用到的编译器只有【turn0fetch0】:
- MinGW-w64 C/C++(例如 MinGW 8.1、MinGW 6.3)
- Microsoft Visual C++ 2017 / 2019 / 2022
- Intel oneAPI(C/C++、Fortran)
没有 ARM Compiler,也没有 IAR,也没有 TI 编译器这些"嵌入式交叉编译器"。
而 MEX 选择编译器的命令是:
matlab
mex -setup
它会列出"MATLAB 支持的已安装编译器"【turn0search0】【turn0search17】。
你在 Windows 上 mex -setup 的时候,只会看到:
- MinGW
- Microsoft Visual C++
- (也许还有 Intel oneAPI)
绝对不会出现 ARM Compiler / RVDS。
三、为什么不能直接用 ARM Compiler 在 PC 上跑仿真?
从技术上讲,有几点原因:
- ARM Compiler 不生成 x64/Windows 代码
它的后端只支持 ARM 目标(例如 ARMv7-M,ARMv7-A 等),不能生成 Windows x64 本地可执行文件(.exe / .dll / .mexw64)。
而 Simulink 仿真需要的就是能在本机上直接加载执行的 MEX 文件(本质就是 DLL),所以 ARM Compiler 完全不满足这个前提。 - MEX 构建系统只对接特定编译器
MathWorks 给 MEX 写了适配层,只对有限的几种编译器做了配置:- 知道调用命令行的参数格式
- 知道怎么链接 MATLAB API / Simulink API
- 知道怎么处理运行时库等
他们没有为 ARM Compiler 做这种适配。
- 即使能调起来,也跑不了
就算你手动让 ARM Compiler 编译出一个 Windows 模块(实际它也做不到),那模块里调用的还是 ARM 的 runtime、CMSIS、HAL 这些,这些库根本没法在 Windows 上运行。
真要跑,只能用 QEMU、TrueSTILE 等虚拟机/模拟器,但那已经完全超出 Simulink"宿主仿真"的范畴。
四、那我在 Simulink 里要怎么利用 ARM Compiler?
真正用到 ARM Compiler 的,只有这些情况:
- 生成代码,然后:
- 在 Keil MDK/STM32CubeIDE 里手动编译;
- 或者用 Embedded Coder 自动调用 Keil/IAR 命令行做"代码生成 + 编译"。
- 使用 PIL(Processor-in-the-Loop)模式:
- 代码仍然在板子上用 ARM Compiler 编译;
- Simulink 通过 JTAG/串口/以太网和板子通信;
- 仿真结果从板子拿回来,而不是在本机上直接跑。
但这些模式下:
- 宿主仿真(Normal/Accelerator 模式)还是用 MSVC/MinGW;
- 只是"目标端"的代码使用 ARM Compiler。
五、所以你现在遇到的问题,本质是什么?
你现在遇到的是这样一个组合:
- 宿主仿真用:MinGW/GCC(通过
mex -setup选的) - 但你 FreeRTOS 代码引用的是:
.../FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/portmacro.h
这是"宿主编译器是 GCC,但代码却写给 RVDS(ARM Compiler 5)"的典型错配,所以 RVDS 特有的语法 GCC 不认识,就报了expected a ")"之类的语法错误。
正确的做法是:
- 宿主仿真(本机跑):
- 编译器用 MinGW/GCC 或 MSVC;
- FreeRTOS 移植层用
.../portable/GCC/ARM_CM7/...; - 或者更彻底:只引用 FreeRTOS 的核心 API 头文件,移植层用 stub 打桩(前面回答已经讲过)。
- 生成代码跑在板子:
- 用 Keil/STM32CubeIDE,把编译器切回 ARM Compiler 5/6;
- 这时候用
.../portable/RVDS/ARM_CM7/...完全没问题。
六、总结一句话版
- ARM Compiler 5(RVDS)是一个"给 ARM 芯片生成固件"的交叉编译器,根本不能在 PC 上直接编译出 Simulink 仿真需要的 MEX 文件;
- MathWorks 官方支持的宿主仿真编译器只有 MSVC 和 MinGW/GCC 这类"PC 本地编译器",没有 ARM Compiler【turn0fetch0】;
- 所以你在 Simulink 里不能(也不应该)把 ARM Compiler 当作仿真编译器,而是:
- 仿真用 MinGW/MSVC + 对应的移植文件(GCC 版本或 stub);
- 真正的 ARM 固件才在 Keil/STM32CubeIDE 里用 ARM Compiler 编译。