库管理器
DarraRT PLC 提供库管理器统一管理 POU 库的创建 / 打包 / 加密 / 版本 / 依赖。企业级 PLC 代码资产的核心工具, 支持跨项目共享、防泄密、增量升级。
什么是库
库 (Library) 是一组 POU + UDT + 常量 + 资源文件的打包, 可跨项目引用。相比复制粘贴代码, 库的优势:
| 特性 | 复制代码 | 使用库 |
|---|---|---|
| 跨项目共享 | 需人工复制 | 一键引用 |
| Bug 修复 | 每个项目独立修 | 修一次全生效 |
| 版本控制 | 难追踪 | 版本号明确 |
| 代码保护 | 源码可见 | 可加密发布 |
| 依赖管理 | 手动 | 自动 |
| 许可管理 | 无 | License 控制 |
库的类型
按来源分
| 类型 | 说明 | 示例 |
|---|---|---|
| 标准库 | Darra 官方提供 | IEC 61131-3, Safety, Motion |
| 第三方库 | 合作伙伴发布 | ProfiBus 库, OPC UA 客户端 |
| 公司库 | 企业内部共享 | 公司标准动作块 |
| 项目库 | 单项目使用 | 项目专用 FB |
按格式分
| 扩展名 | 内容 | 用途 |
|---|---|---|
.darralib | 源码库 | 开发/调试 |
.darracomp | 已编译库 | 发布/保护 |
.darraenc | 加密库 | 商业授权 |
标准库
Darra 内置以下标准库 (按 IEC 61131-3 / PLCopen):
| 库 | 说明 | 内容 |
|---|---|---|
IEC_61131_3 | IEC 标准 | TON/TOF/TP, CTU/CTD, SR/RS, R_TRIG/F_TRIG |
PLCopen_Motion | 运动控制 | MC_Power, MC_MoveAbsolute, MC_MoveRelative, MC_Home, MC_Stop |
PLCopen_Safety | 安全功能 | SF_* 13 个安全 FB |
Util_String | 字符串处理 | 扩展字符串函数, 格式化, 解析 |
Util_Math | 数学扩展 | 矩阵运算, 向量运算, 滤波器 |
Util_DataLog | 数据日志 | CSV / 数据库 / 环形缓冲 |
Comm_Modbus | Modbus 主从 | Modbus TCP / RTU |
Comm_OPC_UA | OPC UA 客户端 | 浏览, 读写, 订阅 |
Comm_MQTT | MQTT 客户端 | 发布/订阅, QoS, TLS |
Crypto | 加密库 | MD5, SHA256, AES, RSA |
这些库随 IDE 安装, 项目默认引用。
创建库
从现有项目导出
- 选择项目里要发布的 POU / UDT (Ctrl + 多选)
- 右键 → 导出为库
- 填写库信息:
- 库名:
MyCompany_MachineryLib - 版本:
1.0.0(语义化版本) - 作者:
YourCompany - 许可:
Commercial/MIT/GPL - 描述: 详细说明
- 图标: 可选 PNG
- 库名:
- 保存
.darralib文件
从零创建
- 菜单 → 新建 → 库项目
- IDE 打开库编辑器
- 添加 POU / UDT / 常量
- 添加文档 (每个 POU 必须有中文描述)
- 添加 Markdown 说明文件
- 构建 → 生成
.darralib
打包库
源码打包 (.darralib)
完整源码, 适合:
- 公司内部分享
- 开源发布
- 给甲方交付可审查代码
编译打包 (.darracomp)
预编译为中间代码, 源码不可见, 但可被项目引用:
- 库编辑器 → 构建 → 编译为 darracomp
- 选择目标 PLC 架构 (x64 / ARM64)
- 生成
.darracomp
特性:
- 反编译困难 (不是绝对安全)
- 调试信息可选 (发布版去除)
- 体积小 (约源码 30%)
加密打包 (.darraenc)
AES-256 加密, 需要 License 解锁:
- 库编辑器 → 构建 → 加密发布
- 配置:
- 主密钥 (保留在 License 服务器)
- License 类型 (按设备 / 按时间 / 按用户)
- 到期日期
- 最大激活数
- 生成
.darraenc+ License 文件
用户使用需:
- 购买 License
- 通过 License 服务器激活
- IDE 解密加载
版本管理
语义化版本
遵循 SemVer (MAJOR.MINOR.PATCH):
| 版本号变化 | 变更类型 | 示例 |
|---|---|---|
1.0.0 → 2.0.0 | 破坏性 API 变更 | 改了 FB 接口 |
1.0.0 → 1.1.0 | 向后兼容新功能 | 加新 FB |
1.0.0 → 1.0.1 | Bug 修复 | 修 BUG, 接口不变 |
预发布版本:
2.0.0-alpha.12.0.0-beta.32.0.0-rc.12.0.0(正式)
变更日志
每个版本强制填写 CHANGELOG:
## 1.2.0 (2026-04-18)
### 新增
- FB_PID 加入 Anti-Windup 回算法参数 rKt
### 修复
- FB_Motor 在 bReset 边沿错误的问题
- CTU 溢出判定逻辑错误
### 优化
- FB_PID 内部 REAL 改用 LREAL 避免精度丢失
### 破坏性变更 (仅在 MAJOR 版本)
- (无)
IDE 在库更新提示对话框中显示 CHANGELOG。
版本锁定
项目引用库时指定版本:
<LibraryReferences>
<Library name="IEC_61131_3" version="^1.2.0"/> <!-- 兼容 1.2.x 最新 -->
<Library name="Comm_Modbus" version="=1.5.3"/> <!-- 锁定 1.5.3 -->
<Library name="MyCompanyLib" version=">=2.0.0"/> <!-- 至少 2.0.0 -->
<Library name="UnstableLib" version="~1.2.3"/> <!-- 1.2.x 但 >=1.2.3 -->
</LibraryReferences>
多版本共存
同一项目允许不同 POU 使用不同版本的库 (命名空间隔离):
// 使用旧版本
Legacy.FB_Motor fbOldMotor := (Version := '1.0.0');
// 使用新版本
V2.FB_Motor fbNewMotor := (Version := '2.0.0');
适合逐步迁移, 先新代码用新库, 旧代码保持不动。
依赖管理
声明依赖
库发布时声明依赖关系:
<!-- MyLib/manifest.xml -->
<Library name="MyLib" version="1.0.0">
<Dependencies>
<Dependency name="IEC_61131_3" version="^1.0.0"/>
<Dependency name="Util_Math" version="^2.0.0"/>
<Dependency name="Darra_Core" version=">=3.0.0"/>
</Dependencies>
</Library>
依赖解析
引用库时 IDE 自动:
- 读取依赖列表
- 递归下载所有依赖
- 检查版本兼容性 (无冲突)
- 检测循环依赖
- 决定加载顺序
项目引用: MyLib 1.0.0
├── IEC_61131_3 1.2.5 (需要 ^1.0.0 → 满足)
├── Util_Math 2.1.0 (需要 ^2.0.0 → 满足)
└── Darra_Core 3.2.1 (需要 >= 3.0.0 → 满足)
依赖树解析完成, 共引入 4 个库, 无冲突
依赖冲突
不兼容时 IDE 报错:
依赖冲突:
MyLibA 1.0.0 要求 Util_Math ^1.0.0
MyLibB 2.0.0 要求 Util_Math ^2.0.0
无法同时满足
解决方案:
1. 降级 MyLibB 到兼容 Util_Math 1.x 的版本
2. 升级 MyLibA 到兼容 Util_Math 2.x 的版本
3. 使用多版本隔离 (命名空间)
库升级
升级流程
- IDE 检测到库有新版本, 状态栏提示
- 项目树 → 库管理 → 检查更新
- 看 CHANGELOG 确认变更影响
- 决策:
- 自动升级: 补丁版本 (x.x.1 → x.x.2)
- 手动测试后升级: 次版本 (x.1.0 → x.2.0)
- 谨慎迁移: 主版本 (1.x.x → 2.x.x)
- 执行升级, IDE 自动处理依赖
- 编译验证, 修复不兼容
- 提交到版本控制
兼容性检查
升级前 IDE 做兼容性检查:
升级 MyLib 1.0.0 → 2.0.0:
潜在破坏性变更:
✗ FB_Motor.rMaxSpeed 改名为 rMaxVelocity (项目 3 处引用)
✗ FB_Motor.bEnable 移除 (项目 2 处引用)
✓ FB_PID 接口兼容
✓ UDT_MotorStatus 结构兼容
建议: 手动处理 5 处不兼容后再升级
回滚
升级后发现问题, 一键回滚:
- 库管理 → 该库 → 查看历史
- 选择上一版本 → 回滚
- IDE 恢复版本, 项目无需修改
- 提交记录回滚原因
库目录结构
MyCompany_MachineryLib_v1.2.0.darralib
├── manifest.xml 库元数据 + 依赖声明
├── CHANGELOG.md 版本变更日志
├── README.md 库文档
├── LICENSE.txt 许可协议
├── icon.png 库图标 (128x128)
├── src/ 源码 (darralib 格式)
│ ├── pou/
│ │ ├── FB_Cylinder.st
│ │ ├── FB_Motor.st
│ │ └── FB_Conveyor.st
│ ├── udt/
│ │ ├── UDT_Motor.udt
│ │ └── UDT_Sensor.udt
│ └── const/
│ └── Constants.st
├── docs/ Markdown 文档
│ ├── FB_Cylinder.md
│ ├── FB_Motor.md
│ └── ...
├── examples/ 示例项目
│ ├── Example_Cylinder.darraproj
│ └── Example_Motor.darraproj
├── tests/ 自动化测试
│ └── UnitTests.st
└── signatures/ 代码签名 (数字签名)
├── manifest.xml.sig
└── src.sha256
库的自动化测试
库应附带单元测试:
FUNCTION_BLOCK FB_Test_Cylinder
VAR
fbDut : FB_Cylinder; // Device Under Test
iStep : INT := 0;
bTestPass : BOOL;
END_VAR
CASE iStep OF
0: // 初始化测试
fbDut(bReset := TRUE);
iStep := 1;
1: // 测试伸出
fbDut(bExtendCmd := TRUE, bExtendSensor := FALSE, bRetractSensor := TRUE);
IF fbDut.bMoving AND fbDut.bExtendOut THEN
iStep := 2;
END_IF;
2: // 模拟到位
fbDut(bExtendCmd := TRUE, bExtendSensor := TRUE, bRetractSensor := FALSE);
IF fbDut.bAtExtend AND NOT fbDut.bMoving THEN
iStep := 3;
END_IF;
3: // 测试超时
fbDut(bExtendCmd := TRUE, bExtendSensor := FALSE, bRetractSensor := FALSE);
// 等待超时
IF fbDut.bTimeout THEN
iStep := 99;
bTestPass := TRUE;
END_IF;
END_CASE;
END_FUNCTION_BLOCK
发布前必须 100% 通过所有单元测试, CI 检查。
企业私有库仓库
部署库仓库服务器:
https://lib.yourcompany.com/
├── IEC_61131_3_1.2.5.darralib
├── PLCopen_Motion_2.0.1.darralib
├── MyCompany_Conveyor_1.0.0.darralib
├── MyCompany_Welding_2.1.3.darralib
└── ...
IDE 配置:
- 设置 → 库源 → 添加 URL
- 身份验证 (Token / 双因素)
- 访问控制 (按用户 / 按项目)
- 审计日志 (谁下载了哪些库)
与 Git 集成
库代码纳入 Git:
library/MyCompany_MachineryLib/
├── .git/
├── manifest.xml
├── src/
├── docs/
└── tests/
- 分支策略:
main稳定,develop开发,feature/*新功能 - 标签: 每个发布版打 Git Tag (
v1.2.0) - CI: 每次提交自动测试 + 生成
.darralib - CD: Tag 推送自动发布到库仓库
排错表
| 问题 | 原因 | 解决 |
|---|---|---|
| 依赖冲突 | 两个库要求不同版本 | 升降级或多版本隔离 |
| 加密库无法加载 | License 过期 / 未激活 | 联系供应商续期 |
| 库升级后编译错 | 接口破坏性变更 | 看 CHANGELOG 迁移代码 |
| 编译库性能差 | Debug 版本 | 切 Release 版 |
| 库文件损坏 | 下载中断 | 重新下载, 校验 SHA256 |
| 跨架构不兼容 | x64 库用在 ARM64 | 下载对应架构 |
最佳实践
- 优先复用: 新项目先查标准库, 别重新发明轮子
- 严格 SemVer: 版本号准确反映变更性质
- CHANGELOG 必写: 每次发布都要详细记录变更
- 测试覆盖: 单元测试是库质量的底线
- 文档同步更新: 代码变了, 文档也要改
- 锁版本投产: 生产项目锁定具体版本, 不用浮动
- 定期审计: 每季度检查依赖的库是否有安全更新
- 私有库仓库: 企业自建, 掌控发布节奏