#include "cascade.h" #include "common.h" #include "elog.h" #include "modbus_handle.h" #include "cfg.h" #include "thread.h" #include "switch_ctrl.h" #include "paras.h" #if 0 #define LOGD log_d #define LOGE log_e #define LOGW log_w #else #define LOGD printf #define LOGE printf #define LOGW printf #endif #define MB_MAX_LEN 250 #define MB_PARA_SIM #define SLAVE_DATA_SIM #ifdef MB_PARA_SIM #define MB_MASTER 0 #endif int cur_dev_addr=1; static cascade_handle_t casHandle={.inited=0}; ////////////////////////////////////////////////// static inline GlobalDeviceManager* get_dm(void) { return &__globalDeviceManage; } static inline GlobalDeviceManager* get_dm2(void) { return &__globalDeviceManage2; } static inline ModbusInfo_t *get_mb(void) { #ifdef MB_PARA_SIM static ModbusInfo_t mbinfo={ #if (MB_MASTER==1) .product_modbus_type=0, #else .product_modbus_type=1, #endif .product_modbus_addr=1, .product_modbus_baud=115200, }; return &mbinfo; #else return &get_dm()->_global_device_info->_gmodbus_info; #endif } static int slave_init(cascade_handle_t *cas) { int i; for(i=0; i<=CASCADE_MAX; i++) { cas->slaves[i].addr = -1; cas->slaves[i].err = 0; } return 0; } static int slave_add(cascade_handle_t *cas, int addr) { cas->slaves[addr].addr = addr; cas->slaves[addr].err = 0; return 0; } static int slave_cnt(cascade_handle_t *cas) { int i,cnt=0; for(i=1; i<=CASCADE_MAX; i++) { if(cas->slaves[i].addr>=0) { cnt++; } } return cnt; } static slave_t* slave_get(cascade_handle_t *cas, int addr) { return &cas->slaves[addr]; } static int slave_find(cascade_handle_t *cas, int addr) { if(cas->slaves[addr].addr>=0) { return 1; } return 0; } static int slave_get_info(cascade_handle_t *cas, int hardread) { int i,j,r; uint8_t type,maxChn; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm=get_dm(); board_info_t *info=&cas->info; memset(info, 0, sizeof(board_info_t)); #ifdef SLAVE_DATA_SIM for(j=1; j<10; j++) { info->board[info->cnt].addr = 1; info->board[info->cnt].type = 3; info->board[info->cnt].ch_addr = 4; info->cnt++; } #else if(hardread) { for(i=1; i_globalRelaySampManger, i, &type, &maxChn, dm->_global_device_info->product_pwr_type); if(r==0) { for(j=0; jboard[info->cnt].addr = i; info->board[info->cnt].type = type; info->board[info->cnt].ch_addr = j+1; info->cnt++; } } } } else { list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp->product_saddr==0) { continue; } info->board[info->cnt].addr = tmp->product_saddr; info->board[info->cnt].type = tmp->product_ch_type; info->board[info->cnt].ch_addr = tmp->product_ch_addr; info->cnt++; } } #endif LOGD("___ slave_get_info addr, cnt: %d\n", info->cnt); return 0; } static int slave_get_all_data(cascade_handle_t *cas) { GlobalDeviceManager *dm=get_dm(); GlobalPowerManger *tmp=NULL; cas->pwrInfo.cnt=0; list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp) { cas->pwrInfo.info[cas->pwrInfo.cnt] = tmp->_PowerInfo; cas->pwrInfo.cnt++; } } return 0; } static int get_pwr_info(board_info_t *info, int chId, GlobalPowerManger *power) { int i; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm=get_dm(); list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp->product_ch_id==chId) { power->product_id = dm->_global_device_info->product_id; power->product_ch_id = tmp->product_ch_id; strcpy(power->product_ch_name, tmp->product_ch_name); power->product_ch_type = tmp->product_ch_type; power->product_ch_status = tmp->product_ch_status; power->product_ch_start_delay = tmp->product_ch_start_delay; power->product_ch_stop_delay = tmp->product_ch_stop_delay; return 0; } } return -1; } static int slave_save(cascade_handle_t *cas) { int r; GlobalPowerManger power; GlobalDeviceManager *dm=get_dm(); if(cas->cmd.obj!=OBJ_CHANNEL) { return -1; } r = get_pwr_info(cas, cas->cmd.chId, &power); if(r) { LOGE("____ get_pwr_info failed\n"); return -1; } r = dev_update_power_manage_genera_info(dm->db, dm->_global_device_info->product_id, cas->cmd.chId, &power); return r; } ///////////////////////////////////////////////////////////////////////////////////////// static int mb_init(cascade_handle_t *cas, char *path, int type, int addr, uint32_t baud) { int r; r = g_modbus_init(&cas->m, path, baud, type, addr, type?"master":"slave", 0); if(r==0 && type>0) { if(type>0) { LOGD("___ set slave addr: %d\n", addr); cas->addr = addr; g_modbus_set_slave(&cas->m, addr); cascade_slave_map_init(cas); } else { cas->addr = 0; } cas->inited = 1; } else { LOGE("___ mb init failed, %s\n", modbus_strerror(errno)); } return 0; } static int mb_deinit(cascade_handle_t *cas) { g_modbus_deinit(&cas->m); return 0; } static int _mb_read(cascade_handle_t *cas, int addr, uint16_t reg, uint16_t *data, int cnt) { return g_modbus_read_x_reg(&cas->m, addr, reg, cnt, data); } static int _mb_write(cascade_handle_t *cas, int addr, uint16_t reg, uint16_t *data, int cnt) { return g_modbus_write_x_reg(&cas->m, addr, reg, cnt, data); } static int _mb_recv(cascade_handle_t *cas, uint8_t *buf) { return g_modbus_receive(&cas->m, buf); } static int _mb_reply(cascade_handle_t *cas, uint8_t *buff, int reqlen, modbus_mapping_t *map) { return g_modbus_reply(&cas->m, buff, reqlen, map); } //////////////////////////////////////////////////////////// static void print_data(uint8_t *data, int len) { int i; for(i=0; iobj); LOGD("__%s__ cmd.cmd: %d\n", s, cmd->cmd); LOGD("__%s__ cmd.chId: %d\n", s, cmd->chId); //LOGD("__%s__ cmd.time_s: %s\n", s, cmd->time_s); //LOGD("__%s__ cmd.time_e: %s\n", s, cmd->time_e); LOGD("\n"); } static void memswap(uint8_t *buf, int len) { int i; uint8_t tmp; for(i=0; iaddr = data[0]; h->func = data[1]; h->reg = data[2]<<8 | data[3]; h->regcnt = data[4]<<8 | data[5]; h->dlen = 0; h->data = NULL; if(datalen>8) { h->dlen = data[6]; h->data = data+7; memswap(h->data, h->dlen+h->dlen%2); } else { h->dlen = 2; h->data = &data[4]; } return 0; } static int mb_read(cascade_handle_t *cas, int addr, data_t *d) { int r=0,finish=0; int xlen,rlen=0,oncelen=MB_MAX_LEN; uint8_t buff[MODBUS_RTU_MAX_ADU_LENGTH]; if(d->dlen<=0) { //LOGE("___ mb_read dlen %d is wrong!\n", d->dlen); return -1; } LOGD("___ mb_read dlen: %d\n", d->dlen); while(1) { if(rlen+oncelen>d->dlen) { xlen = d->dlen-rlen; } else { xlen = oncelen; } xlen += xlen%2; r = _mb_read(cas, addr, CASCADE_REG_READ, buff, xlen/2); if(r<0) { LOGE("___ _mb_read failed, %s, rlen: %d\n", modbus_strerror(errno), rlen); return -1; } if(rlen+r*2>=d->dlen) { xlen = d->dlen-rlen; finish = 1; } else { xlen = r*2; } memcpy((char*)d->data+rlen, buff, xlen); rlen += xlen; if(finish) { break; } } return 0; } static int mb_write(cascade_handle_t *cas, int addr, data_t *d) { int r=0; int xlen,wlen=0,oncelen=MB_MAX_LEN; uint8_t buff[MODBUS_RTU_MAX_ADU_LENGTH]; if(d->dlen<=0) { //LOGE("___ mb_write dlen %d is wrong!\n", d->dlen); return -1; } LOGD("___ mb_write dlen: %d\n", d->dlen); while(1) { if(wlen+oncelen>d->dlen) { xlen = d->dlen-wlen; } else { xlen = oncelen; } xlen += xlen%2; memcpy(buff, d->data+wlen, xlen); r = _mb_write(cas, addr, CASCADE_REG_WRITE, buff, xlen/2); if(r<0) { //LOGE("___ _mb_write, addr: %d, reg: %d, cnt: %d\n", addr, CASCADE_REG_WRITE, xlen/2); LOGE("___ _mb_write failed, errno: %d, %s\n", errno, modbus_strerror(errno)); return -1; } if(wlen+r*2>=d->dlen) { break; } else { xlen = r*2; } wlen += xlen; } return 0; } static int mb_write_read(cascade_handle_t *cas, int addr, data_t *wd, data_t *rd) { int r=0; r = mb_write(cas, addr, wd); if(r==0) { r = mb_read(cas, addr, rd); } return r; } static int mb_receive(cascade_handle_t *cas) { int r=0,rlen=0; mb_hdr_t h; board_info_t info; modbus_mapping_t *map=NULL; uint8_t buff[MODBUS_RTU_MAX_ADU_LENGTH]; static int precmd=-1; static int sendlen=0; r = _mb_recv(cas, buff); if(r<0) { return -1; } mb_hdr(buff, r, &h); #if 1 //do not know why slave can receive all address data if(h.addr>0 && h.addr!=cas->addr) { return -1; } #endif //LOGD("____ slave recv, reg: %d\n", h.reg); //如果是非自定义寄存器则跳出 if(h.reg==CASCADE_REG_READ || h.reg==CASCADE_REG_WRITE) { if(h.data) { cmd_data_t *cmd = (cmd_data_t*)h.data; cas->cmd = *cmd; precmd = cmd->cmd; sendlen = 0; } if(h.reg==CASCADE_REG_WRITE) { LOGD("____ CASCADE_REG_WRITE, %d\n", cas->cmd.cmd); switch(cas->cmd.cmd) { case CASCADE_CMD_OPEN: case CASCADE_CMD_CLOSE: { int i,t=0; char buff[80]; board_info_t *info=&cas->info; for(i=0; icnt; i++) { if(info->board[i].addr>0) { t = g_switch_set_all_ctrl(&get_dm()->_globalRelaySampManger, info->board[i].type, info->board[i].addr, (cas->cmd.cmd==CASCADE_CMD_OPEN)?1:0); if(t) { LOGE("___ %d %s failed\n", info->board[i].addr, (cas->cmd.cmd==CASCADE_CMD_OPEN)?"open":"close"); } } } if(cas->cmd.cmd==CASCADE_CMD_OPEN) { sprintf(buff,"$开启$|$所有$|$通道$"); } else { sprintf(buff,"$关闭$|$所有$|$通道$"); } dev_insert_alarm_ctrl(get_dm()->db,get_dm()->_global_device_info->product_id,3,buff); } break; case CASCADE_CMD_SAVE: case CASCADE_CMD_SAVE3: { slave_save(cas); } break; } r = _mb_reply(cas, buff, r, cas->map2); } else { if(h.regcnt==1) { LOGD("____ CASCADE SCAN\n"); r = _mb_reply(cas, buff, r, cas->map2); } else { LOGD("____ CASCADE_REG_READ %d\n", cas->cmd.cmd); switch(cas->cmd.cmd) { case CASCADE_CMD_GET_INFO: { LOGD("_____ slave CASCADE_CMD_GET_INFO\n"); slave_get_info(cas, 0); //hardread will cost long time memcpy(cas->map2->tab_registers+(h.reg-CASCADE_REG_OFFSET), (char*)&cas->info, h.regcnt*2); } break; case CASCADE_CMD_QUERY_CH: { LOGD("___ slave CASCADE_CMD_QUERY_CH\n"); if(cas->cmd.obj==OBJ_OVERALL){ slave_get_all_data(cas); memcpy(cas->map2->tab_registers+(h.reg-CASCADE_REG_OFFSET), ((char*)&cas->pwrInfo.info)+sendlen, h.regcnt*2); } else { return -1; } } break; case CASCADE_CMD_QUERY_VOL:break; case CASCADE_CMD_QUERY_CUR:break; case CASCADE_CMD_QUERY_PWR:break; case CASCADE_CMD_QUERY_PWRQ:break; case CASCADE_CMD_QUERY_HIS:break; case CASCADE_CMD_QUERY_TOTAL:break; case CASCADE_CMD_QUERY_TOTAL_PWR:break; } r = _mb_reply(cas, buff, r, cas->map2); if(r>0) { sendlen += h.regcnt*2; //LOGD("____ slave sendlen: %d, h.dlen: %d, r: %d\n", sendlen, h.dlen, r); } } } } else { Modbus_Manger *mm=&get_dm()->_globalRelaySampManger; LOGD("___ slave XXXXXXXXXXX\n"); if(h.func==MODBUS_FC_READ_HOLDING_REGISTERS) { cascade_slave_read(cas, h.reg, h.regcnt); } else if(h.func==MODBUS_FC_WRITE_SINGLE_REGISTER) { cascade_slave_write(cas, h.reg, h.regcnt); } r = _mb_reply(cas, buff, r, cas->map); } return r ; } ///////////////////////////////////////////////////////////////////////// static int cascade_scan(cascade_handle_t *cas) { int i,r=0 ; uint16_t tmp[10]; if(cas->scanAddr>CASCADE_MAX) { cas->scanAddr = 1; } if(!slave_find(cas, cas->scanAddr)) { r = _mb_read(cas, cas->scanAddr, CASCADE_REG_READ, tmp, 1); if(r>0) { LOGD("____ find a slave, addr: %d\n", cas->scanAddr); slave_add(cas, cas->scanAddr); } else { LOGW("____ scan %d fail, %s\n", cas->scanAddr, modbus_strerror(errno)); } } cas->scanAddr++; //print_slave(cas); return 0; } static void power_init(void) { int nGroups=18,chn=1; GlobalDeviceManager *dm=get_dm(); GlobalDeviceManager *dm2=get_dm2(); dm2->_global_device_info = (GlobalDeviceInfo*)malloc(sizeof(GlobalDeviceInfo)); dm2->_global_device_info->product_pwr_type = SmartPDU_AC; dm2->_global_device_info->product_id = 1; //dm2->_global_device_info->product_type_id = 2; strcpy(dm2->_global_device_info->product_name, dm->_global_device_info->product_name); strcpy(dm2->_global_device_info->product_number, dm->_global_device_info->product_number); strcpy(dm2->_global_device_info->product_status, dm->_global_device_info->product_status); INIT_LIST_HEAD(&dm2->_globalPowerManger.list); } static int power_clear(cascade_handle_t *cas) { GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm2=get_dm2(); list_for_each_entry(tmp, &dm2->_globalPowerManger.list, list) { if(tmp) { if(tmp->global_over_manager) { free(tmp->global_over_manager); } list_del(&tmp->list); free(tmp); } } return 0; } static int power_add(cascade_handle_t *cas) { int i,j,nGroups=18,chn=1; GlobalDeviceManager *dm2=get_dm2(); GlobalPowerManger* pm=NULL; board_info_t *info=&cas->info; LOGD("__**___ master add channel to the list, cnt: %d\n", info->cnt); cascade_lock(); power_clear(cas); for(i=0; icnt; i++) { pm = (GlobalPowerManger*)calloc(1, sizeof(GlobalPowerManger)); if(!pm) { return -1; } pm->product_id = dm2->_global_device_info->product_id; pm->product_saddr = info->board[i].addr; pm->product_ch_id = i; pm->product_ch_addr = info->board[i].ch_addr; sprintf(pm->product_ch_name,"CH%d",pm->product_ch_id); pm->product_ch_type = info->board[i].type; pm->product_ch_status = 0; pm->product_ch_start_delay = 1000 * (chn%nGroups!=0?chn%nGroups:nGroups); pm->product_ch_stop_delay = 1000 * (chn%nGroups!=0?chn%nGroups:nGroups); list_add_tail(&pm->list,&dm2->_globalPowerManger.list); chn++; } cascade_unlock(); return 0; } static int power_overall_update(cascade_handle_t *cas) { GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm2=get_dm2(); _OverAllPwrAckInfo *info=&cas->allInfo; if (dm2->_global_device_info->product_pwr_type == SmartPDU_Tree_AC_Tree || dm2->_global_device_info->product_pwr_type == SmartPDU_Tree_AC_One) { dev_search_latest_t_ac_power_statistic_info(0, 0, info); dev_search_latest_t_ac_power_statistic_info(0, 1, info); dev_search_latest_t_ac_power_statistic_info(0, 2, info); } else { GlobalPowerInfo pwrInfo; dev_search_latest_power_info(dm2->db, dm2->_global_device_info->product_id, 0, &pwrInfo); info->voltage = pwrInfo._power_info.voltage ; info->current = pwrInfo._power_info.current ; info->power = pwrInfo._power_info.power ; info->freq = pwrInfo._power_info.freq ; info->consumption = pwrInfo._power_info.consumption ; info->factor = pwrInfo._power_info.factor ; } return 0; } static int power_ch_update(cascade_handle_t *cas) { int cnt=0; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm2=get_dm2(); PowerInfo *info=cas->pwrInfo.info; list_for_each_entry(tmp, &dm2->_globalPowerManger.list, list) { if(cnt>cas->pwrInfo.cnt) { break; } tmp->_PowerInfo = info[cnt]; cnt++; } return 0; } static void print_sensor(char *s, sensor_data_t *ss) { LOGD("__%s__ ss.type: %d\n", s, ss->type); LOGD("__%s__ ss.addr: %d\n", s, ss->addr); LOGD("__%s__ ss.voltage: %f\n", s, ss->pwr.voltage); LOGD("__%s__ ss.current: %f\n", s, ss->pwr.current); LOGD("__%s__ ss.power: %f\n", s, ss->pwr.power); LOGD("__%s__ ss.consumption: %f\n", s, ss->pwr.consumption); LOGD("__%s__ ss.freq: %f\n", s, ss->pwr.freq); LOGD("__%s__ ss.factor: %f\n", s, ss->pwr.factor); LOGD("__%s__ ss.status: %d\n", s, ss->pwr.status); LOGD("__%s__ ss.temprature: %f\n", s, ss->temprature); LOGD("__%s__ ss.humidity: %f\n", s, ss->humidity); LOGD("__%s__ ss.warning: %d\n", s, ss->warning); LOGD("__%s__ ss.power_status: %d\n", s, ss->power_status); LOGD("__%s__ ss.sensor_status: %d\n", s, ss->sensor_status); LOGD("\n"); } #define VALUE_OF(m,a,b) ((m[a]<<16)+m[b]) static int power_get(cascade_handle_t *cas, int addr, sensor_data_t *ss) { uint32_t offset = 6000; uint32_t value = 0 ; uint16_t temp[100]; int r,cnt = sizeof(sensor_ori_t)/2; r = _mb_read(cas, addr, offset, temp, cnt); if(r!=cnt) { LOGE("___mbus_read slave %d failed, %s\n", addr, modbus_strerror(errno)); return -1; } ss->type = temp[0]; ss->addr = temp[1]; ss->pwr.voltage = VALUE_OF(temp,3,2)/1000.0; ss->pwr.current = VALUE_OF(temp,5,4)/1000.0; ss->pwr.power = VALUE_OF(temp,7,6)/1000.0; ss->pwr.consumption = VALUE_OF(temp,9,8)/1000.0; ss->pwr.freq = VALUE_OF(temp,11,10)/1000.0; ss->pwr.factor = VALUE_OF(temp,13,12)/1000.0; ss->pwr.status = temp[20]; ss->temprature = VALUE_OF(temp,15,14)/1000.0; ss->humidity = VALUE_OF(temp,17,16)/1000.0; ss->warning = VALUE_OF(temp,19,18)/1000.0; ss->sensor_status = temp[21]; //print_sensor("11", ss); return 0; } #define REGS(x) (((x)+(x)%2)/2) static int power_query() { } static int master_request(cascade_handle_t *cas, cmd_data_t *cmd) { int i,r; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm=get_dm(); GlobalDeviceManager *dm2=get_dm2(); GlobalDeviceInfo *dev=&dm2->_global_device_info; data_t rdata,wdata; if(cur_dev_addr==0) { return -1; } switch(cmd->cmd) { case CASCADE_CMD_OPEN: case CASCADE_CMD_CLOSE: case CASCADE_CMD_SAVE: case CASCADE_CMD_SAVE3: { wdata.dlen = sizeof(*cmd); wdata.data = (uint8_t*)cmd; r = mb_write(&cas->m, cur_dev_addr, &wdata); } break; case CASCADE_CMD_GET_INFO: { wdata.dlen = sizeof(*cmd); wdata.data = (uint8_t*)cmd; rdata.dlen = sizeof(cas->info); rdata.data = (uint8_t*)&cas->info; LOGD("_____ master send CASCADE_CMD_GET_INFO\n"); r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { power_add(cas); } else { LOGE("_____ master request CASCADE_CMD_GET_INFO failed\n"); } } break; default: return -1; } return r; } static int master_query(cascade_handle_t *cas) { int i,r; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm2=get_dm2(); GlobalDeviceInfo *dev=&dm2->_global_device_info; _OverChnPwrAckInfo chInfo; _OverAllPwrAckInfo allInfo; cmd_data_t *cmd=&cas->cmd; data_t rdata,wdata; if(cur_dev_addr==0) { return -1; } #if 0 //add for test cmd->obj = OBJ_OVERALL; cmd->cmd = CASCADE_CMD_QUERY_CH; for(i=0; ich[i].addr = i+1; cmd->ch[i].ch_type = 8; } cmd->chId = 44; strcpy(cmd->time_s, "123456789 ABCDEFGH"); strcpy(cmd->time_e, "2222/22/22 11:11:11"); print_cmd("master", cmd); #endif wdata.dlen = sizeof(*cmd); wdata.data = (uint8_t*)cmd; switch(cmd->cmd) { case CASCADE_CMD_QUERY_CH: { LOGD("____ master query CASCADE_CMD_QUERY_CH\n"); if(cmd->obj==OBJ_OVERALL || cmd->obj==OBJ_CHANNEL) { rdata.dlen = sizeof(PowerInfo)*cas->info.cnt; rdata.data = (uint8_t*)&cas->pwrInfo.info; r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); LOGD("____ master mb_write_read CASCADE_CMD_QUERY_CH %d\n", r); if(r==0) { power_ch_update(cas); } } else { return -1; } } break; case CASCADE_CMD_QUERY_VOL: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_CUR: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_PWR: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_PWRQ: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_HIS: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_TOTAL: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_TOTAL_PWR: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; default: return -1; } return r; } static int slave_receive(cascade_handle_t *cas) { return mb_receive(cas); } static void* cascade_thread(void *arg) { int r; thread_handle_t *h=(thread_handle_t*)arg; cascade_handle_t *cas=(cascade_handle_t*)h->arg; ModbusInfo_t *info=get_mb(); LOGD("__ cascade %s\n", info->product_modbus_type?"slave":"master"); while(h->quit==0) { if(info->product_modbus_type==0) { //主模 r = master_query(cas); sleep(5); } else { //从模式,等待主设备发起数据请�? r = slave_receive(cas); } } pthread_exit(NULL); } static void* scan_thread(void *arg) { int r; thread_handle_t *h=(thread_handle_t*)arg; cascade_handle_t *cas=(cascade_handle_t*)h->arg; while(h->quit==0) { if(get_mb()->product_modbus_type==0) { //master r = cascade_scan(cas); } sleep(1); } pthread_exit(NULL); } static int set_modbus(cascade_handle_t *cas, ModbusInfo_t *info) { int r; if(cas->inited) { mb_deinit(cas); } cas->inited = 0; LOGD("master init modbus: port: %s, type: %d, baud: %d\n", INTERL_485_CASCADE_PORT, info->product_modbus_type, info->product_modbus_baud); r = mb_init(cas, INTERL_485_CASCADE_PORT, info->product_modbus_type, info->product_modbus_addr, info->product_modbus_baud); if(r!=0) { LOGE("cascade modbus init error.\n"); return -1; } cas->inited = 1; return 0; } int cascade_init(void) { int r=0; cascade_handle_t *cas=&casHandle; memset(cas, 0, sizeof(casHandle)); power_init(); slave_init(cas); pthread_mutex_init(&cas->mutex, NULL); cas->scanAddr = 1; cas->pwrInfo.info = malloc(128*sizeof(PowerInfo)); //cas->map = modbus_mapping_new(0,0,MAX_READ_REGS,MAX_WRITE_REGS); cas->map2 = modbus_mapping_new_start_address(0,0,0,0, CASCADE_REG_READ, MAX_READ_REGS2, CASCADE_REG_WRITE, MAX_WRITE_REGS2); set_modbus(cas, get_mb()); slave_add(cas, 0); thread_start(THREAD_ID_CASCADE, cascade_thread, cas, 4*MB, 0); thread_start(THREAD_ID_SCAN, scan_thread, cas, 4*MB, 0); return 0; } int cascade_set_modbus(ModbusInfo_t *info) { cascade_handle_t *cas=&casHandle; if(!info || info->product_modbus_type>1 || info->product_modbus_addr>CASCADE_MAX) { return -1; } return set_modbus(cas, info); } int cascade_get_dlist(dev_list_t *dl) { int i,cnt=0; slave_t *sl=NULL; cascade_handle_t *cas=&casHandle; if(!dl) { return -1; } sl = (slave_t*)malloc(sizeof(slave_t)*(CASCADE_MAX+1)); if(!sl) { return -1; } for(i=0; i<=CASCADE_MAX; i++) { if(cas->slaves[i].addr>=0) { sl[cnt++] = cas->slaves[i]; } } dl->slave = sl; dl->cnt = cnt; return 0; } int cascade_free_dlist(dev_list_t *dl) { if(!dl) { return -1; } free(dl->slave); return 0; } int cascade_request(cmd_data_t *cmd) { int r=0; cascade_handle_t *cas=&casHandle; if(!cmd) { return -1; } if(cmd->cmd==CASCADE_CMD_QUERY_CH) { cmd_data_t cmd2=*cmd; cmd2.cmd = CASCADE_CMD_GET_INFO; r = master_request(cas, &cmd2); } if(r==0) { cas->cmd = *cmd; r = master_request(cas, cmd); } return r; } int cascade_is_offline(int addr) { slave_t *sl=slave_get(&casHandle, addr); return (sl->addr>=ERR_MAX)?1:0; } int cascade_lock(void) { cascade_handle_t *cas=&casHandle; return pthread_mutex_lock(&cas->mutex); } int cascade_unlock(void) { cascade_handle_t *cas=&casHandle; return pthread_mutex_unlock(&cas->mutex); }