runtime分析

110 阅读2分钟
1.taskmanage.cpp

这个程序实现了一个PLC的任务管理功能,主要包含以下几个方面:

  • 任务监控线程task_monitor()

    • 这个线程主要监控任务的运行步骤m_task_step,根据步骤执行不同的操作:
      • 加载变量表、任务表、modbus列表(步骤3)
      • 初始化POU程序(步骤4)
      • 创建线程池执行任务(步骤5)
      • 等待外部指令改变任务(步骤6)
  • PLC任务运行

    • initPlcPous() 初始化所有POU程序
    • reset_plc_pous() 重置所有POU程序变量
    • runTaskOnce() 运行单个POU程序一次
    • createPoolToCommitTasks() 使用线程池运行所有的PLC任务
  • 任务控制

    • 支持自动模式和手动模式
    • setTaskRunningMode() 设置运行模式
    • setTaskCtrlStat() 设置任务控制状态(运行/停止)
  • 任务看门狗

    • 如果使能了看门狗,会为每个任务启动一个看门狗实例,在超时时会通知IDE并终止所有线程。
  • 和IDE的交互

    • 接收来自IDE的外部命令改变任务
    • 定时向IDE报告任务运行状态
    • 收到改变变量的值指令后改变PLC变量
    • 主要通过commuManage类实现和IDE之间的交互。
  • 此外还包含任务优先级设置、强制写入变量、线程取消点设置等功能。

  • get_and_report_SFCStepstatus方法: 这是获取SFC程序运行步骤状态并上报给IDE的函数

    • 检查是否可以访问原内存,如果不可以直接返回。
    • 从var_end_addr位置读取SFC程序步数nb_steps、动作数nb_actions、转移条件数nb_transitions。
    • 计算步骤、动作、转移条件在内存中的地址位置。
    • 遍历步骤、动作、转移条件,读取它们的布尔状态值。
    • 将读取到的状态值存储到Json对象中。
    • 使用Json::FastWriter生成格式化的Json字符串。
    • 记录当前时间戳。
    • 使用commuManage::statusFreshUp_函数将Json字符串实时上报给IDE。
    • statusFreshUp_函数会使用指定的上报码_SFC和级别_REALTIME_AND_NECES_UNSHIELD上报。
  • var_end_addr: SFC程序中最后一个变量的地址,它的计算方法如下:

    • 先从任务表获取所有的SFC类型任务
    • 对每个SFC任务,找到其对应的变量表
    • 在变量表中,定位最后一个变量last_var
    • 根据last_var的变量类型,查询变量长度映射表,获取其占用的长度size
    • 然后var_end_addr = last_var.v_addr + size
    • 举个例子:
      • 假设最后一个变量last_var的信息如下:
      • 名称:var_end
      • 类型:INT
      • 地址:0x2000
      • 根据变量类型INT查询变量长度映射表,INT的长度为2字节
      • var_end_addr = 0x2000 + 2 = 0x2002
      • 这样就通过最后一个变量的地址,加上其长度,得到了该SFC任务内存区域的结束地址。