跳转至

CatST Firmware:Runtime、扫描周期与安全契约

本文档定义 CatST 生成的 UserLogic.c 在 STM32 固件中运行所依赖的最小且可扩展 Runtime 契约。具体硬件驱动可以剪裁,但 CatST 可见入口、变量区语义和安全策略必须保持一致。现场维护不依赖 J-Link,固定 Bootloader 固化后通过串口完成 App 下载和恢复。


1. 固件定位

STM32 固件不解析 CatST,不解释脚本。CatST 在上位机完成检查、仿真、生成 C 和 ARM GCC 编译,设备只运行编译后的 App。

Runtime 需要向 CatST 提供:

IO 映像区
扫描周期调度
UserLogic_Init / UserLogic_Scan 固定入口
定时器、计数器、边沿检测
安全输出层
运行模式
在线变量访问
下载和 App CRC 状态
通信过程映像接口
中断事件映像接口

固件整体分为固定 Bootloader 和可下载 Application。Bootloader 与底层安全边界属于平台能力,不由 CatST 生成或修改。


2. 固定入口

CatST 只生成以下入口:

void UserLogic_Init(void);
void UserLogic_Scan(void);

固件主循环只在 RUN 模式调用 UserLogic_Scan()UserLogic_Init() 在 Runtime 初始化后调用,用于初始化编译器生成的边沿状态、默认变量或版本信息。

生成文件建议:

UserLogic.c
UserLogic.h
UserConfig.h

禁止 CatST 生成:

main()
中断函数
HAL 回调函数
Bootloader 函数
直接 GPIO/UART/Flash/Watchdog 访问

CatST 不生成用户中断函数。所有 EXTI、TIM、UART、CAN、Ethernet、DMA 中断均由 Runtime 固定实现,并通过事件映像或过程映像暴露给 CatST。


3. 扫描周期模型

标准扫描流程:

读取物理输入
输入滤波
复制到 X 和通信输入映像
处理运行模式
RUN 模式执行 UserLogic_Scan()
执行安全策略
刷新 Y/R 和通信输出映像
处理通信、参数、诊断、看门狗

默认目标:

项目 建议
普通扫描周期 1ms~10ms 可配置
默认扫描周期 5ms
输入滤波 按通道配置,默认 10ms
通信处理 不得长期阻塞扫描
快任务 仅允许 CatST-Fast 或固件专用逻辑

微秒级逻辑必须以实测为准。CatST 只能承诺资源受控和可预算,不能承诺任意现场程序都达到 1 us。


4. 运行模式

模式 UserLogic 输出策略 说明
STOP 不执行 输出关闭 上电和下载后默认模式
RUN 执行 先写映像,再经安全层输出 正常运行
ERROR 不执行 输出关闭 严重故障
DOWNLOAD 不执行 输出关闭 下载固件
FACTORY 不执行或受控执行 仅允许测试输出 出厂测试

RUN 前必须检查:

  1. App CRC 有效。
  2. 参数 CRC 有效。
  3. 无严重故障。
  4. 未处于 DOWNLOAD。
  5. 急停未触发。
  6. 输出总使能有效。

5. Runtime API 契约

Runtime 可使用受控数组或 API。无论内部实现如何,生成代码可依赖以下能力。

5.1 IO 访问

bool PLC_GetX(uint8_t index);
bool PLC_GetY(uint8_t index);
void PLC_SetY(uint8_t index, bool value);
bool PLC_GetR(uint8_t index);
void PLC_SetR(uint8_t index, bool value);
bool PLC_GetM(uint16_t index);
void PLC_SetM(uint16_t index, bool value);
int32_t PLC_GetD(uint16_t index);
void PLC_SetD(uint16_t index, int32_t value);

如采用数组,数组必须是 Runtime 受控映像,不是硬件寄存器。

5.2 定时器和计数器

void PLC_TON(Timer_t *timer, bool input, uint32_t preset_ms);
void PLC_TOF(Timer_t *timer, bool input, uint32_t preset_ms);
void PLC_TP(Timer_t *timer, bool input, uint32_t pulse_ms);
void PLC_CTU(Counter_t *counter, bool input, int32_t preset, bool reset);
void PLC_CTD(Counter_t *counter, bool input, int32_t preset, bool reset);
bool PLC_R_TRIG(Edge_t *edge, bool input);
bool PLC_F_TRIG(Edge_t *edge, bool input);

5.3 安全整数 helper

int32_t PLC_DINT_Add(int32_t a, int32_t b);
int32_t PLC_DINT_Sub(int32_t a, int32_t b);
int32_t PLC_DINT_Mul(int32_t a, int32_t b);
int32_t PLC_DINT_Div(int32_t a, int32_t b);
int32_t PLC_LIMIT_DINT(int32_t min, int32_t value, int32_t max);

生成 C 不应直接产生可能触发未定义行为的整数表达式。


6. 安全层

安全层优先级高于 CatST。

强制关闭输出条件:

上电初始化
复位期间
STOP
ERROR
DOWNLOAD
急停输入有效
App CRC 错误
参数严重错误
看门狗复位后的安全确认前
输出总使能无效

即使 CatST 设置:

Y0 := TRUE;

物理输出仍必须经过安全层才能刷新。


7. 通信任务与过程映像

通信任务不得阻塞 UserLogic_Scan()。推荐结构:

串口/CAN/Ethernet 中断或 DMA
协议解析任务
输入过程映像
 ↓ 扫描边界复制
CatST 扫描
输出过程映像
协议发送任务

EtherCAT/CANopen/以太网的协议解析、PDO/SDO、Socket、对象字典维护均属于 Runtime 或通信任务,不属于 CatST 直接执行语句。


8. 中断与事件映像

Runtime 可以使用中断和 DMA,但必须保证 CatST 扫描语义稳定。

推荐模型:

ISR 写入 active buffer
扫描开始复制或交换快照
UserLogic_Scan() 读取 snapshot
扫描结束按策略清除已消费锁存

Runtime 可提供:

L:事件锁存位
HSC:高速计数器
CAP:捕获值
通信输入过程映像

要求:

  1. ISR 内不得执行 CatST 生成逻辑。
  2. ISR 内不得阻塞等待通信。
  3. ISR 与扫描共享数据必须使用双缓冲、原子访问或短临界区。
  4. CatST 在一次扫描内看到的事件数据必须一致。
  5. 输出仍通过安全层刷新,不允许 ISR 绕过安全层写物理输出。

9. 下载与 App 管理

下载与 App 管理是现场无 J-Link 工作流的核心。空白芯片首次固化 Bootloader 属于研发或生产环节;现场只通过串口维护协议下载 Application。

下载流程要求:

上位机发送 STOP
确认输出关闭
ENTER_DOWNLOAD
复位进入 Bootloader
分包写入 app.bin
CRC 校验
标记 App 有效
复位进入 STOP

要求:

  1. 下载前必须 STOP。
  2. 下载前必须确认输出关闭。
  3. 下载中输出保持关闭。
  4. 下载失败不得标记无效 App 为有效。
  5. F407_STANDARD 建议支持 A/B App,F103_LITE 可单 App。
  6. 下载成功后不自动 RUN。
  7. Bootloader 第一版默认不允许现场升级自身。
  8. 必须提供 Bootloader 兜底进入方式,例如上电窗口命令、按键或拨码。

10. Profile 剪裁

固件 Profile 可剪裁:

IO 数量
T/C 数量
M/D 数量
故障记录深度
A/B 分区
通信端口数量
通信过程映像大小
事件锁存和 HSC/CAP 数量
在线监控刷新深度

不得剪裁:

UserLogic_Init / UserLogic_Scan 入口语义
RUN/STOP/ERROR/DOWNLOAD 安全模式
只读变量保护
输出安全层
下载后默认 STOP
CatST 不直接访问硬件的边界