Codesys中使用CAA_File实现变量日志记录的问题排查
问题:CODESYS中CAA File库文件操作失败及高性能变量记录方案
需求
- 在主PRG及子FB运行期间,持续将变量记录到文本/CSV文件,且不影响任务性能
- 已尝试方案:
- OSCAT Network:库加载失败
- CmpLog:速度慢且不生成外部文件
- 选用CAA File库(参考Codesys Forge帖子)
测试环境
- CODESYS V3.5 SP20+
- 目标设备:CODESYS_Control_for_Raspberry_Pi_MC_SL v4.11.0.0
- 当前测试:Windows仿真模式,最终部署到树莓派
- CAA File版本:3.5.19.0
- 任务配置:单任务优先级1,周期4ms,仅运行单个PRG
- 项目路径:
C:\Users\___\Documents
当前测试代码
PROGRAM PLC_PRG VAR xFileStdInit: BOOL:=FALSE; uiFileStdState: UINT:=0; sFileName: FILE.CAA.FILENAME:= 'TestFile.txt'; hFile: FILE.CAA.HANDLE; sFileTestString: STRING:='Hello caa library user'; sFileString: STRING:=''; szFileSize1: FILE.CAA.SIZE := 0; szFileSize2: FILE.CAA.SIZE := 0; filop: FILE.Open; filwr: FILE.Write; filrd: FILE.Read; filcl: FILE.Close; END_VAR IF NOT xFileStdInit THEN filop(xExecute:=FALSE); filcl(xExecute:=FALSE); filwr(xExecute:=FALSE); filrd(xExecute:=FALSE); xFileStdInit:=TRUE; uiFileStdState:=0; ELSE CASE uiFileStdState OF 0: (* create a new file *) filop.sFileName:=sFileName; filop.eFileMode:=FILE.MODE.MRDWR; filop.xExclusive:=TRUE; filop( xExecute:=TRUE); IF filop.xDone THEN hFile:=filop.hFile; uiFileStdState:=1; END_IF IF filop.xError THEN (* error handling*) ; END_IF 1:(* write text in the file *) filwr.hFile:=hFile; filwr.pBuffer:=ADR(sFileTestString); szFileSize1:=SIZEOF(sFileTestString); filwr.szSize:=szFileSize1; filwr.udiTimeOut:=100000; (* 100ms Timeout *) filwr( xExecute:=TRUE); IF filwr.xDone THEN uiFileStdState:=2; END_IF IF filwr.xError THEN (* error handling*) ; END_IF 2:(* read file - TestFile.txt*) filrd.hFile:=hFile; filrd.udiTimeOut:=100000; (* 100ms Timeout *) filrd.pBuffer:=ADR(sFileString); filrd.szBuffer:=255; filrd( xExecute:=TRUE); IF filrd.xDone THEN szFileSize2:=filrd.szSize; IF szFileSize2 = szFileSize1 THEN uiFileStdState:=3; ELSE (* error handling*) ; END_IF END_IF IF filrd.xError THEN (* error handling*) ; END_IF 3: (* close file - TestFile.txt *) filcl.hFile:=hFile; filcl( xExecute:=TRUE); IF filcl.xDone THEN uiFileStdState:=4; END_IF IF filcl.xError THEN (* error handling*) ; END_IF 4: (* end of example *) ; END_CASE END_IF
当前问题
Windows仿真运行时,uiFileStdState初始为0,filop.xExecute设为TRUE但filop.xDone始终为False,filop.eError显示为ASM_CREATEJOB_FAILED,尝试使用绝对路径未解决问题。
排查方案与替代方案
一、CAA File库问题排查
库兼容性检查
- 确认CAA File库v3.5.19.0与CODESYS V3.5 SP20+的兼容性,尝试升级CAA File到匹配SP20的版本(如v3.5.20.0)
- 仿真模式下,确保已正确添加CAA File库到项目,且库的目标平台包含Windows仿真
权限与路径修正
- 仿真模式下,文件默认路径为CODESYS仿真进程的工作目录,而非项目路径。尝试使用有读写权限的绝对路径,例如:
'C:\Temp\TestFile.txt'(CODESYS支持/作为路径分隔符) - 检查Windows Defender或杀毒软件是否拦截了CODESYS仿真进程的文件操作
- 仿真模式下,文件默认路径为CODESYS仿真进程的工作目录,而非项目路径。尝试使用有读写权限的绝对路径,例如:
FB调用逻辑优化
- CAA File的
OpenFB需要持续调用直到xDone或xError,当前代码的触发逻辑存在缺陷,修改状态0的逻辑如下:0: (* create a new file *) IF NOT filop.xBusy THEN filop.sFileName:=sFileName; filop.eFileMode:=FILE.MODE.MRDWR; filop.xExclusive:=TRUE; filop( xExecute:=TRUE); ELSE filop( xExecute:=FALSE); (* 保持调用直到完成 *) END_IF IF filop.xDone THEN hFile:=filop.hFile; uiFileStdState:=1; filop(xExecute:=FALSE); (* 重置FB *) END_IF IF filop.xError THEN (* 记录错误码,添加重试次数限制后重试 *) uiFileStdState:=0; END_IF
- CAA File的
错误码深度排查
ASM_CREATEJOB_FAILED通常表示底层任务创建失败,通过CODESYS的「工具 -> 诊断日志」查看更详细的错误信息- 检查仿真任务的资源分配,确保有足够的内存和线程资源用于文件操作任务
二、高性能变量记录替代方案
如果CAA File问题无法快速解决,可考虑以下方案:
后台任务异步记录
- 创建低优先级后台任务(周期如100ms/1s),主任务仅将需要记录的变量存入环形缓冲区,后台任务从缓冲区读取并批量写入文件,实现主任务与文件操作解耦,避免占用4ms周期任务的资源
CODESYS自带日志功能
- 在设备配置中添加
Log组件,配置日志文件路径为CSV格式,直接记录变量,性能开销低,无需自定义代码
- 在设备配置中添加
基于SysFile库的自定义异步写入FB
- 利用CODESYS基础
SysFile库封装异步写入FB,通过状态机和定时器实现非阻塞写入,每次写入固定大小的数据块,避免长时间占用CPU
- 利用CODESYS基础
内容的提问来源于stack exchange,提问作者PoGaMi
相关产品推荐
相关产品推荐

