#include #include #include "../include/tinyxml2/tinyxml2.h" #include "../include/config.h" #include "../include/ECatMain.h" #include "../include/parsexml.h" #include "./list.h" #include "./uint.h" #include "./util.h" using namespace std; using namespace tinyxml2; sSysConfig gSysConfig; static sECatData *pECatData; void map_add_ccu(sCCU *p) { pECatData->ccuArray[pECatData->ccuIndex] = p; pECatData->ccuIndex++; } void map_add_eau(sEAU *p) { pECatData->eauArray[pECatData->eauIndex] = p; pECatData->eauIndex++; } void map_add_pcc(sPCC *p) { pECatData->pccArray[pECatData->pccIndex] = p; pECatData->pccIndex++; } #if 1 float str2float(const char *str, float multiple) { float f0 = atof(str); float f = f0 / multiple; // printf("f0 = %f, multiple = %f, f = %f \n", f0, multiple, f); return f; } #else float str2float(const char *str) { float f=atof(str); return f; } #endif uint16_t str2val(const char *str, int multiple) { float f=atof(str) * float(multiple); return uint16_t(f); } bool is_string(const char *str_src, const char *str_dest) { string sname(str_src); if(sname.compare(str_dest) == 0) { return true; } return false; } void parse_ccu(XMLElement* xccu, sEAU *eau) { const char *name; const char *value; const XMLAttribute* ccuAttr = xccu->FirstAttribute(); sCCU *ccu = new sCCU(); list_add_tail(eau->ccu_head, ccu); map_add_ccu(ccu); ccu->aiLength = sizeof(sCCUAI); ccu->aoLength = sizeof(sCCUAO); while (ccuAttr) { name = ccuAttr->Name(); value = ccuAttr->Value(); //cout << "\t" << name << " = " << value << endl; if(is_string(name, "address")) { ccu->cfg.address = str2val(value, 1); my_setbit((uint8_t *)(&eau->ccu_id_table), ccu->cfg.address-1, 1); }else if(is_string(name, "pcs0_enable")) { ccu->cfg.pcs_enable[0] = str2val(value, 1); }else if(is_string(name, "pcs0_address")) { ccu->cfg.pcs_address[0] = str2val(value, 1); }else if(is_string(name, "pcs1_enable")) { ccu->cfg.pcs_enable[1] = str2val(value, 1); }else if(is_string(name, "pcs1_address")) { ccu->cfg.pcs_address[1] = str2val(value, 1); }else if(is_string(name, "pcs2_enable")) { ccu->cfg.pcs_enable[2] = str2val(value, 1); }else if(is_string(name, "pcs2_address")) { ccu->cfg.pcs_address[2] = str2val(value, 1); }else if(is_string(name, "pcs3_enable")) { ccu->cfg.pcs_enable[3] = str2val(value, 1); }else if(is_string(name, "pcs3_address")) { ccu->cfg.pcs_address[3] = str2val(value, 1); } for(int i=0; i<4; i++) { if(ccu->cfg.pcs_enable[i] == 0) { continue; } my_setbit((uint8_t *)(&eau->pcs_id_table), ccu->cfg.pcs_address[i]-1, 1); } ccuAttr = ccuAttr->Next(); } } void parse_eau(XMLElement* xeau, sPCC *pcc) { // 遍历属性列表 const char *name; const char *value; const XMLAttribute* eauAttr = xeau->FirstAttribute(); sEAU *eau = new sEAU(); list_add_tail(pcc->eauHead, eau); map_add_eau(eau); eau->aiLength = sizeof(sEAUAI); eau->aoLength = sizeof(sEAUAO); while (eauAttr) { name = eauAttr->Name(); value = eauAttr->Value(); //cout << "\t" << name << " = " << value << endl; if(is_string(name, "address")) { eau->cfg.address = str2val(value, 1); eau->address = eau->cfg.address; }else if(is_string(name, "rated_active_power")) { eau->cfg.rated_active_power = str2val(value, 100); }else if(is_string(name, "rated_reactive_power")) { eau->cfg.rated_reactive_power = str2val(value, 100); }else if(is_string(name, "ccu_number")) { eau->cfg.ccu_number = str2val(value, 1); }else if(is_string(name, "pcs_number")) { eau->cfg.pcs_number= str2val(value, 1); } eauAttr = eauAttr->Next(); } //cout << endl; XMLElement* eauChild = xeau->FirstChildElement(); while (eauChild) { if(is_string(eauChild->Name(), "CCU")) { parse_ccu(eauChild, eau); } eauChild = eauChild->NextSiblingElement(); } //cout << endl; } void parse_pcc(XMLElement* xpcc) { const char *name; const char *value; const XMLAttribute* pccAttr = xpcc->FirstAttribute(); sPCC *pcc = new sPCC(); list_add_tail(pECatData->pccHead, pcc); map_add_pcc(pcc); while ( pccAttr ) { name = pccAttr->Name(); value = pccAttr->Value(); //cout << "\t" << name << " = " << value << endl; if(is_string(name, "address")) { pcc->cfg.address = str2val(value, 1); }else if(is_string(name, "eau_number")) { pcc->cfg.eau_number = str2val(value, 1); }else if(is_string(name, "ccu_number")) { pcc->cfg.ccu_number = str2val(value, 1); }else if(is_string(name, "pcs_number")) { pcc->cfg.pcs_number = str2val(value, 1); }else if(is_string(name, "bind_eau")) { pcc->cfg.bind_eau = str2val(value, 1); }else if(is_string(name, "rated_active_power")) { pcc->cfg.rated_active_power = str2val(value, 100); }else if(is_string(name, "rated_reactive_power")) { pcc->cfg.rated_reactive_power = str2val(value, 100); }else if(is_string(name, "fvr_power_regulate_ratio")) { pcc->cfg.fvr_power_regulate_ratio = str2float(value, 1.0); } pccAttr = pccAttr->Next(); } XMLElement* pccChild = xpcc->FirstChildElement(); while (pccChild) { if(is_string(pccChild->Name(), "EAU")) { parse_eau(pccChild, pcc); } pccChild = pccChild->NextSiblingElement(); } } void parse_network(XMLElement* ccs) { const XMLAttribute* netAttr = ccs->FirstAttribute(); if(netAttr != NULL) { pECatData->cfg.fvr_pcc_number = str2val(ccs->Attribute("fvr_pcc_number"), 1); //cout << "fvr_pcc_number" << ":" << pECatData->cfg.fvr_pcc_number << endl; } XMLElement* pccChild = ccs->FirstChildElement(); while (pccChild) { if(is_string(pccChild->Name(), "FVR_PCC")) { parse_pcc(pccChild); } //cout << endl; pccChild = pccChild->NextSiblingElement(); } //cout << endl; } void parse_signal(XMLElement* ccs) { //以下两个变量 将要存储 目录节点 下的 信息节点 const char *name; const char *value; //XMLAttribute* netAttr 表示 目录节点下的第一个 信息节点 const XMLAttribute* netAttr = ccs->FirstAttribute(); //循环遍历 目录节点下的所有 数据节点 while (netAttr) { //获取第 n 个 目录节点 下的 信息节点 name = netAttr->Name(); value = netAttr->Value(); if(value != NULL) { //并将遍历到的 本目录节点 下的所有的 信息节点 中所有的数据信息 存储到对应的全局pECatData中 // cout << "\t" << name << " = " << value << endl; if(is_string(name, "remote_local_switch_related_di_address")) { pECatData->cfg.signal.remote_local_switch_related_di_address = str2val(value, 1); }else if(is_string(name, "ccs_enable_switch_related_di_address")) { pECatData->cfg.signal.ccs_enable_switch_related_di_address = str2val(value, 1); }else if(is_string(name, "ffr_enable_switch_related_di_address")) { pECatData->cfg.signal.ffr_enable_switch_related_di_address = str2val(value, 1); }else if(is_string(name, "fvr_enable_switch_related_di_address")) { pECatData->cfg.signal.fvr_enable_switch_related_di_address = str2val(value, 1); }else if(is_string(name, "fpu_enable_switch_related_di_address")) { pECatData->cfg.signal.fpu_enable_switch_related_di_address = str2val(value, 1); }else if(is_string(name, "fpu_start_signal_1_related_di_address")) { pECatData->cfg.signal.fpu_start_signal_1_related_di_address = str2val(value, 1); }else if(is_string(name, "fpu_start_signal_2_related_di_address")) { pECatData->cfg.signal.fpu_start_signal_2_related_di_address = str2val(value, 1); } }else{ // cout << "\t" << name << endl; } //获取下一个信息节点 netAttr = netAttr->Next(); } //cout << endl; } void parse_ffr(XMLElement* ccs) { const char *name; const char *value; const XMLAttribute* netAttr = ccs->FirstAttribute(); while (netAttr) { name = netAttr->Name(); value = netAttr->Value(); if(value != NULL) { // 频率的精度为0.0005, 所有频率值需要除精度 // cout << "\t" << name << " = " << value << endl; if(is_string(name, "enable")) { pECatData->cfg.ffr.enable = str2val(value,1); }else if(is_string(name, "rated_frequency")) { pECatData->cfg.ffr.rated_frequency = str2float(value,FRE_UNIT); }else if(is_string(name, "frequency_frozen_zone")) { pECatData->cfg.ffr.frequency_frozen_zone = str2float(value,FRE_UNIT); }else if(is_string(name, "power_regulate_ratio")) { pECatData->cfg.ffr.power_regulate_ratio = str2float(value,1.0); }else if(is_string(name, "power_limit_ratio")) { pECatData->cfg.ffr.power_limit_ratio = str2float(value,1.0); }else if(is_string(name, "frequency_return_difference")) { pECatData->cfg.ffr.frequency_return_difference = str2float(value,FRE_UNIT); }else if(is_string(name, "frequency_offset_difference")) { pECatData->cfg.ffr.frequency_offset_difference = str2val(value,1); }else if(is_string(name, "hold_time")) { pECatData->cfg.ffr.hold_time = str2float(value,1.0); // str2val(value, 1); }else if(is_string(name, "simulate_timeout_time")) { pECatData->cfg.ffr.simulate_timeout_time = str2val(value, 1); }else if(is_string(name, "wavetest_start_frequency")) { pECatData->cfg.ffr.wavetest_start_frequency= str2float(value,FRE_UNIT); }else if(is_string(name, "wavetest_end_frequency")) { pECatData->cfg.ffr.wavetest_end_frequency= str2float(value,FRE_UNIT); }else if(is_string(name, "wavetest_step_frequency")) { pECatData->cfg.ffr.wavetest_step_frequency = str2float(value,FRE_UNIT); }else if(is_string(name, "wavetest_step_time")) { pECatData->cfg.ffr.wavetest_step_time = str2val(value, 1); } }else{ // //cout << "\t" << name << endl; } netAttr = netAttr->Next(); } //cout << endl; } void parse_fvr(XMLElement* ccs) { const char *name; const char *value; const XMLAttribute* netAttr = ccs->FirstAttribute(); while (netAttr) { name = netAttr->Name(); value = netAttr->Value(); if(value != NULL) { // cout << "\t" << name << " = " << value << endl; if(is_string(name, "enable")) { pECatData->cfg.fvr.enable = str2val(value,1); }else if(is_string(name, "rated_voltage")) { pECatData->cfg.fvr.rated_voltage = str2val(value, 1); }else if(is_string(name, "voltage_frozen_zone")) { pECatData->cfg.fvr.voltage_frozen_zone = str2val(value, 1); // }else if(is_string(name, "power_regulate_ratio")) { // pECatData->cfg.fvr.power_regulate_ratio = str2float(value, 1.0); }else if(is_string(name, "power_limit_ratio")) { pECatData->cfg.fvr.power_limit_ratio = str2float(value, 1.0); // printf(" -- ratio= %f.\n", pECatData->cfg.fvr.power_limit_ratio); }else if(is_string(name, "voltage_return_difference")) { pECatData->cfg.fvr.voltage_return_difference = str2val(value, 1); }else if(is_string(name, "hold_time")) { pECatData->cfg.fvr.hold_time = str2val(value, 1); }else if(is_string(name, "simulate_timeout_time")) { pECatData->cfg.fvr.simulate_timeout_time = str2val(value, 1); }else if(is_string(name, "wavetest_start_voltage")) { pECatData->cfg.fvr.wavetest_start_voltage= str2val(value, 1); }else if(is_string(name, "wavetest_end_voltage")) { pECatData->cfg.fvr.wavetest_end_voltage= str2val(value, 1); }else if(is_string(name, "wavetest_step_voltage")) { pECatData->cfg.fvr.wavetest_step_voltage = str2val(value, 1); }else if(is_string(name, "wavetest_step_time")) { pECatData->cfg.fvr.wavetest_step_time = str2val(value, 1); } }else{ //cout << "\t" << name << endl; } netAttr = netAttr->Next(); } //cout << endl; } void parse_fpu(XMLElement* ccs) { const char *name; const char *value; const XMLAttribute* netAttr = ccs->FirstAttribute(); while (netAttr) { name = netAttr->Name(); value = netAttr->Value(); if(value != NULL) { //cout << "\t" << name << " = " << value << endl; if(is_string(name, "enable")) { pECatData->cfg.fpu.enable = str2val(value,1); }else if(is_string(name, "start_signal_mode")) { pECatData->cfg.fpu.start_signal_mode = str2val(value, 1); }else if(is_string(name, "hold_time")) { pECatData->cfg.fpu.hold_time = str2val(value, 1); } }else{ //cout << "\t" << name << endl; } netAttr = netAttr->Next(); } //cout << endl; } void parse_ip(XMLElement* ccs) { const char *name; const char *value; const XMLAttribute* netAttr = ccs->FirstAttribute(); while (netAttr) { name = netAttr->Name(); value = netAttr->Value(); if(value != NULL) { //cout << "\t" << name << " = " << value << endl; if(is_string(name, "ccm0_a_ip_address")) { pECatData->cfg.ip.ccm0_a_ip_address = str2val(value, 1); }else if(is_string(name, "ccm0_b_ip_address")) { pECatData->cfg.ip.ccm0_b_ip_address = str2val(value, 1); }else if(is_string(name, "ccm0_a_104_port")) { pECatData->cfg.ip.ccm0_a_104_port = str2val(value, 1); }else if(is_string(name, "ccm0_a_modbus_port")) { pECatData->cfg.ip.ccm0_a_modbus_port = str2val(value, 1); }else if(is_string(name, "ccm0_b_104_port")) { pECatData->cfg.ip.ccm0_b_104_port = str2val(value, 1); }else if(is_string(name, "ccm0_b_modbus_port")) { pECatData->cfg.ip.ccm0_b_modbus_port = str2val(value, 1); }else if(is_string(name, "ccm1_a_ip_address")) { pECatData->cfg.ip.ccm1_a_ip_address = str2val(value, 1); }else if(is_string(name, "ccm1_b_ip_address")) { pECatData->cfg.ip.ccm1_b_ip_address = str2val(value, 1); }else if(is_string(name, "ccm1_a_104_port")) { pECatData->cfg.ip.ccm1_a_104_port = str2val(value, 1); }else if(is_string(name, "ccm1_a_modbus_port")) { pECatData->cfg.ip.ccm1_a_modbus_port = str2val(value, 1); }else if(is_string(name, "ccm1_b_104_port")) { pECatData->cfg.ip.ccm1_b_104_port = str2val(value, 1); }else if(is_string(name, "ccm1_b_modbus_port")) { pECatData->cfg.ip.ccm1_b_modbus_port = str2val(value, 1); } } netAttr = netAttr->Next(); } //cout << endl; } //将CCS节点下的所有信息节点全部送往该函数中进行处理 int parse_ccs(XMLElement* ccs) { //获取该节点的名字 以及 其节点中存放的数值 const char *name = ccs->Name(); const char *value = ccs->GetText(); //首先通过value值来判断其是 信息节点 还是 目录节点 if(value != NULL) { //再通过其信息节点的 名称来做不通的处理 // //cout << name << " = " << value << endl; // 将数据信息的值 由 数字字符串转换为浮点数 并计入全局变量pECatData表中 就是其属性ECatData表中 if(is_string(name, "ct_signal_ratio")) { pECatData->cfg.ct_signal_ratio = str2val(value, 1); }else if(is_string(name, "pt_signal_ratio")) { pECatData->cfg.pt_signal_ratio = str2val(value, 1); }else if(is_string(name, "rated_active_power")) { pECatData->cfg.rated_active_power = str2val(value, 100); }else if(is_string(name, "rated_reactive_power")) { pECatData->cfg.rated_reactive_power = str2val(value, 100); }else if(is_string(name, "pcs_rated_active_power")) { pECatData->cfg.pcs_rated_active_power = str2val(value, 1); }else if(is_string(name, "pcs_rated_reactive_power")) { pECatData->cfg.pcs_rated_reactive_power = str2val(value, 1); }else if(is_string(name, "bms_info_source")) { //字符串拷贝 strcpy(pECatData->cfg.bms_info_source, value); }else if(is_string(name, "ffr_bind_eau")) { pECatData->cfg.ffr_bind_eau = str2val(value, 1); }else if(is_string(name, "pcs_number")) { pECatData->cfg.pcs_number = str2val(value, 1); }else if(is_string(name, "ccu_number")) { pECatData->cfg.ccu_number = str2val(value, 1); }else if(is_string(name, "eau_number")) { pECatData->cfg.eau_number = str2val(value, 1); }else if(is_string(name, "ccm_number")) { pECatData->cfg.ccm_number = str2val(value, 1); } }else{ //以上都是 信息节点 //以下都是 目录节点 //通过判断名字来做不通的数据处理 // //cout << name << endl; if(is_string(name, "signal_bind")) { //将名为signal_bind的 目录节点 传入下面的函数 进行进一步处理 //其实就是再将其目录节点下的 信息节点再次解析存入 全局结构体中 parse_signal(ccs); }else if(is_string(name, "ffr_config")) { parse_ffr(ccs); }else if(is_string(name, "fvr_config")) { parse_fvr(ccs); }else if(is_string(name, "fpu_config")) { parse_fpu(ccs); }else if(is_string(name, "ip_config")) { parse_ip(ccs); }else if(is_string(name, "network")) { parse_network(ccs); } } return 1; } //从ccm.xml文件中获取Ecat设备点表信息 将xml中的信息存储在 sECatData mData 中 解析xml文件 int parse_xml(const char* name, sECatData *p) { //抽象出一个XML文档的实例化对象 XMLDocument doc; //doc实例化对象去加载对应name的xml文件 并判断其是否加载成功对应的文件 if ( doc.LoadFile(name) ) { doc.PrintError(); return -1; } //换名 其中pECatData 就是 ECatMain 中的 sECatData mData pECatData = p; XMLElement* ccs = NULL; // 根元素 此时根据xml文件中得知其是EtherCATInfo的这个节点 XMLElement* ccm= doc.RootElement(); //获取根节点EtherCATInfo的这个节点中的Version的值 cout << "Version=" << ccm->Attribute( "Version" ) << endl << endl; // 遍历元素 //从根节点中获取名为Descriptions的节点 并将这个节点赋值给XMLElement* descriptions XMLElement* descriptions = ccm->FirstChildElement("Descriptions"); //查看Descriptions节点是否存在 if(descriptions !=NULL) { //如果存在则 在Descriptions寻找名为CCS的节点 ccs = descriptions->FirstChildElement( "CCS" ); // printf(" find ccs = 0x%x\n", ccs); } while (ccs) { // 遍历子元素 //XMLElement* ccsChild指向ccs节点下的第一个元素 例如:ct_signal_ration XMLElement* ccsChild = ccs->FirstChildElement(); while (ccsChild) { //将CCS节点下的所有子节点全部送去该函数进行处理 parse_ccs(ccsChild); //此时ccsChild节点同级的下一个元素节点 ccsChild = ccsChild->NextSiblingElement(); } //此时ccs节点同级的下一个元素节点 ccs = ccs->NextSiblingElement( "ccs" ); } printf("parse xml finish.\n"); return 0; } void config_print(void) { }