
CC2642R1 这块片子我从第一代 CC2640 就开始跟中间换过 CCS、换过 IAR最后落到 VSCode 上前后折腾了大概三四个晚上才把编译、烧录、单步调试这一整条链路捋顺。CC2642R1 属于 TI SimpleLink CC26x2R 系列Arm Cortex-M4F 主核跑到 48MHz配上 352KB Flash、80KB SRAM 加 8KB 可配置 GPRAM协议栈只跑 BLE是很多低功耗蓝牙产品的常青树。官方主推的 IDE 是 CCS功能确实全但索引慢、启动笨重写业务代码的时候体验一般。把 CC2642R1 的 Vscode环境开发跑通之后日常改代码、加断点、看寄存器都顺畅了很多插件生态也能顺手用上。这篇内容适合已经摸过嵌入式、想换掉笨重 IDE 的人也适合刚拿到 LAUNCHXL-CC26X2R1 开发板、对着 SDK 目录发懵的新手。我不会只贴几条命令了事而是把每一步背后的原因讲清楚让版本对不上、路径找不到、断点打不上的时候你自己也能定位。1. 先把 CC2642R1 这套软件栈拆开看1.1 芯片结构决定了你不可能只面对一个工程CC2642R1 的内部不是一颗单核 MCU它是一颗 Cortex-M4F 应用核搭一颗 Cortex-M0 射频核另外还塞了一个 Sensor Controller 协处理器专门干那种主核睡了也要周期采样的活。射频核跑的是 TI 烧在 ROM 里的固件你平时碰不到但 BLE 协议栈的实时性、时序精度全靠它。这个结构带来的直接后果是你写的应用代码只是整个镜像的一部分协议栈库、射频驱动、启动代码、链接脚本、CCFG 配置区缺一样都起不来。传统 CCS 工程会把一个 BLE 例程拆成两个工程一个 stack 工程产协议栈镜像或者库一个 app 工程产应用镜像烧录的时候两个镜像都要落进 Flash。SDK 5.x 之后 TI 把协议栈做成了库的形式构建流程简化为链接一个ble5stack库但概念上的分层没变。你在 VSCode 里搭环境本质上就是把 CCS 那套 Eclipse 的构建逻辑换成 CMake 加命令行把 Eclipse 的调试前端换成 Cortex-Debug。想明白这一点后面很多配置就不难理解了——我们要复现的是同一套编译和调试行为只是换了个外壳。1.2 官方 SDK 里究竟装了什么从官网下载下来的simplelink_cc13xx_cc26xx_sdk解压后是个大杂烩第一次看确实容易懵。我把关键目录列一下方便你对照目录作用是否必须关注examples/rtos/CC26X2R1_LAUNCHXL/按协议栈分类的例程ble5stack 下面就是 BLE 例子必看source/ti/驱动、协议栈、RTOS、中间件源码必看kernel/tirtos7/TI-RTOS7 内核SDK 7.x 的默认内核必看tools/CMake 工具链文件、SysConfig 相关、烧录脚本必看docs/API 文档和 Release Note排查时看.metadata/产品元数据命令行工具会读它别删例程目录的结构也值得留意。每个例程下面一般会有ticlang/、gcc/、iar/若干子目录对应不同编译器。我们要走的是ticlang/这条线因为 TI Arm Clang 是官方当前主推的编译器TI-RTOS7 和最新协议栈都围绕它做了适配。目录里通常能看到CMakeLists.txt、一个.cmake文件以及.syscfg配置文件这三样东西就是整个构建的骨架。.syscfg描述外设和协议栈配置.cmake里写源文件列表和编译宏CMakeLists.txt负责把它们组织起来。搞清楚这三者的分工改工程的时候你就知道该动哪个文件了。1.3 VSCode 方案和 CCS 方案的边界在哪先把预期摆正VSCode 方案不是要把 CCS 完全踢出局而是让你在 90% 的日常时间里待在更顺手的编辑器里。有几个场景我仍然会打开 CCS比如用 SysConfig 图形界面配引脚、用 UniFlash 做整片擦除、或者需要看 TI 官方那种带图形化寄存器视图的调试界面。这些属于低频操作忍一忍没问题。为什么值得折腾一是构建速度快CMake 加 Ninja 的增量编译通常几秒钟就完事CCS 那种 Eclipse 构建动辄半分钟二是代码导航舒服几万行的协议栈源码里跳转、查引用比 Eclipse 的索引靠谱得多三是可脚本化整套构建和烧录都能写成命令行接进你自己的自动化流程里四是插件生态Git 集成、格式化、静态检查这些都能顺手接进来。代价也很明确没有图形化配置向导初始搭建需要你手动理清路径和参数出问题时报错信息比 CCS 生硬。接受这个交换后面就顺了。2. 装机清单版本对不上后面全是坑2.1 一份能跑通的版本矩阵TI 这套工具链最让人头疼的就是版本耦合。SDK、编译器、SysConfig、XDCTools 之间存在兼容矩阵Release Note 里写得清清楚楚但很多人不看就直接装最新版然后在链接阶段收获一堆莫名其妙的符号缺失。我踩过的坑是拿新编译器配老 SDK协议栈库的.a文件是旧编译器产物链接时 ABI 不兼容报错信息完全不指向根因。下面这套组合是我实测跑得很稳的一组你可以直接照抄也可以按自己手上 SDK 的 Release Note 微调组件建议版本说明SimpleLink SDKsimplelink_cc13xx_cc26xx_sdk_7_10_01_247.10 是长期维护版本例程完整TI Arm Clangti-cgt-armllvm_2.1.3.LTS或3.2.0.LTS以 SDK 文档标注为准SysConfigsysconfig_1.16.x与 SDK 版本绑定XDCToolsxdctools_3_62_01_16_coreTI-RTOS7 构建依赖CMake3.20 以上建议 3.24 以上Ninja1.10 以上比 Make 快很多OpenOCD0.12.0带 CC26x2 板级配置Python3.8 以上SysConfig 和部分脚本要调用注意不要同时装多个大版本 SDK 却共用同一个编译器目录。构建脚本里经常用相对路径往上找工具链混装之后可能出现本地能编、换台机器就挂的情况。2.2 TI 工具链的安装位置与目录约定Windows 上我习惯把所有 TI 工具统一装在C:/ti/下面不用默认的带空格的 Program Files 路径。原因很实在CMake 和某些脚本对带空格的路径处理不干净报错时你还得多花时间怀疑是路径问题。装完之后目录大概长这样C:/ti/ ├── simplelink_cc13xx_cc26xx_sdk_7_10_01_24/ ├── ti-cgt-armllvm_2.1.3.LTS/ ├── sysconfig_1.16.2/ └── xdctools_3_62_01_16_core/SDK 建议直接用官方安装器跑一遍别手动解压压缩包。安装器会在系统里注册环境变量还会把工具链路径写进.metadata/product.json命令行构建的时候能自动找到依赖。手动解压很容易漏掉这一步结果 CMake 配置阶段直接报找不到编译器。装完之后做两件事第一把 SDK 的tools目录路径记下来后面 CMake 工具链文件就在这里第二把 TI Arm Clang 的bin目录加进系统 PATH这样在终端里直接敲tiarmclang --version就能验证。我见过不少人卡在这一步其实是 PATH 没生效或者加进了 PATH 但没重开终端。2.3 VSCode 本体与必装插件VSCode 直接从官网下载安装包装上就行注意选 System Installer 而不是 User Installer前者对右键菜单和文件关联支持更完整。装完之后把在 PATH 中添加那个选项勾上这样命令行里code .能直接打开当前目录。插件这块不需要堆一屏五个就够用了C/C微软官方那个负责语法高亮、跳转定义、IntelliSense。装完记得关掉它自带的自动补全提示不然跟 clangd 打架。CMake Tools提供 CMake 构建、配置选择、目标切换。它和 CMake 命令行并不冲突图形界面顺手很多。Cortex-Debug嵌入式调试的核心插件GDB 集成、寄存器视图、外设寄存器解析、反汇编、内存查看全靠它。clangd可选但强烈建议代码索引和跳转比 C/C 插件快一大截尤其是面对 SDN 那几万行协议栈源码时。用它的话需要在工程根目录放一个compile_commands.json。Code Spell Checker之类的小工具随便不影响主流程。compile_commands.json是让编辑器理解你工程的关键。CMake 加一个-DCMAKE_EXPORT_COMPILE_COMMANDSON参数就会在构建目录里生成它把它软链接或者复制到工程根目录clangd 就能准确找到每个源文件的头文件路径和宏定义。这一步不做的话打开ble5stack的源码会满屏红波浪线跳转也会跳到错误的地方。3. 从示例工程跑通第一次编译3.1 看懂 SDK 的目录结构和构建入口不要一上来就想着把自己项目搭起来。先在 SDK 里找一个最小例程跑通确认整条链路没问题再把配置往自己的工程上搬。我一般选hex_peripheral它是个透传服务例程功能简单、依赖最少。路径大致是SDK/examples/rtos/CC26X2R1_LAUNCHXL/ble5stack/hex_peripheral/ticlang/进去之后你会看到CMakeLists.txt、hex_peripheral.cmake、hex_peripheral.syscfg这几个文件。CMakeLists.txt内容通常很短它做的主要是引入 SDK 提供的公共构建脚本比如common.cmake然后调用一个宏把工程装配起来。具体的源文件、编译定义、包含路径都写在.cmake文件里。这种设计的好处是不同例程之间高度一致坏处是你第一次看会找不到编译宏在哪定义。记住一个原则找编译宏去.cmake找外设配置去.syscfg找工具链和全局参数去 SDK 的tools/cmake。在终端里先确认几个环境变量。SDK 安装器有时会把COM_TI_SIMPLELINK_CC13XX_CC26XX_SDK_INSTALL_DIR写进系统变量有的版本则要你自己设。保险起见在构建前手动 export 一遍export TI_SDK_PATHC:/ti/simplelink_cc13xx_cc26xx_sdk_7_10_01_24 export SYSCONFIG_TOOLC:/ti/sysconfig_1.16.2/sysconfig_cli.bat这两个变量在构建脚本里会被引用缺了会直接报错。3.2 CMake 构建流程逐步拆解进入ticlang目录按下面的方式配置构建。工具链文件的文件名以你手上 SDK 为准进tools/cmake目录 ls 一眼就知道cd $TI_SDK_PATH/examples/rtos/CC26X2R1_LAUNCHXL/ble5stack/hex_peripheral/ticlang cmake -S . -B build -G Ninja \ -DCMAKE_TOOLCHAIN_FILE$TI_SDK_PATH/tools/cmake/ticlang.cmake \ -DCMAKE_BUILD_TYPEDebug \ -DCMAKE_EXPORT_COMPILE_COMMANDSON几个参数逐个说明。-S .指定源码目录就当前目录-B build把生成物全部丢进 build 子目录保持源码树干净。-G Ninja指定生成器Ninja 的增量构建比 Make 快得多。-DCMAKE_TOOLCHAIN_FILE是最关键的一环这个文件里定义了交叉编译器的绝对路径、目标架构thumbv7em、浮点 ABIhard、以及一堆 TI 特有的编译选项。-DCMAKE_BUILD_TYPEDebug会带上-Og和调试符号方便后面单步。-DCMAKE_EXPORT_COMPILE_COMMANDSON就是前面提到的编辑器索引文件。配置阶段跑完控制台会打印出一串信息里面能看到编译器版本、SysConfig 版本、目标板型号。这三项任何一个显示为空或者版本号明显不对都别急着往下走。然后开始构建cmake --build build -j 8-j 8按你机器的核心数调整。第一次构建会比较久因为要编译 TI-RTOS7 内核和协议栈库三五分钟正常。之后的增量构建通常只要几秒到十几秒。构建成功后在build目录下能找到.out文件那是 TI 格式的可执行镜像Cortex-Debug 和烧录工具都认它。同时也会生成.hex和.bin看你要用哪种烧录方式。提示如果你拿到的是 SDK 6.20 之前的版本可能没有完整的 CMake 支持那就得退回 Makefile 路线用ticlang/Makefile配合gmake。命令行参数不同但思路一致。建议还是升到 7.x。3.3 链接脚本、内存布局与 CCFG 那点事构建跑通之后我建议你花十分钟看一眼链接脚本因为它决定了你的程序能不能跑起来。CC26x2R1 的内存布局大致是这样区域起始地址大小用途Flash0x00000000352 KB代码与常量CCFG0x00057FA888 B启动配置区放在 Flash 末尾SRAM0x2000000080 KB数据、栈、堆GPRAM0x110000008 KB可配为缓存或通用 RAM外设0x40000000-寄存器映射CCFG 那个 88 字节区域特别容易被忽略。它里面定义了是否启用引导加载程序、是否擦除外部 Flash、是否锁定调试接口等等。链接脚本里会用CCFG段把它固定在 Flash 最末尾如果你的程序体积超过了0x00057FA7链接器会直接报段溢出。所以当你删掉某个大数组之后突然构建成功或者加了个大缓冲区之后链接失败第一反应就该去查 Flash 占用。GPRAM 这 8KB 也有讲究。它可以配置成射频核的缓存能明显提升 BLE 收发性能也可以当普通 RAM 给主核用。配置方式通常是通过 SysConfig 或者 CCFG 里的一个设置项。默认例程一般会把它设成缓存如果你内存吃紧想征用它记得同时确认协议栈对这部分内存的假设别想当然地拿走。BLE 协议栈本身在 Flash 里占得不小ble5stack 的几个变体从 100KB 到 150KB 不等具体看你开了哪些功能。也就是说 352KB 里留给应用的空间大约只有 200KB 出头。做产品的时候经常是功能越加越多Flash 就悄悄满了所以从项目初期就该关注 map 文件的体积变化别等到发布前才发现塞不下。4. 调试与烧录链路怎么打通4.1 XDS110 驱动与探针识别LAUNCHXL-CC26X2R1 板载调试器就是 XDS110插上 USB 之后设备管理器里应该能看到两个串口一个 Application UART一个 Auxiliary UART和一个 XDS110 Debug Probe。驱动一般随 CCS 一起装如果你没装 CCS单独去下 XDS110 驱动包也能装上。识别不正常的典型症状有三种。第一种是设备管理器里出现带黄色感叹号的未知设备那基本是驱动没装对重新装一遍驱动包里的.inf就行。第二种是能看到设备但调试工具连不上这种情况我遇到过好几次最后发现是板子上电顺序的问题——先把板子通过 USB 插上再开电脑或者用了不带数据传输功能的充电线。第三种是能连上但一读内存就断连八成是探针固件版本太老用 CCS 自带的 XDS110 Firmware Updater 升级一下固件。验证探针是否正常可以用 UniFlash 或者dslite命令行工具做个简单探测。命令行方式大概是这样dslite.sh --mode processors -c XDS110 -f firmware.hex -d CC26X2R1F能看到芯片型号被正确识别说明硬件链路是通的再去配 VSCode 就不会怀疑是硬件问题。4.2 launch.json 字段逐个说明调试配置放在工程根目录的.vscode/launch.json里。一份能用的 Cortex-Debug 配置长这样{ version: 0.2.0, configurations: [ { name: CC26X2R1 Debug, type: cortex-debug, request: launch, servertype: openocd, cwd: ${workspaceFolder}, executable: ${workspaceFolder}/build/hex_peripheral.out, device: CC26x2R1, configFiles: [ board/ti_cc26x2_launchpad.cfg ], gdbPath: C:/ti/ti-cgt-armllvm_2.1.3.LTS/bin/arm-none-eabi-gdb.exe, preLaunchTask: cmake-build, runToEntryPoint: main, svdFile: ${workspaceFolder}/.vscode/CC26X2R1.svd } ] }逐条解释几个容易出错的字段。servertype选openocd因为 OpenOCD 从 0.11 开始就带了 CC26x2 的板级配置文件board/ti_cc26x2_launchpad.cfg会自动引入 XDS110 的接口配置所以configFiles里只写板级文件一条就够不用手动加 interface。gdbPath指向 TI Arm Clang 工具链自带的 GDB具体文件名不同版本略有差异进bin目录 ls 一下按实际的填。preLaunchTask指向.vscode/tasks.json里定义的一个构建任务这样每次点调试都会先编译一次避免调试的镜像和源码脱节。svdFile是可选项但强烈建议配上它能让 Cortex-Debug 显示外设寄存器的名字而不是冷冰冰的地址看 GPIO、UART、定时器状态的时候效率天差地别。SVD 文件在 TI 的器件支持包里能找到。对应的tasks.json大致是{ version: 2.0.0, tasks: [ { label: cmake-build, type: shell, command: cmake --build build -j 8, options: { cwd: ${workspaceFolder} }, group: { kind: build, isDefault: true }, problemMatcher: [$gcc] } ] }4.3 SysConfig 的接入方式SysConfig 是 TI 这几年推的图形化配置工具引脚复用、外设初始化、协议栈参数都在.syscfg文件里描述构建时由命令行工具生成ti_devices_config.c、ti_drivers_config.c等一堆源文件。这个流程在 CMake 构建里已经自动接好了你不需要手动调但要知道它什么时候跑、产物在哪。产物默认落在构建目录下的syscfg子目录里。如果你想在 VSCode 里可视化编辑.syscfg可以装 TI 提供的 SysConfig 插件或者直接用 CCS 打开那个文件改完再回来编译。命令行方式是这样sysconfig_cli.bat -s $TI_SDK_PATH/.metadata/product.json \ -o build/syscfg --compiler ticlang hex_peripheral.syscfg最容易出问题的地方是 SysConfig 的版本。SDK 的.metadata/product.json里写死了它期望的 SysConfig 版本范围版本对不上会直接报错退出错误信息还算清晰。另一个坑是.syscfg文件被改坏之后生成阶段的报错指向的是生成文件而不是源文件看着一头雾水。碰到这种情况我一般先用命令行单独跑一遍 SysConfig 生成看看能不能定位到具体哪一行配置有问题。注意不要手动去改 SysConfig 生成的ti_*.c/h文件。下次构建它们会被覆盖你的修改直接蒸发。所有配置都要回到.syscfg层面去做。5. 常见问题速查与排查实录5.1 编译期最容易撞上的几堵墙CMake Error: Could not find toolchain file这种报错九成是路径写错了或者用的是反斜杠。CMake 在 Windows 上对路径比较敏感建议统一用正斜杠或者用 CMake 变量拼出来。另一种可能是 SDK 装完之后你改了目录名脚本里写死的路径就失效了。找不到头文件的报错通常长这样fatal error: ti/drivers/GPIO.h file not found。这类问题一般出在编译定义或者包含路径没生效根源往往在.cmake文件。排查方法是打开构建目录里的compile_commands.json搜一下出问题的那个源文件看看它的-I参数里到底有没有你期望的路径。这比盯着 CMakeLists 层层追要快得多。链接阶段报符号未定义尤其是ble5stack相关的符号多半是协议栈库没构建或者没链接进来。SDK 的 CMake 脚本一般会自动处理这个依赖但如果你的工程是自己从零写的就得手动把库路径和库名加进去。还有一种情况是编译宏不一致比如应用编译时定义了BLE_V42_FEATURES协议栈库构建时没定义双方对同一个结构体大小的理解不同链接时就炸了。5.2 调试期的异常表现与处理思路断点打上去变成空心圆说明调试器没法把断点落到代码地址上。原因有两种一是编译时没生成调试符号检查CMAKE_BUILD_TYPE是不是 Debug二是实际烧录进去的镜像和本地源码不一致重新构建再烧一次基本能解决。单步跳进协议栈代码之后停下来或者在中断里卡死通常是调试器把射频核也暂停了。BLE 协议栈对时序很敏感主核长时间暂停会导致射频核超时连接断开。调试 BLE 应用时要注意别在射频活动期间长时间挂起必要的时候把连接间隔调大一些再调。程序烧进去跑不起来串口没输出第一件事是确认复位向量和 CCFG 配置。如果 CCFG 里的启动配置被写坏了芯片可能一上电就进不了应用。用 UniFlash 做一次全片擦除再重新烧录通常能救回来。第二件事是确认时钟配置CC26x2R1 默认用 48MHz 晶振如果你的板子换过晶振或者用了内部 RCSysConfig 里要同步改否则射频根本起不来。5.3 常见问题速查表现象大概率原因处理方式配置阶段找不到工具链路径错误或反斜杠统一用正斜杠确认文件存在头文件找不到包含路径或宏未生效查compile_commands.json的-I链接报协议栈符号未定义库未链接或宏不一致检查库路径与编译定义Flash 段溢出代码超 352KB看 map 文件裁剪功能或优化等级断点打不上无调试符号或镜像不匹配用 Debug 构建并重新烧录调试时连接断开主核挂起导致射频超时缩短暂停时间调大连接间隔上电无输出CCFG 或时钟配置异常全片擦除重烧核对晶振配置探针连不上驱动、线缆或固件问题换数据线升级 XDS110 固件SysConfig 生成失败版本不匹配或配置语法错误单独跑 CLI 定位具体行增量构建异常缓慢生成器用了 Make 而非 Ninja加-G Ninja重新配置6. 几个让我少加班的小习惯6.1 工作区与多工程的组织方式同时跟几个项目的时候我习惯一个物理工程配一个 VSCode 工作区不搞那种一个窗口开一堆文件夹的玩法。原因是每个工程的 SDK 版本、编译器版本可能不同.vscode里的路径配置也不一样混在一个窗口里特别容易串。真要统一管理可以用多根工作区但每个根目录下各自维护自己的settings.json和launch.json别指望全局配置能覆盖所有情况。构建目录我坚持叫build并且加进.gitignore。有人喜欢把生成物和源码放一起短期看省事时间一长你自己都分不清哪个文件是手写的哪个是生成的。SysConfig 的产物、CMake 的缓存、编译中间文件统统在构建目录里删掉重来毫无心理负担。源码管理上有个小技巧把.vscode目录也提交进仓库但把里面涉及本机绝对路径的部分改成工作区相对路径或者用${workspaceFolder}变量。这样同事拉下来就能直接用省掉一轮你那边怎么配的的问答。6.2 版本升级时的自保策略TI 的 SDK 更新频率不低但我不建议见到新版就升。升级之前先做三件事把当前能跑的工程完整备份一份包括构建目录之外的配置文件翻一遍新 SDK 的 Release Note重点看编译器版本要求和 API 变更列表在备份工程上做升级验证确认编译通过、烧录正常、功能跑通再动正式代码。我遇到过最难受的一次升级是从 5.x 跨到 7.xTI-RTOS 的配置方式有变化.cfg文件和syscfg的分工调整了原来能编的工程直接报一堆配置错误。后来是照着新 SDK 里同功能例程的配置文件逐个对照改过来的花了大半天。从那之后我养成了一个习惯把每次能跑通的构建命令和版本号写进工程的 README下次出问题翻出来对照能省很多猜测时间。另外工具链的路径尽量用环境变量引用别在 CMake 文件里写死C:/ti/xxx。这样换机器或者换版本的时候只改一处环境变量不用满工程搜替换。我个人是设了TI_SDK_PATH、TI_ARM_CLANG_PATH、SYSCONFIG_TOOL三个变量CMake 里全部通过$ENV{}取迁移成本几乎为零。最后再分享一个我自己常用的组合把cmake --build、dslite.sh烧录、串口日志抓取这三步写成一个 shell 脚本调试的时候一键跑完。省下来的那点手动时间其实不多但能避免忘了重新编译就烧了旧镜像这类低级错误这个价值比省时间大得多。