@ -0,0 +1,742 @@
# include "myBase.h"
# include "mySystem.h"
# include "myDatacenter.h"
# include "myLog.h"
# include "myCmd.h"
# include "myFunc.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <locale.h> // ANSI编码支持
# include <unistd.h> // usleep函数实现延时
# define MAX_OUT_NODES 20 // 最大输出节点数
LOCAL uint8_t g_plc_st_out [ MAX_OUT_NODES ] = { 0 } ;
LOCAL uint32_t * gp_run_cnt_in = NULL ;
LOCAL uint8_t * gp_st [ 10 ] = { NULL } ;
typedef struct
{
stru_self_ptl_cfg_base base ;
uint8_t * p_data ;
} stru_plc_cfg ;
stru_self_ptl_cfg * p_plc_cfg = nullptr ;
std : : vector < stru_plc_cfg > g_plc_cfg = { } ;
// ==================== 常量定义 ====================
# define MAX_LOGIC_GRAPHS 4 // 最大逻辑图数量
# define MAX_NODES_PER_GRAPH 20 // 每个逻辑图最大节点数
# define MAX_LINKS_PER_GRAPH 20 // 每个逻辑图最大链路数
// 节点类型标识
# define NODE_TYPE_HW_OUTPUT 0 // 硬件输出点( dev_in)
# define NODE_TYPE_HW_INPUT 1 // 硬件输入点( dev_out)
# define NODE_TYPE_OR_GATE 2 // 或门元件
# define NODE_TYPE_AND_GATE 3 // 与门元件
# define NODE_TYPE_NOT_GATE 4 // 非门元件
# define NODE_TYPE_62P_GATE 5 // 62p延时元件( 输入1延时输出1, 输入0立即输出0)
# define NODE_TYPE_62D_GATE 6 // 62d延时元件( 输入1立即输出1, 输入0延时输出0)
# define NODE_TYPE_RISING_EDGE 7 // 上升沿元件( 0→1脉冲)
# define NODE_TYPE_SR_LATCH 8 // SR触发器( S优先)
# define NODE_TYPE_RS_LATCH 9 // RS触发器( R优先)
# define NODE_TYPE_FALLING_EDGE 10 // 下降沿元件( 1→0脉冲)
// ==================== 动态链表结构(硬件点) ====================
typedef struct HWPoint {
int id ;
int value ;
struct HWPoint * next ;
} HWPoint ;
typedef struct {
HWPoint * input_head ;
HWPoint * output_head ;
int input_count ;
int output_count ;
} HardwareManager ;
// ==================== 逻辑图数据结构 ====================
typedef struct {
int type ;
int id ;
int x ;
int y ;
int value ;
int last_input ;
} LogicNode ;
typedef struct {
int src_type ;
int src_id ;
int dest_type ;
int dest_id ;
} LogicLink ;
typedef struct {
char key [ 20 ] ;
char name [ 50 ] ;
LogicNode nodes [ MAX_NODES_PER_GRAPH ] ;
int node_count ;
LogicLink links [ MAX_LINKS_PER_GRAPH ] ;
int link_count ;
} LogicGraph ;
// ==================== 硬件点操作函数 ====================
static HWPoint * create_hw_point ( int id , int value ) {
HWPoint * point = ( HWPoint * ) malloc ( sizeof ( HWPoint ) ) ;
if ( point ) {
point - > id = id ;
point - > value = value ;
point - > next = NULL ;
}
return point ;
}
static void destroy_hw_list ( HWPoint * head ) {
HWPoint * tmp ;
while ( head ) {
tmp = head ;
head = head - > next ;
free ( tmp ) ;
}
}
static void init_hardware_manager ( HardwareManager * hw ) {
memset ( hw , 0 , sizeof ( HardwareManager ) ) ;
}
static void destroy_hardware_manager ( HardwareManager * hw ) {
destroy_hw_list ( hw - > input_head ) ;
destroy_hw_list ( hw - > output_head ) ;
memset ( hw , 0 , sizeof ( HardwareManager ) ) ;
}
static int get_hw_point_value ( HWPoint * head , int id ) {
HWPoint * curr = head ;
while ( curr ) {
if ( curr - > id = = id ) return curr - > value ;
curr = curr - > next ;
}
return 0 ;
}
static int set_hw_point_value ( HWPoint * * head , int * count , int id , int value ) {
HWPoint * curr = * head ;
while ( curr ) {
if ( curr - > id = = id ) {
curr - > value = value ;
return 0 ;
}
curr = curr - > next ;
}
HWPoint * new_point = create_hw_point ( id , value ) ;
if ( ! new_point ) {
fprintf ( stderr , " 内存分配失败: 无法创建硬件点ID=%d \n " , id ) ;
return - 1 ;
}
new_point - > next = * head ;
* head = new_point ;
( * count ) + + ;
return 0 ;
}
// 从逻辑图中提取所有硬件点到管理器
static void extract_hw_points_from_graphs ( LogicGraph graphs [ ] , int graph_count ,
HardwareManager * hw , int default_input_value ) {
stru_plc_cfg * p = nullptr ;
for ( int g = 0 ; g < graph_count ; g + + ) {
LogicGraph * graph = & graphs [ g ] ;
for ( int n = 0 ; n < graph - > node_count ; n + + ) {
LogicNode * node = & graph - > nodes [ n ] ;
if ( node - > type = = NODE_TYPE_HW_INPUT ) {
for ( uint32_t i = 0 ; i < g_plc_cfg . size ( ) ; i + + ) {
p = & g_plc_cfg . at ( i ) ;
if ( p - > base . inf = = node - > id ) {
default_input_value = * ( uint8_t * ) p - > p_data ;
}
}
set_hw_point_value ( & hw - > input_head , & hw - > input_count ,
node - > id , default_input_value ) ;
} else if ( node - > type = = NODE_TYPE_HW_OUTPUT ) {
set_hw_point_value ( & hw - > output_head , & hw - > output_count , node - > id , 0 ) ;
}
}
}
}
static void print_hardware_manager ( HardwareManager * hw ) {
printf ( " ==================== 硬件点列表 ==================== \n " ) ;
printf ( " 硬件输入点( dev_out) : 共%d个 \n " , hw - > input_count ) ;
HWPoint * curr = hw - > input_head ;
int idx = 1 ;
while ( curr ) {
printf ( " %d. ID=%d, 值=%d \n " , idx + + , curr - > id , curr - > value ) ;
curr = curr - > next ;
}
printf ( " 硬件输出点( dev_in) : 共%d个 \n " , hw - > output_count ) ;
curr = hw - > output_head ;
idx = 1 ;
while ( curr ) {
printf ( " %d. ID=%d, 值=%d \n " , idx + + , curr - > id , curr - > value ) ;
curr = curr - > next ;
}
}
// ==================== 节点查找 ====================
static LogicNode * find_node ( LogicGraph * graph , int type , int id ) {
for ( int i = 0 ; i < graph - > node_count ; i + + ) {
if ( ( type = = 0 ) | | ( type = = 1 ) ) {
if ( graph - > nodes [ i ] . type = = type & & graph - > nodes [ i ] . id = = id ) {
return & graph - > nodes [ i ] ;
}
} else {
if ( graph - > nodes [ i ] . type = = type & &
( ( graph - > nodes [ i ] . id & 0xFF ) = = ( id & 0xFF ) ) ) {
return & graph - > nodes [ i ] ;
}
}
}
return NULL ;
}
// ==================== 逻辑图解析 ====================
int parse_reclose_logic ( const char * file_path , LogicGraph graphs [ ] , int * graph_count ) {
FILE * fp = fopen ( file_path , " rb " ) ;
if ( ! fp ) {
fprintf ( stderr , " 错误:无法打开文件 %s \n " , file_path ) ;
return - 1 ;
}
* graph_count = 0 ;
char buffer [ 4096 ] ;
size_t bytes_read = fread ( buffer , 1 , sizeof ( buffer ) - 1 , fp ) ;
buffer [ bytes_read ] = ' \0 ' ;
fclose ( fp ) ;
char * write_ptr = buffer ;
char * clean_buffer = buffer ;
while ( * clean_buffer ) {
if ( ! isspace ( ( unsigned char ) * clean_buffer ) ) {
* write_ptr + + = * clean_buffer ;
}
clean_buffer + + ;
}
* write_ptr = ' \0 ' ;
char * ptr = buffer ;
while ( ptr & & * graph_count < MAX_LOGIC_GRAPHS ) {
while ( * ptr & & * ptr ! = ' " ' ) ptr + + ;
if ( ! * ptr ) break ;
ptr + + ;
char key [ 20 ] ;
int key_len = 0 ;
while ( * ptr & & * ptr ! = ' " ' & & key_len < ( int ) sizeof ( key ) - 1 ) {
key [ key_len + + ] = * ptr + + ;
}
if ( ! * ptr ) break ;
key [ key_len ] = ' \0 ' ;
ptr + + ;
while ( * ptr & & * ptr ! = ' : ' ) ptr + + ;
if ( ! * ptr ) break ;
ptr + + ;
while ( * ptr & & * ptr ! = ' " ' ) ptr + + ;
if ( ! * ptr ) break ;
ptr + + ;
char graph_data [ 1024 ] ;
int data_len = 0 ;
while ( * ptr & & * ptr ! = ' " ' & & data_len < ( int ) sizeof ( graph_data ) - 1 ) {
graph_data [ data_len + + ] = * ptr + + ;
}
if ( ! * ptr ) break ;
graph_data [ data_len ] = ' \0 ' ;
ptr + + ;
if ( strstr ( graph_data , " node= " ) & & strstr ( graph_data , " link= " ) ) {
LogicGraph * cur_graph = & graphs [ * graph_count ] ;
memset ( cur_graph , 0 , sizeof ( LogicGraph ) ) ;
strncpy ( cur_graph - > key , key , sizeof ( cur_graph - > key ) - 1 ) ;
char * data_ptr = graph_data ;
while ( * data_ptr ) {
char * equals = strchr ( data_ptr , ' = ' ) ;
if ( ! equals ) break ;
char param_key [ 20 ] ;
int pkey_len = equals - data_ptr ;
if ( pkey_len < ( int ) sizeof ( param_key ) ) {
strncpy ( param_key , data_ptr , pkey_len ) ;
param_key [ pkey_len ] = ' \0 ' ;
} else {
data_ptr = equals + 1 ;
continue ;
}
char * value_start = equals + 1 ;
char * value_end = strchr ( value_start , ' & ' ) ;
if ( ! value_end ) value_end = value_start + strlen ( value_start ) ;
int value_len = value_end - value_start ;
char value [ 512 ] ;
if ( value_len < ( int ) sizeof ( value ) ) {
strncpy ( value , value_start , value_len ) ;
value [ value_len ] = ' \0 ' ;
} else {
data_ptr = value_end + 1 ;
continue ;
}
if ( strcmp ( param_key , " name " ) = = 0 ) {
strncpy ( cur_graph - > name , value , sizeof ( cur_graph - > name ) - 1 ) ;
} else if ( strcmp ( param_key , " node " ) = = 0 ) {
char * node_start = strchr ( value , ' [ ' ) ;
char * node_end = strchr ( value , ' ] ' ) ;
if ( node_start & & node_end ) {
node_start + + ;
* node_end = ' \0 ' ;
char * token = strtok ( node_start , " {}, " ) ;
while ( token & & cur_graph - > node_count < MAX_NODES_PER_GRAPH ) {
if ( strlen ( token ) > 0 ) {
LogicNode node ;
if ( sscanf ( token , " %d:%x:%d:%d " ,
& node . type , & node . id , & node . x , & node . y ) = = 4 ) {
node . value = 0 ;
cur_graph - > nodes [ cur_graph - > node_count + + ] = node ;
}
}
token = strtok ( NULL , " {}, " ) ;
}
}
} else if ( strcmp ( param_key , " link " ) = = 0 ) {
char * link_start = strchr ( value , ' [ ' ) ;
char * link_end = strchr ( value , ' ] ' ) ;
if ( link_start & & link_end ) {
link_start + + ;
* link_end = ' \0 ' ;
char * token = strtok ( link_start , " {}, " ) ;
while ( token & & cur_graph - > link_count < MAX_LINKS_PER_GRAPH ) {
if ( strlen ( token ) > 0 ) {
LogicLink link ;
if ( sscanf ( token , " %d:%x-%d:%x " ,
& link . src_type , & link . src_id ,
& link . dest_type , & link . dest_id ) = = 4 ) {
cur_graph - > links [ cur_graph - > link_count + + ] = link ;
}
}
token = strtok ( NULL , " {}, " ) ;
}
}
}
data_ptr = value_end ;
if ( * data_ptr = = ' & ' ) data_ptr + + ;
}
( * graph_count ) + + ;
}
}
return 0 ;
}
// ==================== 逻辑运算函数 ====================
static int collect_input_signals ( LogicGraph * graph , LogicNode * element_node ,
int * input_values , int max_inputs ) {
int input_count = 0 ;
for ( int i = 0 ; i < graph - > link_count & & input_count < max_inputs ; i + + ) {
LogicLink * link = & graph - > links [ i ] ;
if ( link - > dest_type = = element_node - > type & &
( ( link - > dest_id & 0xFF ) = = ( element_node - > id & 0xFF ) ) ) {
LogicNode * src_node = find_node ( graph , link - > src_type , link - > src_id ) ;
if ( src_node ) {
input_values [ input_count + + ] = src_node - > value ;
printf ( " 找到输入信号:%d:%d = %d \n " ,
link - > src_type , link - > src_id , src_node - > value ) ;
}
}
}
return input_count ;
}
static void execute_not_gate ( LogicNode * not_node , int input_value ) {
not_node - > value = ! input_value ;
printf ( " 非门运算:输入=%d → 输出=%d \n " , input_value , not_node - > value ) ;
}
static void execute_and_gate ( LogicNode * and_node , int * input_values , int input_count ) {
and_node - > value = ( input_count = = 0 ) ? 0 : 1 ;
for ( int i = 0 ; i < input_count ; i + + ) {
and_node - > value = and_node - > value & & input_values [ i ] ;
}
printf ( " 与门运算:输入=[ " ) ;
for ( int i = 0 ; i < input_count ; i + + ) {
printf ( " %d%s " , input_values [ i ] , ( i < input_count - 1 ) ? " , " : " " ) ;
}
printf ( " ] → 输出=%d \n " , and_node - > value ) ;
}
static void execute_or_gate ( LogicNode * or_node , int * input_values , int input_count ) {
or_node - > value = 0 ;
for ( int i = 0 ; i < input_count ; i + + ) {
or_node - > value = or_node - > value | | input_values [ i ] ;
}
printf ( " 或门运算:输入=[ " ) ;
for ( int i = 0 ; i < input_count ; i + + ) {
printf ( " %d%s " , input_values [ i ] , ( i < input_count - 1 ) ? " , " : " " ) ;
}
printf ( " ] → 输出=%d \n " , or_node - > value ) ;
}
static void execute_62p_gate ( LogicNode * node , int input_value ) {
int tp = ( node - > id > > 8 ) & 0xFFFFFF ;
int component_id = node - > id & 0xFF ;
if ( input_value = = 1 ) {
printf ( " 62p延时元件 (ID=%d, 序号=%d):输入=1, 开始延时%d毫秒 \n " ,
node - > id , component_id , tp ) ;
usleep ( tp * 1000 ) ;
node - > value = 1 ;
printf ( " 62p延时元件 (ID=%d, 序号=%d):延时结束,输出=1 \n " ,
node - > id , component_id ) ;
} else {
node - > value = 0 ;
}
}
static void execute_62d_gate ( LogicNode * node , int input_value ) {
int td = ( node - > id > > 8 ) & 0xFFFFFF ;
int component_id = node - > id & 0xFF ;
if ( input_value = = 1 ) {
node - > value = 1 ;
printf ( " 62d延时元件 (ID=%d, 序号=%d):输入=1, 立即输出=1 \n " ,
node - > id , component_id ) ;
} else {
printf ( " 62d延时元件 (ID=%d, 序号=%d):输入=0, 开始延时%d毫秒 \n " ,
node - > id , component_id , td ) ;
usleep ( td * 1000 ) ;
node - > value = 0 ;
printf ( " 62d延时元件 (ID=%d, 序号=%d):延时结束,输出=0 \n " ,
node - > id , component_id ) ;
}
}
static void execute_rising_edge_gate ( LogicNode * node , int input_value ) {
int component_id = node - > id & 0xFF ;
if ( node - > last_input = = 0 & & input_value = = 1 ) {
printf ( " 上升沿元件 (ID=%d, 序号=%d):检测到上升沿,输出脉冲 \n " ,
node - > id , component_id ) ;
node - > value = 1 ;
} else {
node - > value = 0 ;
}
node - > last_input = input_value ;
}
static void execute_falling_edge_gate ( LogicNode * node , int input_value ) {
int component_id = node - > id & 0xFF ;
if ( node - > last_input = = 1 & & input_value = = 0 ) {
printf ( " 下降沿元件 (ID=%d, 序号=%d):检测到下降沿,输出脉冲 \n " ,
node - > id , component_id ) ;
node - > value = 1 ;
} else {
node - > value = 0 ;
}
node - > last_input = input_value ;
}
static void execute_sr_latch ( LogicNode * node , int * input_values , int input_count ) {
int component_id = node - > id & 0xFF ;
int s = ( input_count > = 1 ) ? input_values [ 0 ] : 0 ;
int r = ( input_count > = 2 ) ? input_values [ 1 ] : 0 ;
printf ( " SR触发器 (ID=%d, 序号=%d): S=%d, R=%d \n " , node - > id , component_id , s , r ) ;
if ( s = = 1 ) {
node - > value = 1 ;
printf ( " SR触发器: S=1, 置位, 输出=1 \n " ) ;
} else if ( r = = 1 ) {
node - > value = 0 ;
printf ( " SR触发器: S=0, R=1, 复位, 输出=0 \n " ) ;
}
}
static void execute_rs_latch ( LogicNode * node , int * input_values , int input_count ) {
int component_id = node - > id & 0xFF ;
int r = ( input_count > = 1 ) ? input_values [ 0 ] : 0 ;
int s = ( input_count > = 2 ) ? input_values [ 1 ] : 0 ;
printf ( " RS触发器 (ID=%d, 序号=%d): R=%d, S=%d \n " , node - > id , component_id , r , s ) ;
if ( r = = 1 ) {
node - > value = 0 ;
printf ( " RS触发器: R=1, 复位, 输出=0 \n " ) ;
} else if ( s = = 1 ) {
node - > value = 1 ;
printf ( " RS触发器: R=0, S=1, 置位, 输出=1 \n " ) ;
}
}
// ==================== 逻辑图执行 ====================
int execute_logic_graph ( LogicGraph * graph , HardwareManager * hw ) {
if ( ! graph | | ! hw ) return - 1 ;
printf ( " \n ===================================================== \n " ) ;
printf ( " 执行逻辑图:%s (%s) \n " , graph - > key , graph - > name ) ;
printf ( " ===================================================== \n " ) ;
// 步骤1: 初始化节点值
printf ( " \n 【节点初始化】 \n " ) ;
for ( int i = 0 ; i < graph - > node_count ; i + + ) {
LogicNode * node = & graph - > nodes [ i ] ;
const char * type_name = " " ;
switch ( node - > type ) {
case NODE_TYPE_HW_INPUT :
node - > value = get_hw_point_value ( hw - > input_head , node - > id ) ;
type_name = " 硬件输入点 " ; break ;
case NODE_TYPE_HW_OUTPUT : type_name = " 硬件输出点 " ; break ;
case NODE_TYPE_OR_GATE : type_name = " 或门元件 " ; break ;
case NODE_TYPE_AND_GATE : type_name = " 与门元件 " ; break ;
case NODE_TYPE_NOT_GATE : type_name = " 非门元件 " ; break ;
case NODE_TYPE_62P_GATE : type_name = " 62p延时元件 " ; break ;
case NODE_TYPE_62D_GATE : type_name = " 62d延时元件 " ; break ;
case NODE_TYPE_RISING_EDGE : type_name = " 上升沿元件 " ; break ;
case NODE_TYPE_SR_LATCH : type_name = " SR触发器 " ; break ;
case NODE_TYPE_RS_LATCH : type_name = " RS触发器 " ; break ;
case NODE_TYPE_FALLING_EDGE : type_name = " 下降沿元件 " ; break ;
default : type_name = " 未知节点 " ; break ;
}
printf ( " %s (类型=%d, ID=%d): 初始值=%d \n " ,
type_name , node - > type , node - > id , node - > value ) ;
}
// 步骤2: 执行逻辑元件运算
printf ( " \n 【逻辑元件运算】 \n " ) ;
for ( int i = 0 ; i < graph - > node_count ; i + + ) {
LogicNode * node = & graph - > nodes [ i ] ;
int input_values [ 10 ] ;
int input_count ;
switch ( node - > type ) {
case NODE_TYPE_NOT_GATE :
printf ( " \n 处理非门元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
if ( input_count > 0 ) execute_not_gate ( node , input_values [ 0 ] ) ;
else { printf ( " 警告:非门元件没有输入信号 \n " ) ; node - > value = 0 ; }
break ;
case NODE_TYPE_OR_GATE :
printf ( " \n 处理或门元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
execute_or_gate ( node , input_values , input_count ) ;
break ;
case NODE_TYPE_AND_GATE :
printf ( " \n 处理与门元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
execute_and_gate ( node , input_values , input_count ) ;
break ;
case NODE_TYPE_62P_GATE :
printf ( " \n 处理62p延时元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
if ( input_count > 0 ) execute_62p_gate ( node , input_values [ 0 ] ) ;
else { printf ( " 警告: 62p延时元件没有输入信号 \n " ) ; node - > value = 0 ; }
break ;
case NODE_TYPE_62D_GATE :
printf ( " \n 处理62d延时元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
if ( input_count > 0 ) execute_62d_gate ( node , input_values [ 0 ] ) ;
else { printf ( " 警告: 62d延时元件没有输入信号 \n " ) ; node - > value = 0 ; }
break ;
case NODE_TYPE_RISING_EDGE :
printf ( " \n 处理上升沿元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
if ( input_count > 0 ) execute_rising_edge_gate ( node , input_values [ 0 ] ) ;
else { printf ( " 警告:上升沿元件没有输入信号 \n " ) ; node - > value = 0 ; }
break ;
case NODE_TYPE_FALLING_EDGE :
printf ( " \n 处理下降沿元件 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
if ( input_count > 0 ) execute_falling_edge_gate ( node , input_values [ 0 ] ) ;
else { printf ( " 警告:下降沿元件没有输入信号 \n " ) ; node - > value = 0 ; }
break ;
case NODE_TYPE_SR_LATCH :
printf ( " \n 处理SR触发器 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
execute_sr_latch ( node , input_values , input_count ) ;
break ;
case NODE_TYPE_RS_LATCH :
printf ( " \n 处理RS触发器 (ID=%d) \n " , node - > id ) ;
input_count = collect_input_signals ( graph , node , input_values , 10 ) ;
execute_rs_latch ( node , input_values , input_count ) ;
break ;
}
}
// 步骤3: 处理输出链路
printf ( " \n 【输出链路处理】 \n " ) ;
for ( int i = 0 ; i < graph - > link_count ; i + + ) {
LogicLink * link = & graph - > links [ i ] ;
LogicNode * src_node = find_node ( graph , link - > src_type , link - > src_id ) ;
LogicNode * dest_node = find_node ( graph , link - > dest_type , link - > dest_id ) ;
if ( src_node & & dest_node & & dest_node - > type = = NODE_TYPE_HW_OUTPUT ) {
dest_node - > value = src_node - > value ;
set_hw_point_value ( & hw - > output_head , & hw - > output_count ,
dest_node - > id , dest_node - > value ) ;
if ( dest_node - > id < MAX_OUT_NODES ) {
g_plc_st_out [ dest_node - > id ] = dest_node - > value ;
}
printf ( " 硬件输出: ID=%d = %d( 已同步到硬件管理器) \n " ,
dest_node - > id , dest_node - > value ) ;
}
}
printf ( " \n 【逻辑图执行结果】 \n " ) ;
for ( int i = 0 ; i < graph - > node_count ; i + + ) {
LogicNode * node = & graph - > nodes [ i ] ;
const char * type_name = " " ;
switch ( node - > type ) {
case NODE_TYPE_HW_INPUT : type_name = " 硬件输入点 " ; break ;
case NODE_TYPE_HW_OUTPUT : type_name = " 硬件输出点 " ; break ;
case NODE_TYPE_OR_GATE : type_name = " 或门元件 " ; break ;
case NODE_TYPE_AND_GATE : type_name = " 与门元件 " ; break ;
case NODE_TYPE_NOT_GATE : type_name = " 非门元件 " ; break ;
case NODE_TYPE_62P_GATE : type_name = " 62p延时元件 " ; break ;
case NODE_TYPE_62D_GATE : type_name = " 62d延时元件 " ; break ;
case NODE_TYPE_RISING_EDGE : type_name = " 上升沿元件 " ; break ;
case NODE_TYPE_SR_LATCH : type_name = " SR触发器 " ; break ;
case NODE_TYPE_RS_LATCH : type_name = " RS触发器 " ; break ;
case NODE_TYPE_FALLING_EDGE : type_name = " 下降沿元件 " ; break ;
default : type_name = " 未知节点 " ; break ;
}
printf ( " %s (ID=%d): 最终值=%d \n " , type_name , node - > id , node - > value ) ;
}
return 0 ;
}
// ==================== PLC 逻辑入口 ====================
int PLC_Logic ( void ) {
char proc_dir [ 512 ] = { 0 } ;
if ( 0 ! = func_get_process_self_dir ( proc_dir , sizeof ( proc_dir ) ) )
{
MY_LOG_E ( " func_get_process_self_dir failed " ) ;
return - 1 ;
}
std : : string file_path = std : : string ( proc_dir ) + " config/PLC/Reclose_logic.txt " ;
LogicGraph graphs [ MAX_LOGIC_GRAPHS ] ;
int graph_count = 0 ;
if ( parse_reclose_logic ( file_path . c_str ( ) , graphs , & graph_count ) ! = 0 ) {
return 2 ;
}
HardwareManager hw ;
init_hardware_manager ( & hw ) ;
extract_hw_points_from_graphs ( graphs , graph_count , & hw , 0 ) ;
# ifdef DEBUG
printf ( " ==================== 文件解析结果 ==================== \n " ) ;
printf ( " 共解析到 %d 个逻辑图 \n " , graph_count ) ;
for ( int i = 0 ; i < graph_count ; i + + ) {
printf ( " 逻辑图%d: key=%s, name=%s, 节点数=%d, 链路数=%d \n " ,
i + 1 , graphs [ i ] . key , graphs [ i ] . name ,
graphs [ i ] . node_count , graphs [ i ] . link_count ) ;
}
print_hardware_manager ( & hw ) ;
for ( int i = 0 ; i < graph_count ; i + + ) {
execute_logic_graph ( & graphs [ i ] , & hw ) ;
}
printf ( " \n ==================== 最终硬件输出状态 ==================== \n " ) ;
printf ( " 硬件输出点( dev_in) 最终值: \n " ) ;
HWPoint * curr = hw . output_head ;
int idx = 1 ;
while ( curr ) {
printf ( " %d. ID=%d: %d \n " , idx + + , curr - > id , curr - > value ) ;
curr = curr - > next ;
}
# endif
destroy_hardware_manager ( & hw ) ;
return 0 ;
}
// ==================== 模块初始化与线程 ====================
int app_plc_init1 ( void * arg )
{
stru_app * p_app = ( stru_app * ) arg ;
if ( NULL = = p_app ) {
MY_LOG_E ( " app_plc_init1 arg null " ) ;
return - 1 ;
}
int ret = 0 ;
ret | = dc_signal_out ( " plc.run_cnt " , " plc线程计数 " , DATA_TYPE_U32 , & p_app - > run_cnt ) ;
for ( int i = 0 ; i < MAX_OUT_NODES ; i + + ) {
std : : string saddr = " plc.st.out. " + std : : to_string ( i ) ;
std : : string desc = " plc输出 " + std : : to_string ( i ) ;
ret | = dc_signal_out ( saddr . c_str ( ) , desc , DATA_TYPE_U8 , & g_plc_st_out [ i ] ) ;
}
if ( ret ! = 0 ) {
MY_LOG_E ( " app_plc_init1 dc_signal_out failed " ) ;
return - 1 ;
}
p_plc_cfg = self_ptl_cfg_get ( ) ;
if ( nullptr = = p_plc_cfg ) {
MY_LOG_E ( " app_plc_init1 self_ptl_cfg_get failed " ) ;
return - 1 ;
}
for ( uint32_t i = 0 ; i < p_plc_cfg - > st_vec . size ( ) ; i + + ) {
stru_self_ptl_cfg_base * p_base = & p_plc_cfg - > st_vec . at ( i ) ;
g_plc_cfg . push_back ( { ( * p_base ) , NULL } ) ;
}
return 0 ;
}
int app_plc_init2 ( void * arg )
{
int ret = 0 ;
ret | = dc_signal_in ( " plc.run_cnt_in " , " plc.run_cnt_in " , " plc.run_cnt " , ( void * * ) & gp_run_cnt_in ) ;
for ( uint32_t i = 0 ; i < g_plc_cfg . size ( ) ; i + + ) {
stru_plc_cfg * p = & g_plc_cfg [ i ] ;
std : : string saddr = " plc.st.in. " + std : : to_string ( i ) ;
std : : string desc = " plc链接遥信 " + std : : to_string ( i ) ;
ret | = dc_signal_in ( saddr . c_str ( ) , desc , p - > base . saddr . c_str ( ) , ( void * * ) & p - > p_data ) ;
}
if ( ret ! = 0 ) {
MY_LOG_E ( " app_plc_init2 dc_signal_in failed " ) ;
return - 1 ;
}
return 0 ;
}
void * app_plc ( void * arg )
{
if ( NULL = = arg ) {
LOG_E ( " app_plc arg null " ) ;
return NULL ;
}
stru_app * p_app = ( stru_app * ) arg ;
uint32_t event ;
while ( 1 ) {
task_event_recv ( p_app - > p_event ,
EV_TIMER1 | EV_TIMER2 | EV_TIMER3 ,
TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR ,
TASK_EVENT_WAIT_FOREVER ,
& event ) ;
if ( event & EV_TIMER1 ) { ; }
if ( event & EV_TIMER2 ) { ; }
if ( event & EV_TIMER3 ) {
p_app - > run_cnt + + ;
PLC_Logic ( ) ;
}
}
return NULL ;
}