// // Created by huli on 2020/9/25. // #ifndef NNXX_TESTS_SNAP7_E_BASE_H #define NNXX_TESTS_SNAP7_E_BASE_H #include #include #include #include #include "../error_code/error_code.h" #include "../tool/thread_condition.h" #include "../snap7_communication/snap7_buf.h" #include "../snap7_communication/s7_plc.h" #include "../snap7_communication/snap7_communication.pb.h" class Snap7_communication_base { public: //snap7的通信延时, 默认50ms #define SNAP7_COMMUNICATION_DELAY_TIME_MS 10 //snap7, 通信错误的最大次数, 默认3 #define SNAP7_COMMUNICATION_ERROR_COUNT_MAX 10 //snap7的通信参数路径 #define SNAP7_COMMUNICATION_PARAMETER_PATH "snap7_communication.prototxt" //通信状态 enum Snap7_communication_statu { SNAP7_COMMUNICATION_UNKNOWN =0, //通信状态 未知 SNAP7_COMMUNICATION_READY =1, //通信状态 正常 SNAP7_COMMUNICATION_RECEIVE =2, //接受 SNAP7_COMMUNICATION_SEND =3, //发送 SNAP7_COMMUNICATION_DISCONNECT =4, //断连 SNAP7_COMMUNICATION_FAULT =10, //通信状态 错误 }; public: Snap7_communication_base(); Snap7_communication_base(const Snap7_communication_base& other)= default; Snap7_communication_base& operator =(const Snap7_communication_base& other)= default; ~Snap7_communication_base(); public://API functions //初始化 通信 模块。如下三选一 virtual Error_manager communication_init(); //初始化 通信 模块。从文件读取 virtual Error_manager communication_init_from_protobuf(std::string prototxt_path); //初始化 通信 模块。从protobuf读取 virtual Error_manager communication_init_from_protobuf(Snap7_communication_proto::Snap7_communication_parameter_all& snap7_communication_parameter_all); //反初始化 通信 模块。 virtual Error_manager communication_uninit(); //唤醒s7通信线程 virtual Error_manager communication_start(); //停止s7通信线程 virtual Error_manager communication_stop(); public://get or set member variable Snap7_communication_statu get_status(); //修改通信延时, 单位ms Error_manager set_communication_delay_time_ms(int time); //修改状态 Error_manager set_snap7_communication_statu(Snap7_communication_base::Snap7_communication_statu statu); protected://member functions //通信连接 Error_manager communication_connect(std::string ip_string); //启动通信, run thread Error_manager communication_run(); //通信断连 Error_manager communication_disconnect(); //mp_communication_thread线程的执行函数, 负责进行s7的通信 void communication_thread(); //接受数据, 读取DB块, Error_manager read_data_buf(Snap7_buf& snap7_buf); //发送数据, 写入DB块, Error_manager write_data_buf(Snap7_buf& snap7_buf); //数据颠倒 Error_manager reverse_byte(void* p_buf_in, void* p_buf_out, int size); //更新数据 virtual Error_manager updata_receive_buf(); virtual Error_manager updata_send_buf(); protected://member variable public: //状态 Snap7_communication_statu m_communication_status; //通信状态 std::string m_ip_string; //通信ip int m_error_count; //错误的计数, 如果超过3次就重连 //通信模块 std::mutex m_communication_lock; //通信锁 TSnap7Client m_snap7_client; //通信的客户端 int m_communication_delay_time_ms;//通信延时, 单位ms //注:s7协议通信很不稳定, 在每次使用 TSnap7Client 之后, 都需要加延时 //数据 std::mutex m_receive_buf_lock; //接受的锁 std::map m_receive_buf_map; //接受的map容器 std::mutex m_send_buf_lock; //发送的锁 std::map m_send_buf_map; //发送的map容器 //线程, snap7的通信核心就是对 发送和接受内存的 周期性读写, 所以使用一个线程即可. std::thread* mp_communication_thread; //通信的线程指针 Thread_condition m_communication_condition; //通信的条件变量 private: }; #endif //NNXX_TESTS_SNAP7_E_BASE_H