1. 本文要解决什么问题
本文记录一次在 Windows 下使用 Keil MDK 配置 TI MSPM0G3507 开发环境时遇到的完整排错过程。
目标是让 Keil 能够正常编译 MSPM0G3507 的空白工程:
empty_LP_MSPM0G3507_nortos_keil排查过程中主要遇到了以下几类问题:
系统找不到指定的路径。armclang: error: no such file or directory: '../ti_msp_dl_config.c'error: 'ti_msp_dl_config.h' file not foundCouldn't find .metadata\product.json Invalid argument '-s': File "C:\.metadata\product.json" does not existerror: 'ti/devices/msp/msp.h' file not foundL6002U: Could not open file ../../source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a这些错误看起来分散,但本质上都和一个问题有关:
Keil 工程被移动后,工程里的相对路径不再指向正确的 MSPM0 SDK 目录,导致 SysConfig 脚本、SDK 头文件和 driverlib 静态库都找不到。
2. 我的环境信息
本文中的路径和版本来自本次实际排错环境:
Keil MDK 编译器:ARMCLANG V6.24 Keil 安装路径:C:\d\Keil5\MDK\ARM\ARMCLANG\Bin MSPM0 SDK 路径:C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05 SysConfig 路径:C:\Ti\SYSCONFIG\sysconfig_cli.bat 工程路径:C:\Ti\Project\empty\keil 工程名:empty_LP_MSPM0G3507_nortos_keil 芯片/开发板:MSPM0G3507 / LP_MSPM0G3507如果你的安装路径不同,需要把本文中的路径替换成你自己电脑上的真实路径。
例如:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05需要替换为你自己的 MSPM0 SDK 安装目录。
3. 背景知识:为什么 MSPM0 工程依赖 SysConfig
TI MSPM0 工程通常不是纯手写初始化代码,而是通过 SysConfig 生成一部分外设配置代码。
工程里会有一个文件:
empty.syscfg这个文件不是 C 源码,而是 SysConfig 的配置文件。Keil 在编译前会先调用 TI 的 SysConfig 工具,根据empty.syscfg生成下面两个文件:
ti_msp_dl_config.c ti_msp_dl_config.h然后工程中的业务代码再包含这个头文件:
#include "ti_msp_dl_config.h"所以如果 SysConfig 没有正常运行,就会出现:
../ti_msp_dl_config.c 找不到 ti_msp_dl_config.h file not found这类错误不是 C 代码写错了,而是编译前的代码生成步骤没有成功执行。
4. 第一个问题:Before Build 找不到 syscfg.bat
最开始 Keil 编译时出现了下面的日志:
Before Build - User command #1: cmd.exe /C "C:\Ti\Project\empty\keil\../../tools/keil/syscfg.bat 'C:\Ti\Project\empty\keil\' empty.syscfg" 系统找不到指定的路径。后面紧跟着出现:
armclang: error: no such file or directory: '../ti_msp_dl_config.c' ../empty.c(33): error: 'ti_msp_dl_config.h' file not found4.1 原因分析
Keil 的 Before Build 命令中使用了相对路径:
../../tools/keil/syscfg.bat当前工程路径是:
C:\Ti\Project\empty\keil所以这个相对路径实际会被解析为:
C:\Ti\Project\tools\keil\syscfg.bat但是syscfg.bat实际在 MSPM0 SDK 目录中:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat因此 Keil 找不到脚本。
4.2 解决方法
进入 Keil:
Project -> Options for Target -> User -> Before Build/Rebuild把 Before Build 命令改成绝对路径:
cmd.exe /C call "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil" empty.syscfg这里需要注意两点:
第一,使用call调用.bat文件。
第二,工程路径最后不要加反斜杠:
"C:\Ti\Project\empty\keil"不要写成:
"C:\Ti\Project\empty\keil\"否则 Windows 命令行解析引号时容易出错。
5. 第二个问题:cmd /C 引号解析错误
修改命令后,曾经出现过下面的错误:
'C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil\' 不是内部或外部命令,也不是可运行的程序或批处理文件。5.1 原因分析
原命令类似这样:
cmd.exe /C "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil\" empty.syscfgcmd.exe /C后面如果第一个内容就是带引号的可执行路径,后面又接参数,Windows 有时会把命令和参数拼接错。
5.2 解决方法
使用call:
cmd.exe /C call "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil" empty.syscfg重新编译后,Keil 日志中能看到:
Using Sysconfig Tool from "C:\Ti\SYSCONFIG\sysconfig_cli.bat"说明syscfg.bat已经被成功调用。
6. 第三个问题:Couldn't find .metadata\product.json
虽然syscfg.bat已经被调用,但又出现了新的错误:
"Couldn't find .metadata\product.json" Invalid argument '-s': File "C:\.metadata\product.json" does not exist6.1 原因分析
MSPM0 SDK 根目录下有一个重要文件:
.metadata\product.json正常情况下,它应该位于:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\.metadata\product.json但是 TI 提供的tools\keil\syscfg.bat默认会从工程目录开始,一层一层向上查找.metadata\product.json。
当前工程在:
C:\Ti\Project\empty\keil脚本会依次查找:
C:\Ti\Project\empty\keil\.metadata\product.json C:\Ti\Project\empty\.metadata\product.json C:\Ti\Project\.metadata\product.json C:\Ti\.metadata\product.json C:\.metadata\product.json它不会自动跳到:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05所以最后报错:
File "C:\.metadata\product.json" does not exist6.2 解决方法一:把工程放回 SDK 根目录
这是最推荐的方式。
如果参考的教程要求把empty工程复制到 SDK 根目录下,那么工程路径应该类似:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\empty\keil而不是:
C:\Ti\Project\empty\keil这样syscfg.bat从工程目录向上查找时,就能找到:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\.metadata\product.json此时 Before Build 可以使用相对路径:
cmd.exe /C call "$P../../tools/keil/syscfg.bat" "$P" empty.syscfg其中$P是 Keil 当前工程目录。
如果工程位于:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\empty\keil那么:
$P../../tools/keil/syscfg.bat就会指向:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat6.3 解决方法二:工程放在外部目录时,固定 SDK_ROOT
如果必须把工程放在:
C:\Ti\Project\empty\keil那么就不能继续依赖syscfg.bat自动向上查找 SDK 根目录,而应该在脚本里固定 SDK 路径。
可以备份原始文件:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat然后把它改成类似下面的版本:
@echo off set "SYSCFG_PATH=C:\Ti\SYSCONFIG\sysconfig_cli.bat" set "SDK_ROOT=C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05" if not exist "%SYSCFG_PATH%" ( echo Couldn't find SysConfig Tool: "%SYSCFG_PATH%" exit /b 1 ) if not exist "%SDK_ROOT%\.metadata\product.json" ( echo Couldn't find SDK product file: "%SDK_ROOT%\.metadata\product.json" exit /b 1 ) set "PROJ_DIR=%~1" set "PROJ_DIR=%PROJ_DIR:'=%" set "SYSCFG_FILE=%~2" set "SYSCFG_FILE=%SYSCFG_FILE:'=%" if "%PROJ_DIR:~-1%"=="\" set "PROJ_DIR=%PROJ_DIR:~0,-1%" echo Using SysConfig Tool from "%SYSCFG_PATH%" echo Using SDK from "%SDK_ROOT%" echo Project dir: "%PROJ_DIR%" echo Syscfg file: "%SYSCFG_FILE%" call "%SYSCFG_PATH%" -o "%PROJ_DIR%\.." -s "%SDK_ROOT%\.metadata\product.json" --compiler keil "%PROJ_DIR%\%SYSCFG_FILE%"改完后,Keil 的 Before Build 保持:
cmd.exe /C call "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil" empty.syscfg成功时日志应该出现:
Using SysConfig Tool from "C:\Ti\SYSCONFIG\sysconfig_cli.bat" Using SDK from "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05" Project dir: "C:\Ti\Project\empty\keil" Syscfg file: "empty.syscfg"不应该再出现:
Couldn't find .metadata\product.json Invalid argument '-s': File "C:\.metadata\product.json" does not exist7. 第四个问题:ti/devices/msp/msp.h file not found
解决 SysConfig 脚本调用后,继续编译时出现:
..\ti_msp_dl_config.h(54): error: 'ti/devices/msp/msp.h' file not found 54 | #include <ti/devices/msp/msp.h> | ^~~~~~~~~~~~~~~~~~~~~~7.1 原因分析
ti_msp_dl_config.h中包含了:
#include <ti/devices/msp/msp.h>这个头文件属于 MSPM0 SDK,通常位于:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\devices\msp\msp.h由于代码中写的是:
#include <ti/devices/msp/msp.h>所以 Keil 的 Include Path 必须包含 SDK 的source目录:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source如果 Include Path 没加这个目录,编译器就无法找到ti/devices/msp/msp.h。
7.2 解决方法
进入 Keil:
Project -> Options for Target -> C/C++ (AC6) -> Include Paths添加:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source如果你的工程放在 SDK 根目录下,也可以使用相对路径:
../../source如果后续出现 CMSIS 相关头文件找不到,可以再添加:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\third_party\CMSIS\Core\Include但针对本文中的msp.h报错,首先需要添加的是:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source7.3 验证方法
重新 Rebuild。
如果这个问题解决,日志中不应该再出现:
'ti/devices/msp/msp.h' file not found编译阶段应该能够通过,并进入链接阶段。
8. 第五个问题:链接阶段找不到 driverlib.a
编译阶段通过后,又遇到链接错误:
linking... .\Objects\empty_LP_MSPM0G3507_nortos_keil.axf: error: L6002U: Could not open file ../../source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a: No such file or directory8.1 原因分析
这次不是头文件找不到,而是链接器找不到静态库:
driverlib.aKeil 工程里原来的库路径是:
../../source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a如果工程在 SDK 根目录下,例如:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\empty\keil那么这个相对路径能正确指向:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a但当前工程在:
C:\Ti\Project\empty\keil相对路径会被解析为:
C:\Ti\Project\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a这个路径不存在,所以链接失败。
8.2 解决方法
先确认真实库文件是否存在。
在 CMD 中运行:
dir C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a如果文件存在,就说明只是 Keil 工程里的库路径错了。
进入 Keil:
Project -> Options for Target -> Linker查找是否存在:
../../source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a把它改成绝对路径:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a如果 Keil 对反斜杠兼容不好,可以写成:
C:/Ti/M0_SDK/mspm0_sdk_2_02_00_05/source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a也可以在 Keil 左侧工程树中找到driverlib.a,右键查看属性,把它的路径从相对路径改成 SDK 中的真实路径。
8.3 如果找不到 driverlib.a
如果上面的dir命令提示找不到文件,可以在 SDK 目录中搜索:
dir C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\driverlib.a /s找到真实路径后,再把 Keil 里的库路径改成对应位置。
9. 两种可行的最终配置方案
经过排查,可以总结出两种可行方案。
方案 A:工程放在 SDK 根目录下
这是最接近 TI 官方例程和教程设计的方式。
目录结构如下:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05 ├── .metadata │ └── product.json ├── source ├── tools │ └── keil │ └── syscfg.bat └── empty └── keil └── empty_LP_MSPM0G3507_nortos_keil.uvprojxKeil 的 Before Build:
cmd.exe /C call "$P../../tools/keil/syscfg.bat" "$P" empty.syscfgInclude Path 使用:
../../sourcedriverlib.a 使用:
../../source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a这种方式的优点是:相对路径基本不用改。
缺点是:工程需要放在 SDK 目录下,不太适合后续自己管理多个项目。
方案 B:工程放在自定义目录,所有 SDK 路径改成绝对路径
如果希望工程放在:
C:\Ti\Project\empty\keil那么必须处理三类路径。
第一,Before Build 调用 SDK 中的syscfg.bat:
cmd.exe /C call "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil" empty.syscfg第二,syscfg.bat里固定 SDK_ROOT:
set "SDK_ROOT=C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05"第三,Keil 的 Include Path 加 SDK source:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source第四,Linker 中的driverlib.a改成绝对路径:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a这种方式的优点是:工程可以放在自己的项目目录中。
缺点是:需要手动维护路径。如果换 SDK 版本,需要同步修改路径。
10. 如何验证最终配置成功
配置完成后,在 Keil 中执行:
Project -> Rebuild all target files成功时应该满足以下条件。
第一,SysConfig 阶段不再出现:
Couldn't find .metadata\product.json第二,编译阶段不再出现:
'ti/devices/msp/msp.h' file not found第三,链接阶段不再出现:
L6002U: Could not open file driverlib.a第四,最终应该生成:
Objects\empty_LP_MSPM0G3507_nortos_keil.axfKeil 输出中应该类似:
0 Error(s), 0 Warning(s) Target created.如果能看到Target created,说明工程已经完成编译和链接。
11. 常见问题汇总
问题一:系统找不到指定的路径
现象:
Before Build - User command #1: cmd.exe /C "...\tools/keil/syscfg.bat ..." 系统找不到指定的路径。原因:
Keil 的 Before Build 命令中syscfg.bat路径错误。通常是工程被复制到了 SDK 外部目录,导致相对路径失效。
解决:
把 Before Build 改成真实路径:
cmd.exe /C call "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil" empty.syscfg或者把工程放回 SDK 根目录,继续使用相对路径。
验证:
重新编译后,日志中应该出现:
Using Sysconfig Tool from "C:\Ti\SYSCONFIG\sysconfig_cli.bat"问题二:ti_msp_dl_config.h file not found
现象:
../empty.c(33): error: 'ti_msp_dl_config.h' file not found原因:
SysConfig 没有成功运行,导致ti_msp_dl_config.c和ti_msp_dl_config.h没有生成。
解决:
先修复 Before Build 中的 SysConfig 调用命令,确保empty.syscfg能生成对应 C/H 文件。
验证:
工程目录上一级应该能看到:
ti_msp_dl_config.c ti_msp_dl_config.h问题三:Couldn't find .metadata\product.json
现象:
"Couldn't find .metadata\product.json" Invalid argument '-s': File "C:\.metadata\product.json" does not exist原因:
syscfg.bat没有找到 SDK 根目录。常见原因是工程不在 SDK 目录树下。
解决:
推荐把工程放到 SDK 根目录下:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\empty\keil如果必须放在外部目录,则修改syscfg.bat,固定:
set "SDK_ROOT=C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05"验证:
重新编译后,不应再出现C:\.metadata\product.json相关错误。
问题四:ti/devices/msp/msp.h file not found
现象:
error: 'ti/devices/msp/msp.h' file not found原因:
Keil Include Path 没有包含 MSPM0 SDK 的source目录。
解决:
在 Keil 中添加 Include Path:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source验证:
重新编译后,不再出现msp.h file not found。
问题五:L6002U Could not open driverlib.a
现象:
L6002U: Could not open file ../../source/ti/driverlib/lib/keil/m0p/mspm0g1x0x_g3x0x/driverlib.a原因:
链接器中的driverlib.a路径仍然是相对路径,但工程已经不在 SDK 根目录下,相对路径解析错误。
解决:
把库文件路径改成绝对路径:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a验证:
重新 Rebuild,链接阶段不再报 L6002U。
12. 工程化建议
如果只是跟着教程跑通第一个工程,建议使用方案 A:把工程放到 SDK 根目录下。这样最少改路径,最容易和教程保持一致。
如果后续要自己维护多个项目,建议使用方案 B:工程放在自己的项目目录中,但要统一管理 SDK 路径。
可以约定一个固定 SDK 根目录:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05然后在 Keil 中统一使用绝对路径:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a这样即使工程移动,编译也不会因为相对路径失效。
但这种方式也有代价:如果升级 SDK 版本,例如从:
mspm0_sdk_2_02_00_05升级到:
mspm0_sdk_2_xx_xx_xx需要同步修改 Keil 工程中的路径。
13. 完整复现清单
13.1 准备文件
需要准备:
Keil MDK MSPM0 SDK TI SysConfig MSPM0G3507 Keil 示例工程本文环境中的关键路径是:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05 C:\Ti\SYSCONFIG\sysconfig_cli.bat C:\Ti\Project\empty\keil13.2 检查 SysConfig
确认文件存在:
dir C:\Ti\SYSCONFIG\sysconfig_cli.bat13.3 检查 SDK product.json
确认文件存在:
dir C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\.metadata\product.json13.4 检查 SDK 头文件
确认文件存在:
dir C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\devices\msp\msp.h13.5 检查 driverlib.a
确认文件存在:
dir C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a如果找不到,搜索:
dir C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\driverlib.a /s13.6 配置 Before Build
Keil 中配置:
Project -> Options for Target -> User -> Before Build/Rebuild如果工程在 SDK 外部目录,使用:
cmd.exe /C call "C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\tools\keil\syscfg.bat" "C:\Ti\Project\empty\keil" empty.syscfg13.7 配置 Include Path
Keil 中配置:
Project -> Options for Target -> C/C++ (AC6) -> Include Paths添加:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source13.8 配置 driverlib.a
Keil 中配置:
Project -> Options for Target -> Linker把driverlib.a路径改成:
C:\Ti\M0_SDK\mspm0_sdk_2_02_00_05\source\ti\driverlib\lib\keil\m0p\mspm0g1x0x_g3x0x\driverlib.a13.9 Rebuild 验证
在 Keil 中执行:
Project -> Rebuild all target files成功时应该看到:
Target created. 0 Error(s), 0 Warning(s)14. 总结
这次 Keil 配置 MSPM0G3507 环境的核心问题不是编译器错误,也不是 C 代码错误,而是工程路径移动后,TI 示例工程中的相对路径失效。
整个排错过程可以归纳为三类路径问题:
第一,SysConfig 脚本路径错误,导致ti_msp_dl_config.c/h无法生成。
第二,SDK Include Path 缺失,导致ti/devices/msp/msp.h找不到。
第三,driverlib 静态库路径错误,导致链接器找不到driverlib.a。
如果按教程把工程放在 SDK 根目录下,很多相对路径可以直接成立。如果要把工程放到自己的项目目录中,就需要把 SysConfig、SDK source、driverlib.a 这几个路径全部改成明确的绝对路径。
遇到这类问题时,不要只盯着最后一条报错。Keil 的日志要从上往下看,第一条路径错误往往才是真正根因。后面的ti_msp_dl_config.h not found、msp.h not found、driverlib.a not found,通常都是前面路径配置错误引发的连锁反应。