剑池CDK组件化SDK搭建与Flash算法开发指南

发布时间:2026/10/29 4:12:23
剑池CDK组件化SDK搭建与Flash算法开发指南 简介《阿里平头哥剑池CDK快速上手指南》是一份面向物联网与嵌入式开发者的PDF手册重点服务使用平头哥C-SKY、RISC-V架构芯片并希望快速掌握剑池CDK集成开发环境的人群。内容围绕“1天上手、5天出原型、20天出产品”的1520理念展开帮助读者理解CDK的Packages、Editor、Debugger、Analyzer四大模块及端云一体开发方式并系统讲解组件化SDK工程的创建、链接脚本调整、Flash算法文件实现与配置、开发板与芯片组件更新、solution工程调试以及SDK离线/在线发布流程。资源包仅含1个PDF文件大小约3.18MB单文件结构便于按章节查阅目录从工具介绍、初始工程搭建到SDK发布与常见问题解答层层递进适合作为自定义平台SDK制作时的随查手册。已有1028人学习对需要缩短物联网产品开发周期的初中级嵌入式开发者具有参考价值。1. 剑池 CDK 到底解决什么把散装 SDK 拆成能复用的组件手里拿到一块新的 RISC-V 物联网开发板翻出来的 SDK 又是一堆散落的 .c 和 .h 文件换个芯片型号就得重新拷一遍、改一通宏定义这种麻烦做嵌入式的基本都碰过。剑池 CDK 走的是另一条路把整套东西拆成 solution、SDK、chip、board、common 几类组件工程文件里只存依赖关系源码按组件归位换平台时改的是组件而不是满工程 grep 找路径。它同时支持 C-SKY 与 RISC-V 两套指令集编辑器、调试器、分析器挂在同一个图形界面里还能直接从芯片开放平台拉取网络组件、协议栈和外设驱动省掉不少攒轮子的时间。下面这套流程适合两类人刚接触这套工具、想知道工程骨架怎么搭的新手和已经能跑通 demo、但要给团队交付一份可复用 SDK 的老手。2. 组件化 SDK 工程怎么搭从 New SOC Project 到链接脚本对齐2.1 四块功能划分决定了你后面会卡在哪一步剑池 CDK 把功能拆成 Packages、Editor、Debugger、Analyzer 四块这个划分不是说明书里的噱头它直接对应你做 SDK 时会卡住的位置。Packages 是组件化模块也是整件事的骨架。solution、SDK、chip、board 这几类组件都以 package 的形式存在工程文件里只记依赖源码落在新建工程时指定的 Package Path 目录下。Editor 是图形化的代码编辑入口但它同时承担了组件配置窗口、编译选项、链接脚本图形编辑这些关键入口很多人以为自己只用它写代码实际上后面调 LD、配算法文件全在这里点。Debugger 负责图形化调试Flash 算法工程那一整套调试逻辑也走它这也是第 3 章要单独起一个工程的原因。Analyzer 偏性能与体积分析工程定稿之后再回头看更划算。我一般的顺序是先把 Packages 这条线走通再碰其它三块。原因是组件路径和依赖一旦填错编辑器里能打开、编译器也可能过但烧写和调试阶段会冒出一堆看起来毫不相关的怪问题排查成本极高。还有一层值得提前知道这套工具与芯片开放平台的组件超市是打通的蓝牙、语音、网络类组件可以直接拉。这意味着你做的 SDK 如果按组件规范拆好别人导入之后还能继续复用平台上的组件而不是把一坨源码拷来拷去。端云一体这个词听起来虚落到操作上就是“组件来源可以是本地目录也可以是平台”。2.2 建骨架Solution Package 类型与 Package Path菜单 Project - New SOC Project 打开新建窗口填工程名Project Type 选 Solution Package再指定 Package Path。这两个参数最容易被随手填错参数该填什么填错的后果Project TypeSolution Package选成其它类型工程视图里不会自动生成 sdk 与 chip 组件后面要手工补依赖Package Path组件源码要落盘的目录路径带中文、空格或过长编译阶段不一定报错链接时找不到头文件和库工程名与 solution 业务相关的短名与已有工程重名组件目录会被覆盖建完之后工程视图是三层结构理解这三层比记住按钮位置重要得多my_solutionsolution 工程本体含 main 文件以及可配置的调试初始化脚本和 Flash 初始化脚本。__SDK_CK802sdk 类型组件依赖一个 chip 组件源码保存在 Package Path 指定的目录。__Chip_CK802chip 类型组件包含 CPU 的初始化启动代码和链接脚本文件同样落在 Package Path。可以把它们理解成三层责任solution 管应用和配置sdk 管平台无关的封装chip 贴着硅。后面换板子动的主要是 chip 和 boardsolution 里的业务代码基本不动这才是组件化真正省钱的地方。很多人第一次用会把业务代码直接塞进 solution 根目录结果换芯片时又要全量搬一遍等于白拆。建完骨架后先别急着写代码做一次空跑验证什么都不改直接编译整个 solution。能过说明组件依赖和路径是对的过不了先把依赖关系理清楚别往里面塞业务代码否则后面分不清是环境问题还是代码问题。2.3 链接脚本五个符号不能随手改默认的 LD 文件CDK 提供了图形化文本修改方式存储布局在两段 Flash、两段 RAM 以内直接改图形配置就够了。超过这个复杂度比如 Flash 分了三段、RAM 有多个不连续区间就得按 GCC 的语法手写 LD。手写之前先认清楚默认文件里这五个符号符号作用__s_ram_data_1程序数据区起始位置__e_ram_data_1程序数据区结束位置__s_ram_bss_1BSS 区起始位置__e_ram_bss_1BSS 区结束位置__e_rom程序只读数据区之后 4 字节对齐的位置这五个符号在 chip 组件的 src/ck802.c 里被直接引用用来完成 C 运行时初始化里的数据段搬运和 BSS 清零。改 LD 时把它们删掉、改名或者让它们指向的区间互相重叠编译和链接都不会报错但程序跑起来会随机崩。这类问题的血泪之处在于崩的位置和根因隔着好几层你会一直怀疑业务代码。下面是一段 MEMORY 段对齐的写法示例地址和长度按自己板子的实际参数改/* 存储区间声明ORIGIN / LENGTH 必须与板子实际可用空间一致 */ MEMORY { ROM (rx) : ORIGIN 0x00000000, LENGTH 512K RAM (rwx) : ORIGIN 0x20000000, LENGTH 96K } SECTIONS { .text : { *(.text*) *(.rodata*) . ALIGN(4); __e_rom .; /* 只读区之后 4 字节对齐点ck802.c 要用到 */ } ROM .data : { __s_ram_data_1 .; /* 数据区起点启动代码从这里开始搬 */ *(.data*) __e_ram_data_1 .; /* 数据区终点决定搬运长度 */ } RAM AT ROM .bss : { __s_ram_bss_1 .; /* BSS 起点 */ *(.bss*) *(COMMON) __e_ram_bss_1 .; /* BSS 终点启动代码按这个长度清零 */ } RAM }逻辑说明.data用AT ROM把初值放在 ROM 里运行时由启动代码搬到 RAM__s_ram_data_1与__e_ram_data_1之间就是搬运区间的边界两者一错全局变量的初值全是随机数。__e_rom强调 4 字节对齐是因为紧随其后的可能是按字访问的表结构或跳转表不对齐会直接触发总线异常。参数说明LENGTH 要比芯片手册标称的可用空间略小一点给栈和调试期临时缓冲留余量两段 RAM 的板子再开一个 RAM2 区域并写对应的 RAM2但别把 BSS 拆到两段上启动代码不会替你处理这种布局。改完 LD 一定要回到图形配置里核对一遍图形视图和文本视图不一致时以最终参与编译的那份为准。2.4 建自己的平台组件Create a new SDK 与 Create a new package右键 my_solution 节点选 Create a new SDK填自己的 SDK 名基础组件选 __SDK_CK802然后右键工程视图里的 SDK 组件选 Create a new package填芯片组件名比如 SmartL_Chip基础组件同样选 __SDK_CK802。这两步的本质是“复制一份默认组件当模板再改内容”。保留模板的好处是启动文件、链接脚本、编译选项的位置都是对的坏处是残留的默认配置很容易被忽略比如 chip 组件里的宏开关还指着默认型号编译能过跑起来外设全无响应。我一般建完组件后立刻做三件事把组件配置窗口里的宏定义逐条过一遍、把 LD 文件里的地址区间换成板子的实际值、把启动文件里的时钟初始化改掉。三件事做完再编译能省掉后面大量的“明明编译过了却不工作”。组件创建完成后工程视图里的节点是可以直接拖动和重命名之外的拖拽复用的但依赖关系不要随便改。sdk 依赖 chipsolution 依赖 sdk这个方向反了CDK 在链接阶段会给出很难读的错误。3. Flash 算法文件怎么写FlashDev.c 描述器件、Driver.c 实现接口、main.c 做调试闭环3.1 为什么烧写要单独起一个 Flash 工程CDK 支持 Flash 烧写但不同厂家的 Flash 器件编程时序、命令字、扇区划分都不一样工具不可能内置所有型号。它的做法是允许开发者提供一个 Flash 算法文件最终产物是 .elf烧写时 CDK 把这个算法下载到芯片 RAM 里跑起来再通过全局变量给算法下命令由算法自己去操作 Flash 控制器。这个机制决定了两件事一是算法工程和业务 SDK 是两个独立工程CPU 型号必须完全一致否则下载进去跑飞二是算法工程里不能依赖业务 SDK 的任何代码它得足够小、足够独立能在 RAM 里跑完。新建入口同样是 New SOC ProjectProject Type 选 FlashRAM1 里填板子的 RAM 区域CPU 与目标 SDK 的 CPU 必须一模一样。建完之后工程里有三个文件承担不同职责FlashDev.c 描述器件、Driver.c 实现接口、main.c 做主控逻辑。3.2 FlashDev.c把器件参数填对FlashDev.c 里是一个固定结构的描述体字段顺序不能调CDK 按这个结构解析/* 器件基本信息字段顺序与含义固定不要自行增删 */ struct FlashDevice const FlashDevicesINDEVSECTION { 6, // 保留的版本描述不要改 SmartL_Flash, // 算法名工程配置里显示的就是它 ck802, // CPU 名全小写必须与 SDK 的 CPU 一致 0x123456, // Flash ID NorFlash, // 器件类型 512 * 1024, // 保留字段按默认填 1, // 是否可直接访问1 表示可在 Flash 上直接取指 1, // RangeNumbers下面地址表的条目数 { {0x0, 0x80000, 0x200} // {起始地址, 容量, 扇区大小} } };参数说明第三个字段 CPU 名必须全小写写成 CK802 或 C-SKY 都会导致算法加载失败最后一个结构里的扇区大小 0x200 必须和 Driver.c 中 flashErase 的实现对齐两处不一致的典型现象是“擦除返回成功但数据没变”。如果板子上挂了两片 Flash把 RangeNumbers 改成 2 并补一行地址范围擦除接口会按传入地址自动落到对应区域不需要在驱动里再写分支。3.3 Driver.c八个接口的语义与返回值Driver.c 是真正干活的地方要按硬件实现下面这些接口接口语义返回flashInit编程开始前的初始化运行 Flash 程序时最先执行0 成功非 0 失败flashUnInit编程结束后的收尾CDK 在操作完成后默认调用0 成功flashID读取器件 ID通过参数带回0 成功flashProgram向目标地址写数据0 成功flashRead读取数据非直读型 Flash 才会被调用0 成功flashErase擦除指定空间地址按 PageSize 对齐、长度为 PageSize 的整数倍0 成功flashChipErase整片擦除0 成功flashChecksum烧写镜像的快速校验与镜像里的 checksum 比对0 成功实现时有几个容易写错的地方值得提前说清楚。flashErase 的地址参数一定是对齐过的但很多人会在里面再做一次“向下对齐”结果擦掉了不该擦的区域正确做法是直接信任 CDK 传进来的地址只在内部做范围校验。flashProgram 不要假设一次写入的长度是页大小的整数倍末尾不满一页的部分要么用缓冲补齐要么拆成单字节写具体取决于器件手册。flashChecksum 如果不实现返回 0 也能跑通但校验环节就形同虚设量产阶段出问题会很难定位。还有一个细节这些接口的返回值不是给业务代码看的是给 CDK 判断流程用的。返回非 0 时 CDK 会中止烧写并报错所以哪怕只是参数越界也老老实实返回错误码别为了“让它跑完”强行返回 0。3.4 调试闭环-O0 编译、Watch 改变量、把 PC 拉到 lr算法工程写完不能直接拿去烧得先在 RAM 里把它调通。整套调试手法有个固定套路第一次用会觉得别扭用两次就顺了。第一步右击算法工程打开 Compiler 配置把 Optimization 改成 -O0重新编译。这一步是为了让单步调试和变量观察不被优化打乱-O2 下很多局部变量会被优化掉Watch 窗口里看不到值。第二步双击工程视图里的算法工程节点设为 active project点调试按钮启动。程序跑到 main 函数后全速运行会停在__bkpt_label()这一行。这个函数就是软断点CDK 把算法下载到 RAM 之后停在这里等你下发命令。第三步在 Watch 窗口里设置全局变量验证某个接口。以 flashProgram 为例把 g_func 设为 1g_dstAddress 设为要编程的 Flash 地址g_length 设为数据长度g_rwBuffer 里填上特征数据。调试时不要拿几 KB 去试十几个字节足够验证时序和地址映射数据量大了反而容易掩盖边界问题。第四步把 PC 的值设成当前 lr 的值然后单步运行。这一步是从断点函数返回到 main 的命令分发处PC 不拉回来你会一直卡在__bkpt_label里出不去这是第一次用最容易卡住的地方。第五步单步进入 flashProgram跑完整个函数再回到 Watch 窗口核对目标地址的数据。按同样的方式依次验证 flashID、flashRead、flashErase、flashChipErase、flashChecksum每个接口单独过一遍。全部通过之后把 Compiler 选项从 -O0 改回 -O2 重新编译产物才是能进 SDK 的版本。3.5 算法文件挂进 SDK两种路径调通之后把算法工程根目录下 Obj/ 里生成的 SmartL_Flash.elf 拷到 SDK 工程这边挂载方式分两种情况情况 1SDK 使用了芯片组件正常路径。把 .elf 拷到 SmartL_Chip 组件目录右键组件节点选 Open Containing Folder 可以直接打开目录然后在组件配置窗口里把 SmartL_Flash.elf 设为算法文件。情况 2没有使用芯片组件或者用的是旧版本组件。把 .elf 拷到 my_solution 工程根路径下与 .ckdproj 文件同目录然后在工程配置的 Flash 标签页里选择这个算法文件。两种路径的区别在于配置生效的范围前者跟着组件走组件被别人复用时算法一起被带走后者只对当前工程生效。给团队交付 SDK 一定要走情况 1否则别人导入你的工程后烧写配置是空的还得再来问你一遍。4. 把初始工程改造成平台 SDK开发板组件、芯片组件与 common 组件的收口4.1 开发板组件用 Add Source Folder 导入已有代码骨架建好之后my_solution 里还是默认的模板内容接下来要把它换成 SmartL 平台的真实代码。第一步是在 SDK 组件节点下新增一个开发板组件 SmartL_Board然后右键该节点选 Add Source Folder选中已有的代码目录确认导入。这一步导入的是目录引用关系不是文件拷贝所以原目录后续被删掉或移动工程立刻红叉。我一般会先把要导入的目录整理成一个固定的板级目录结构再执行导入避免导到一半发现目录里混着别的平台的代码。导入之后必须配编译选项在 Compiler 的 Global Config 里配置开发板组件要暴露给外部的头文件搜索路径然后 Debug Level 也要选带调试信息的选项。头文件路径这一项漏配的典型现象是“组件自己能编译依赖它的 solution 报找不到 xxx.h”。Debug Level 不配调试时变量看不到值、断点位置漂移排查起来很浪费时间。4.2 芯片组件更新启动代码与链接脚本要一起改芯片组件是贴着硅的那层换平台时改动最集中。需要同步的有三块内容内容改什么漏改的后果启动代码时钟、看门狗、中断向量表、栈顶地址上电就跑飞或反复复位链接脚本MEMORY 区间与 2.3 节提到的那五个符号全局变量初值丢失、BSS 清零越界编译宏芯片型号、外设开关、Flash 容量编译能过运行时外设无响应或越界访问这三块里最容易被单独改掉的是链接脚本——因为启动代码改完能跑大家就以为完事了结果换个优化等级或者加个全局数组就崩。我的习惯是把启动文件和 LD 文件放在同一个组件里、同一次提交里改并且在组件说明里写清楚两者的对应关系后面接手的人不至于只改一半。4.3 common 组件把硬件无关的那部分单独拎出来平台代码里总有一批与硬件无关的东西环形缓冲区、协议解析、状态机、日志格式化。这些东西放在开发板组件里不会报错但会让组件职责变糊别人复用时得连板子一起搬。正确做法是新增两个硬件无关的 common 组件把这类代码挪进去然后让 solution 同时依赖 sdk、board 和 common。拆分时注意依赖方向common 不能反向依赖 board否则组件图里会出现环CDK 解析依赖时直接失败。拆完之后的好处很直接换一块新板子common 原样复用你只需要重新做 chip 和 board工作量从“重写一遍”降到“改配置”。4.4 solution 收口调试配置与 Flash 配置一起验前面几步做完solution 工程要做最后的收口。调试初始化脚本要指向新板子的 RAM 初始化流程Flash 初始化脚本要和第 3 章做的算法文件对应上然后在工程配置里检查编译产物路径、算法文件路径、调试器型号这三项。验证顺序建议固定下来先编译再下载到 RAM 调试最后烧到 Flash 冷启动。跳过中间那步直接烧 Flash一旦启动代码有问题你会分不清是算法的问题还是代码的问题。冷启动通过之后把 solution 完整编译一遍并记录产物大小这个数字是后面发布 SDK 时的基线涨得离谱就说明有组件被重复链接了。5. 避坑排查链接脚本、算法文件、组件路径上的五个翻车点5.1 编译链接都过一上电就随机崩现象工程编译零告警下载到 RAM 调试也正常烧到 Flash 冷启动后跑几秒就崩崩的位置每次都不一样。原因链接脚本里的__e_rom、__s_ram_bss_1这类符号被改过名字或者指向的区间重叠启动代码按错误的长度搬运数据段、按错误的边界清 BSS把不该清的 RAM 清了。这类错误编译期发现不了因为符号本身是合法的。解决把默认 LD 文件里的五个保留符号原样保留只改它们所在的地址区间不改名字、不改相对顺序。改完用调试器在启动代码前后各打一个断点核对 RAM 里的数据段内容与 ROM 中的初值是否一致不一致就说明搬运长度算错了。5.2 擦除返回成功但写进去的数据读出来是旧值现象flashErase 返回 0flashProgram 也返回 0但 flashRead 读回来的还是上一次的数据。原因FlashDev.c 里描述的扇区大小与 Driver.c 中 flashErase 实际操作的扇区大小不一致。CDK 按描述体里的 PageSize 对齐地址传给你驱动内部又按自己的页大小二次对齐两次对齐叠加实际擦掉的是另一块区域。解决把 FlashDev.c 最后一个结构里的扇区大小与驱动里的页大小宏统一成同一个值最好只在一处定义、另一处引用。改完用 3.4 节的方法单独验证一次 flashErase擦之前先读一遍擦之后再读一遍两次数值必须不同。5.3 换台电脑打开工程组件节点全是红叉现象在自己机器上好好的工程拷给同事或者换台机器打开组件节点全部红叉编译报找不到源文件。原因Package Path 用的是绝对路径或者组件导入时用的是目录引用而不是相对路径。换机器后路径不存在组件自然找不到。解决新建工程时 Package Path 尽量选在工程目录内或者用相对路径导入已有代码目录时确认是相对引用。已经出问题的工程可以在组件配置窗口里重新指定路径重新指定后记得清理一次编译产物再全量编译否则旧的中间文件会继续生效。5.4 算法工程 -O0 调通了改 -O2 之后烧写失败现象-O0 下每个接口都验证通过改成 -O2 重新编译、挂进 SDK 后烧写报错或者烧写成功但校验失败。原因-O2 下编译器会重排或消除部分全局变量访问如果 main 里的全局变量没有加 volatile 或者被优化进了寄存器CDK 在外部修改这些变量后算法读不到新值。解决把 g_func、g_dstAddress、g_length、g_checksum、g_rwBuffer 这几个被外部修改的全局变量加上 volatile 修饰并把命令分发逻辑放在一个不会被优化掉的循环里。改完用 -O2 重新跑一遍 3.4 节的调试流程确认每个接口在优化后依然能正确响应。5.5 发布出去的 SDK别人导入后头文件找不到现象自己工程里一切正常把 SDK 发布给同事对方导入后编译报找不到头文件或者链接时报未定义符号。原因组件的 Global Config 里配的头文件搜索路径是本地绝对路径或者发布时漏掉了某些组件目录依赖关系在对方机器上解析不到。解决发布前把所有组件的头文件路径改成相对组件目录的写法导出一份完整组件清单逐条核对依赖。接收方导入后先做一次空编译编译不过就是路径问题别急着往下调业务。这个检查我一般会做成一个固定动作每次发布都走一遍。6. 进阶SDK 的离线与在线发布以及交付前的验收清单SDK 做完只是自己能用要给别人用还得走发布。CDK 支持两种方式离线发布是把整个 solution 连同依赖组件打包成一个可分发的工程包对方解压后直接导入在线发布是把组件推到芯片开放平台上别人通过组件超市拉取。两种方式的选择标准很简单只给内部几个人用、或者网络环境受限走离线要给不特定开发者复用、希望跟着平台版本走走在线。在线发布前组件的元信息要补齐组件名、版本号、依赖列表、支持的芯片型号、暴露的头文件路径。这几项漏一个别人拉下来就得手工改配置。版本号建议按语义化规则来接口不兼容的改动必须升主版本否则老工程拉新组件会编译不过。交付前我会固定走一遍下面这张表任何一项没过就不发检查项通过标准空工程编译新建 solution 只依赖发布的组件能零告警编译通过RAM 调试下载到 RAM 能跑断点命中正常变量可观察Flash 冷启动断电重启后能正常启动不依赖调试器算法文件烧写、读取、擦除、校验四项全部通过组件路径全部为相对路径换机器打开无红叉代码体积与上一版本对比无明显异常增长真正让我养成这套习惯的是一次很尴尬的交付SDK 在自己机器上验证得挺顺打包发出去之后对方导入编译不过查了半天是某个组件的头文件路径写成了本地绝对路径。从那以后我每次发布前都强制走一遍上面的清单尤其是“换台机器空工程编译”这一项它能把路径类问题一次性暴露干净。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询