#include "cascade.h" #include "mb.h" #include "lock.h" #include "list.h" #include "modbus.h" #include #include #include "pthread.h" #include "stdio.h" #include "string.h" #include "power.h" #include "paras.h" #include "thread.h" #define REGS(x) (((x)+(x)%2)/2) typedef void * handle_t; typedef struct { mb_inst_t *hinst; uint8_t mode; uint8_t type; rt_thread_t tid; uint8_t quit; }mb_handle_t; typedef struct { union { md_ac_dc_t ac_dc; md_3_ac_t ac_3; }data; }north_data_t; typedef union{ slave_info_t info; north_data_t north; }cascade_data_cache; typedef struct cascade_info{ uint8_t switch_flag; uint8_t saddr; uint8_t read_addr; uint8_t md_type; uint32_t bund; uint8_t quit; //slave_info_t *info; lock_t lock; slave_t slaves[POWER_CASCADE_MAX+1]; cmd_data_t cmd; power_all_t all; //north_data_t *north; cascade_data_cache *chache; }cascade_handle_t; static int sendlen=0; //级联读取offset static cascade_handle_t slave_info = {0}; //自维护全局变量 static mb_cascade_fun_t func = {0}; //匹配mdbus 回调函数 const mb_cb_table_t mb_table = { .read_disc = mb_port_read_disc, //读离散量输入 .read_coil = mb_port_read_coil, //读线圈 .write_coil = mb_port_write_coil, //写线圈 .read_input = mb_port_read_input, //读输入寄存器 .read_hold = mb_port_read_hold, //读保持寄存器 .write_hold = mb_port_write_hold, //写保持寄存器 }; static int mb_write_read(cascade_handle_t *cas, int addr, data_t *wd, data_t *rd); static int master_query(cascade_handle_t *cas); static void slave_func(uint16_t reg,void *r_w_data,uint32_t lenth); static int slave_get_info(cascade_handle_t *cas); static int master_cmd(cascade_handle_t *cas,uint8_t cur_dev_addr ,cmd_data_t *cmd); static void slave_rm(uint8_t addr); static void memswap(uint8_t *buf, int len); static void * my_memcpy_byte(void *dst, const void *src, int n); static uint8_t master_scan(cascade_handle_t *cas); static int _mb_write(cascade_handle_t *cas, int addr, data_t *d); static int _mb_read(cascade_handle_t *cas, int addr, data_t *d); static void* off_on_thread(void *arg); //主机控制从机开关线程 static void memswap(uint8_t *buf, int len) { int i; uint8_t tmp; for(i=0; i 0 && addr < POWER_SLAVE_CH_MAX) { slave_info.slaves[addr].addr = 0; slave_info.slaves[addr].err = 0; } } static uint8_t master_scan(cascade_handle_t *cas) { static uint8_t slave_addr = 1; if(slave_addr > POWER_CASCADE_MAX) { slave_addr = 1; } if(cas->slaves[slave_addr].addr == 0) { //scan uint16_t value = 0; lock_on(cas->lock); int r = mb_read(MB_ID_CASCADE,slave_addr,CASCADE_REG_SCAN,&value,1,300); lock_off(cas->lock); if(r > 0) { LOGD("scan slave addr %d !!!\n",slave_addr); cas->slaves[slave_addr].addr = slave_addr; cas->slaves[slave_addr].err = 0; } } slave_addr++; } static int slave_get_info(cascade_handle_t *cas) { slave_info_t *info = &cas->chache->info; power_all_t all; power_data_get(&all); info->channels = all.chs-1 > 0 ? all.chs-1 : all.chs; if(info->channels > POWER_SLAVE_CH_MAX) info->channels = POWER_SLAVE_CH_MAX; if(info->channels == 0) return -1; for(int i=0; i < info->channels;i++) { info->ch[i] = all.pch[i+1]; } LOGD("slave will send %d channels to master!!!!\n",info->channels); return 0; } static void *my_memcpy_byte(void *dst, const void *src, int n) { if (dst == NULL || src == NULL || n <= 0) return NULL; char * pdst = (char *)dst; char * psrc = (char *)src; if (pdst > psrc && pdst < psrc + n) { pdst = pdst + n - 1; psrc = psrc + n - 1; while (n--) *pdst-- = *psrc--; } else { while (n--) *pdst++ = *psrc++; } return dst; } static void slave_func(uint16_t reg,void *r_w_data,uint32_t lenth) { cmd_data_t *cmd=NULL; pthread_t id = 0; power_all_t all; power_data_get(&all); switch (reg) { case CASCADE_REG_SCAN: break; case CASCADE_REG_WRITE: { cmd = (cmd_data_t*)(r_w_data); if(cmd->cmd>=CASCADE_CMD_GET_INFO) { //slave_info.cmd = *cmd; memcpy(&slave_info.cmd,r_w_data,sizeof(cmd_data_t)); sendlen = slave_info.cmd.c_m.sendlen_offset; } //LOGD("____write_____ %d\n",lenth); // sendlen = 0; switch(cmd->cmd) { case CASCADE_CMD_OPEN: case CASCADE_CMD_CLOSE: { cmd_data_t *pcmd=malloc(sizeof(cmd_data_t)); if(pcmd) { *pcmd = *cmd; pthread_create(&id,NULL,off_on_thread,pcmd); pthread_detach(id); } } break; case CASCADE_CMD_OPEN_NF: case CASCADE_CMD_CLOSE_NF: { } break; case CASCADE_CMD_SAVE: case CASCADE_CMD_SAVE3: { } break; case CASCADE_CMD_BREAKER_SAVE_ADD: { } break; case CASCADE_CMD_BREAKER_SAVE_UPDATE: { } break; case CASCADE_CMD_BREAKER_SAVE_DELETE: { } break; } } break; case CASCADE_REG_READ: { cmd = &slave_info.cmd; switch(cmd->cmd) { case CASCADE_CMD_GET_INFO: { uint8_t * base_addr = (uint8_t *)&all.pch[1]; //my_memcpy_byte(r_w_data,base_addr+sendlen,lenth*2); memcpy(r_w_data,base_addr+sendlen,lenth*2); memswap(r_w_data,lenth*2); LOGD("____read_____ readlen = %d,sendlen = %d power_ch_t size=%d\n",lenth,sendlen,sizeof(power_ch_t)); } break; case CASCADE_CMD_QUERY_CH: { uint8_t * base_addr = (uint8_t *)&all.pch[1]; my_memcpy_byte(r_w_data,base_addr+sendlen,lenth*2); memswap(r_w_data,lenth*2); } break; case CASCADE_CMD_BREAKER_QUERY: 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; case CASCADE_CMD_BREAKER_GET_INFO:break; } //sendlen += lenth*2; } break; default: { } break; } } static int _mb_write(cascade_handle_t *cas, int addr, data_t *d) { int i = 0,r=0,timeout=0; int wl,xlen,wlen=0,oncelen=250; uint8_t retry = 5; uint8_t buff[MB_BUF_SIZE+100]; if(d->dlen<=0) { return -1; } lock_on(cas->lock); for(;i < retry;i++) { while(1) { if(wlen+oncelen>d->dlen) { xlen = d->dlen-wlen; } else { xlen = oncelen; } xlen += xlen%2; memcpy(buff, d->data+wlen, xlen); //交换数据 memswap(buff,xlen%2+xlen); wl = mb_write(MB_ID_CASCADE, addr, CASCADE_REG_WRITE, (uint16_t*)buff, xlen/2); if(wl<=0) { LOGE("___ _mb_write failed, addr: %d, reg: %d, cnt: %d, %s, retry: %d errno = %d \n", addr, CASCADE_REG_WRITE, xlen/2,"write failed",i+1,wl); if(addr >0 && addr < POWER_SLAVE_CH_MAX) { slave_info.slaves[addr].err ++; if(slave_info.slaves[addr].err > 5) { slave_rm(addr); } } r = -1; break; }else { slave_info.slaves[addr].err = 0; r = 0; } if(wlen+wl*2>=d->dlen) { break; }else { xlen = wl*2; } wlen += xlen; } if(r == 0) break; } lock_off(cas->lock); return r; } static int _mb_read(cascade_handle_t *cas, int addr, data_t *d) { int i=0,r=0,finish=0,timeout=0; int rl,xlen,rlen=0,oncelen=250; uint8_t retry = 5; uint16_t buff[MB_BUF_SIZE]; if(d->dlen<=0) { return -1; } lock_on(cas->lock); for(i =0;i < retry;i++) { while(1) { if(rlen+oncelen>d->dlen) { xlen = d->dlen-rlen; }else{ xlen = oncelen; } xlen += xlen%2; rl = mb_read(MB_ID_CASCADE, addr, CASCADE_REG_READ, buff, xlen/2,100); if(rl<=0) { LOGE("___ _mb_read failed, %s, rlen: %d, retry: %d\n", "read error", rlen, i+1); if(addr >0 && addr < POWER_SLAVE_CH_MAX) { cas->slaves[addr].err ++; if(cas->slaves[addr].err > 5) { slave_rm(addr); } } r = -1; break; }else { cas->slaves[addr].err =0; } if(rlen+rl*2>=d->dlen) { xlen = d->dlen-rlen; finish = 1; }else { xlen = rl*2; } memcpy((char*)d->data+rlen, buff, xlen); rlen += xlen; if(finish) { r = 0; break; } } if(r==0) break; } lock_off(cas->lock); return r; } 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_write_read_n(cascade_handle_t *cas, int addr, data_t *wd, data_t *rd) { int i=0,r=0,finish=0,timeout=0; int rl,xlen,rlen=0,oncelen=250; uint16_t buff[MB_BUF_SIZE]; while(1) { //set sendlen = rlen; cas->cmd.c_m.sendlen_offset = rlen; wd->dlen = sizeof(cmd_data_t); wd->data = (uint8_t*)&(cas->cmd); r = _mb_write(cas, addr,wd); //set need transport len if(rlen+oncelen>rd->dlen) { xlen = rd->dlen-rlen; }else{ xlen = oncelen; } xlen += xlen%2; lock_on(cas->lock); while(1) { rl = mb_read(MB_ID_CASCADE, addr, CASCADE_REG_READ, buff, xlen/2,200); if(rl<=0) { if(addr >0 && addr < POWER_SLAVE_CH_MAX) { cas->slaves[addr].err ++; LOGE("___ _mb_read failed, %s, rlen: %d, retry: %d ernno=%d\n", "read error", rlen, cas->slaves[addr].err,rl); if(cas->slaves[addr].err > 5) { slave_rm(addr); lock_off(cas->lock); goto fail; } }else { lock_off(cas->lock); goto fail; } }else { cas->slaves[addr].err =0; break; } } lock_off(cas->lock); if(rlen+rl*2>=rd->dlen) { xlen = rd->dlen-rlen; finish = 1; }else { xlen = rl*2; } memcpy((char*)rd->data+rlen, buff, xlen); rlen += xlen; if(finish) { r = 0; break; } } fail: return r; } static void* off_on_thread(void *arg) { cascade_handle_t *cas=&slave_info; cmd_data_t *pcmd=(cmd_data_t*)arg; if(pcmd->cmd==CASCADE_CMD_OPEN) { // LOGD("____ slave CASCADE_CMD_OPEN\n"); } else { // LOGD("____ slave CASCADE_CMD_CLOSE\n"); } int flag=((pcmd->cmd==CASCADE_CMD_OPEN)?1:0); if(pcmd->chId == 0xff) { // all }else { //one } if(pcmd->cmd==CASCADE_CMD_OPEN) { // sprintf(temp,"$开启$|$所有$|$通道$"); } else { // sprintf(temp,"$关闭$|$所有$|$通道$"); } //data base free(pcmd); pthread_exit(NULL); } static int master_cmd(cascade_handle_t *cas,uint8_t cur_dev_addr ,cmd_data_t *cmd) { int i,r; 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: case CASCADE_CMD_OPEN_NF: case CASCADE_CMD_CLOSE_NF: { LOGD("____ master CMD: %d\n", cmd->cmd); wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; r = _mb_write(cas, cur_dev_addr, &wdata); } break; case CASCADE_CMD_GET_INFO: { wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; // rdata.dlen = sizeof(slave_info_t)-sizeof(power_ch_t)*POWER_SLAVE_CH_MAX; // rdata.data = (uint8_t*)cas->info; uint16_t value = 0; r = mb_read(MB_ID_CASCADE,cur_dev_addr,4000,&value,1,100);//获取通道数 //r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); LOGD("r = %d value=%d\n",r,value); if(r == 1) { uint8_t chanels = value & 0xff; if(chanels == 0 || chanels > 100) { cas->chache->info.channels = 0; LOGD("get slave channels %d!!!\n",chanels); }else { if(chanels >= POWER_SLAVE_CH_MAX) chanels = POWER_SLAVE_CH_MAX; cas->chache->info.channels = chanels; //rdata.dlen = sizeof(slave_info_t) -sizeof(power_ch_t)*(POWER_SLAVE_CH_MAX - cas->info.channels); rdata.dlen = sizeof(power_ch_t)*cas->chache->info.channels; rdata.data = (uint8_t*)&(cas->chache->info.ch); r = mb_write_read_n(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { }else { LOGE("_____ master CASCADE_CMD_GET_INFO read failed\n"); } } } // if(r==0) { // rdata.dlen = sizeof(slave_info_t)-sizeof(power_ch_t)*(POWER_SLAVE_CH_MAX - cas->info.channels); // rdata.data = (uint8_t*)&cas->info; // r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); // if(r==0) { // }else // { // LOGE("_____ master CASCADE_CMD_GET_INFO read failed\n"); // } // } // else { // LOGE("_____ master CASCADE_CMD_GET_INFO failed\n"); // } } break; case CASCADE_CMD_BREAKER_GET_INFO: { } break; case CASCADE_CMD_BREAKER_SAVE_UPDATE: case CASCADE_CMD_BREAKER_SAVE_DELETE: case CASCADE_CMD_BREAKER_SAVE_ADD: { } break; default: cas->cmd = *cmd; r = 0; } return r; } uint8_t cascade_init(void) { paras_data_t* p_d = paras_get(); memset(&slave_info,0,sizeof(slave_info)); slave_info.quit = 1; slave_info.lock = lock_init(); slave_info.md_type = p_d->cas.mode; slave_info.chache = (cascade_data_cache *) malloc(sizeof(cascade_data_cache)); if(slave_info.chache == NULL) { lock_deinit(slave_info.lock); return -1; } LOGD("__casecde__malloc size if cascade %d\n",sizeof(cascade_data_cache)); if(p_d->cas.mode == MB_MODE_SLAVE) { mb_set_addr(MB_ID_CASCADE,p_d->cas.addr); mb_set_cb(MB_ID_CASCADE, &mb_table); func.slave_func = slave_func; mb_set_cascade_cb(MB_ID_CASCADE,&func); memset(&slave_info.chache->north,0,sizeof(north_data_t)); }else if(p_d->cas.mode == MB_MODE_MASTER) { memset(&slave_info.chache->info,0,sizeof(slave_info_t)); }else { LOGE("cascede mode type is err ____ %d!!!\n",p_d->cas.mode); free(slave_info.chache); slave_info.chache = 0; return -1; } slave_info.quit = 0; slave_info.read_addr = 1; LOGD("scan thread!!!\n"); thread_start(THREAD_ID_CAS_SCAN,cascade_scan_thread,NULL); sleep(1); LOGD("cascade thread!!!\n"); thread_start(THREAD_ID_CAS_TH,cascade_thread,NULL); return 0; } void cascade_reset(uint8_t mode,uint8_t addr) { slave_info.switch_flag = 1; paras_data_t* p_d = paras_get(); if((p_d->cas.mode == MB_MODE_MASTER) && (slave_info.md_type != MB_MODE_MASTER)) { slave_info.md_type = MB_MODE_MASTER; memset(&slave_info.chache->info,0,sizeof(slave_info_t)); }else if((p_d->cas.mode == MB_MODE_SLAVE) && (slave_info.md_type != MB_MODE_SLAVE)) { slave_info.md_type = MB_MODE_SLAVE; mb_set_addr(MB_ID_CASCADE,p_d->cas.addr); mb_set_cb(MB_ID_CASCADE, &mb_table); func.slave_func = slave_func; mb_set_cascade_cb(MB_ID_CASCADE,&func); memset(&slave_info.chache->north,0,sizeof(north_data_t)); }else if(p_d->cas.mode == MB_MODE_SLAVE) { mb_set_addr(MB_ID_CASCADE,p_d->cas.addr); }else { return ; } paras_save(); slave_info.switch_flag = 0; } void cascade_scan_thread(void *arg) { while(slave_info.quit == 0) { if(slave_info.switch_flag) { sleep(1); continue; } if(slave_info.md_type == MB_MODE_MASTER) { master_scan(&slave_info); sleep(1); }else //做从机//拷贝数据到北向 { paras_data_t* p_data = paras_get(); power_all_t all; power_data_get(&all); if(p_data->prod.type == PDU_AC_I1O1 || p_data->prod.type == PDU_DC_I1O1) { int channels = all.chs > 0 ? all.chs - 1: 0; slave_info.chache->north.data.ac_dc.dev_cnt = (p_data->prod.type << 8 | channels); int cnt = all.chs > POWER_SLAVE_CH_MAX ? POWER_SLAVE_CH_MAX : channels; //电量信息 for(int i = 0; i < cnt;i++) { slave_info.chache->north.data.ac_dc.power[i].voltage = all.pch[i+1].power[0].voltage *1000; slave_info.chache->north.data.ac_dc.power[i].current = all.pch[i+1].power[0].current *1000; slave_info.chache->north.data.ac_dc.power[i].power = all.pch[i+1].power[0].power *1000; slave_info.chache->north.data.ac_dc.power[i].consumer = all.pch[i+1].power[0].consump *1000; slave_info.chache->north.data.ac_dc.power[i].factor = all.pch[i+1].power[0].factor *1000; slave_info.chache->north.data.ac_dc.power[i].freq = all.pch[i+1].power[0].freq *1000; } //总信息 //slave_info.chache->north.data.ac_dc.power_all. = all.ttl.total; slave_info.chache->north.data.ac_dc.power_all.all_consumer = all.ttl.total[0].consump *1000; slave_info.chache->north.data.ac_dc.power_all.all_current = all.ttl.total[0].current *1000; slave_info.chache->north.data.ac_dc.power_all.all_power = all.ttl.total[0].power *1000; slave_info.chache->north.data.ac_dc.power_all.all_voltage = all.ttl.total[0].voltage *1000; //温湿度 slave_info.chache->north.data.ac_dc.temp = 0; //后续加上传感器数据 slave_info.chache->north.data.ac_dc.humity = 0; for(int i = 0; i < cnt;i++) slave_info.chache->north.data.ac_dc.switch_stu[i] = 0; for(int i = 0; i < cnt;i++) { slave_info.chache->north.data.ac_dc.delay_open[i] = all.pch[i].info.open_delay; } for(int i = 0; i < cnt;i++) { slave_info.chache->north.data.ac_dc.delay_close[i] = all.pch[i].info.close_delay; } }else { int channels = all.chs > 0 ? all.chs - 1: 0; slave_info.chache->north.data.ac_3.dev_cnt = (p_data->prod.type << 8 | channels); for(int i = A_P; i <= C_P;i++) { slave_info.chache->north.data.ac_3.ac_3_all_pw[i].consumer = all.ttl.total[i].consump *1000; slave_info.chache->north.data.ac_3.ac_3_all_pw[i].current = all.ttl.total[i].current *1000; slave_info.chache->north.data.ac_3.ac_3_all_pw[i].power = all.ttl.total[i].power *1000; slave_info.chache->north.data.ac_3.ac_3_all_pw[i].voltage = all.ttl.total[i].voltage *1000; } int cnt = all.chs > POWER_SLAVE_CH_MAX ? POWER_SLAVE_CH_MAX : channels; for(int i = 0; i < cnt;i++) { //总体信息 } for(int i = 0; i < cnt;i++) { for(int j = A_P; j <= C_P;j++) { slave_info.chache->north.data.ac_3.ac_3_chn_p[i][j].p_consumer = all.pch[i+1].power[j].consump * 1000; slave_info.chache->north.data.ac_3.ac_3_chn_p[i][j].p_current = all.pch[i+1].power[j].current * 1000; slave_info.chache->north.data.ac_3.ac_3_chn_p[i][j].p_power = all.pch[i+1].power[j].power * 1000; slave_info.chache->north.data.ac_3.ac_3_chn_p[i][j].p_voltage = all.pch[i+1].power[j].voltage * 1000; slave_info.chache->north.data.ac_3.ac_3_chn_p[i][j].p_status = all.pch[i+1].status; } } for(int i = 0; i < cnt;i++) { slave_info.chache->north.data.ac_3.delay_open[i] = all.pch[i].info.open_delay; } for(int i = 0; i < cnt;i++) { slave_info.chache->north.data.ac_3.delay_close[i] = all.pch[i].info.close_delay; } } //LOGD("cpy data to north user\n"); //slave_get_info(&slave_info); } sleep(1); } } void cascade_thread(void *arg) { LOGD("__ cascade %s\n", (slave_info.md_type==MB_MODE_MASTER)?"master":"slave"); while(slave_info.quit==0) { if(slave_info.switch_flag) { sleep(1); continue; } if(slave_info.md_type==MB_MODE_MASTER) { //主模 cmd_data_t cmd; cmd.cmd = CASCADE_CMD_GET_INFO; cmd.obj = OBJ_OVERALL; slave_info.cmd = cmd; master_cmd(&slave_info,slave_info.read_addr,&cmd); sleep(1); } else { //从模式,等待主设备发起数据请求 mb_slave_poll(MB_ID_CASCADE); } } pthread_exit(NULL); } int cascade_request(cmd_data_t *cmd) { master_cmd(&slave_info,1,cmd); return 0; } int mb_port_read_disc(u16 addr, u8 *pbit)//读离散量输入, 返回 : 0-成功, -2-地址错误 { MB_ASSERT(pbit != NULL); return(-2); } int mb_port_read_coil(u16 addr, u8 *pbit)//读线圈, 返回 : 0-成功, -2-地址错误 { MB_ASSERT(pbit != NULL); return(-2); } int mb_port_write_coil(u16 addr, u8 bit)//写线圈, 返回 : 0-成功, -2-地址错误, -4-设备故障 { return(-2); } int mb_port_read_input(u16 addr, u16 *preg)//读输入寄存器, 返回 : 0-成功, -2-地址错误 { MB_ASSERT(preg != NULL); return(-2); } int mb_port_read_hold(u16 addr, u16 *preg)//读保持寄存器, 返回 : 0-成功, -2-地址错误 { MB_ASSERT(preg != NULL); uint16_t *data = NULL; if( AC_DC_DEV_CHN_REG <= addr && addr <= AC_DC_DRY_REG) { data = (uint16_t*)(&slave_info.chache->north.data.ac_dc); uint32_t offset = addr - AC_DC_DEV_CHN_REG; *preg = *(data+offset); return 0; } if(AC_3_DEV_CHN_REG <= addr && addr <= AC_3_DRY_REG) { data = (uint16_t*)(&slave_info.chache->north.data.ac_3); uint32_t offset = addr - AC_3_DEV_CHN_REG; *preg = *(data+offset); return 0; } return(-2); } int mb_port_write_hold(u16 addr, u16 reg)//写保持寄存器, 返回 : 0-成功, -2-地址错误, -3-值非法, -4-设备故障 { //power_all_t *power = power_data_get(); if(AC_DC_SET_DELAY_OPEN <= addr && addr <= AC_DC_ALL_SET_SWITCH_REG) { switch(addr) { case AC_DC_SET_DELAY_OPEN ... (AC_DC_SET_DELAY_CLOSE-1): { uint16_t channel = addr - AC_DC_SET_DELAY_OPEN; //获取通道控制接口 写入数据 } break; } return 0; } return(-2); } uint8_t cascade_read_slave(uint8_t addr) { memset(&slave_info.chache->info,0,sizeof(slave_info_t)); slave_info.read_addr = addr; } int cascade_power_get(power_all_t *all) { if(!all) { return -1; } all->chs = slave_info.chache->info.channels; all->pch = &slave_info.chache->info.ch[0]; return 0; } int cascade_get_dlist(dev_list_t *dl) { int i,cnt=0; slave_t *sl=NULL; if(!dl) { return -1; } sl = (slave_t*)malloc(sizeof(slave_t)*(POWER_CASCADE_MAX+1)); if(!sl) { return -1; } for(i=0; i<=POWER_CASCADE_MAX; i++) { if(slave_info.slaves[i].addr>=0) { sl[cnt++] = slave_info.slaves[i]; } } dl->slave = sl; dl->cnt = cnt; LOGD("____dev cnt: %d\n", cnt); } int cascade_free_dlist(dev_list_t *dl) { if(!dl) { return -1; } free(dl->slave); return 0; } int cascade_lock(int flag) { cascade_handle_t *h=&slave_info; if(flag) { lock_on(h->lock); } else { lock_off(h->lock); } return 0; }