mbs.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. #include "mbs.h"
  2. #include "appl.h"
  3. enum mbs_idx_t {
  4. MBSIDX_CTN = 0,
  5. };
  6. // 0:cess2000 modbus tcp slave
  7. fmodbus_t *MB[8];
  8. /* ----------------------- Defines ------------------------------------------*/
  9. /* ctn modbus tcp slave*/
  10. #define REG_HOLDING_START_ZH 0x0000
  11. #define REG_HOLDING_NREGS_ZH 0x8000
  12. static USHORT usRegHoldingBuf_ZH[REG_HOLDING_NREGS_ZH] = {0};
  13. #define REG_INPUT_START_ZH 0x0000
  14. #define REG_INPUT_REG_ZH 0x8000
  15. static USHORT usRegInputReg_ZH[REG_INPUT_REG_ZH] = {0};
  16. static enum ThreadState { STOPPED, RUNNING, SHUTDOWN } ePollThreadState;
  17. static pthread_mutex_t xLock = PTHREAD_MUTEX_INITIALIZER;
  18. // static BOOL bDoExit;
  19. void *pvPollingThread(void *pvParameter) {
  20. fmodbus_t *ctx = (fmodbus_t *) pvParameter;
  21. syslog(LOG_INFO, "%s, ++, mbsidx:%d", __func__, ctx->mbsidx);
  22. if (eMBEnable(ctx) == MB_ENOERR) {
  23. do {
  24. if (eMBPoll(ctx) != MB_ENOERR) break;
  25. } while (TRUE);
  26. }
  27. (void) eMBDisable(ctx);
  28. syslog(LOG_INFO, "%s, --, mbsidx:%d", __func__, ctx->mbsidx);
  29. return NULL;
  30. }
  31. static void onReadInputBuf_ZH(fmodbus_t *ctx) {
  32. usRegInputReg_ZH[1 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Tick);
  33. usRegInputReg_ZH[2 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.State);
  34. usRegInputReg_ZH[3 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.Err);
  35. usRegInputReg_ZH[4 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.Ap);
  36. usRegInputReg_ZH[5 - REG_INPUT_START_ZH] =
  37. (unsigned short) (APPL.GaoteBms.Soc);
  38. usRegInputReg_ZH[6 - REG_INPUT_START_ZH] =
  39. (unsigned short) (APPL.GaoteBms.Soh);
  40. usRegInputReg_ZH[9 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.GateAp);
  41. usRegInputReg_ZH[10 - REG_INPUT_START_ZH] =
  42. (unsigned short) (0); // 这个版本的 ctn2 没有光伏功率
  43. usRegInputReg_ZH[11 - REG_INPUT_START_ZH] =
  44. (unsigned short) (APPL.Ctl.GateLoadAp);
  45. usRegInputReg_ZH[12 - REG_INPUT_START_ZH] = (unsigned short) (1);
  46. usRegInputReg_ZH[14 - REG_INPUT_START_ZH] = APPL.GateMeter.CommState;
  47. usRegInputReg_ZH[70 - REG_INPUT_START_ZH] = 0;
  48. usRegInputReg_ZH[71 - REG_INPUT_START_ZH] = (233 & 0xffff0000) >> 16;
  49. usRegInputReg_ZH[72 - REG_INPUT_START_ZH] = (233 & 0x0000ffff);
  50. usRegInputReg_ZH[73 - REG_INPUT_START_ZH] = (100 & 0xffff0000) >> 16;
  51. usRegInputReg_ZH[74 - REG_INPUT_START_ZH] = (100 & 0x0000ffff);
  52. usRegInputReg_ZH[250 - REG_INPUT_START_ZH] = (unsigned short) (1); // ctn idx 始终为1,只有一台柜子
  53. usRegInputReg_ZH[251 - REG_INPUT_START_ZH] = (unsigned short) (APPL.CommState);
  54. usRegInputReg_ZH[252 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Tick);
  55. usRegInputReg_ZH[253 - REG_INPUT_START_ZH] =
  56. (unsigned short) (APPL.Ctl.State);
  57. usRegInputReg_ZH[254 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.Err);
  58. usRegInputReg_ZH[255 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.Ap);
  59. usRegInputReg_ZH[256 - REG_INPUT_START_ZH] =
  60. (unsigned short) (APPL.GaoteBms.Soc);
  61. usRegInputReg_ZH[257 - REG_INPUT_START_ZH] =
  62. (unsigned short) (APPL.GaoteBms.Soh);
  63. usRegInputReg_ZH[258 - REG_INPUT_START_ZH] =
  64. (unsigned short) (APPL.Ctl.bChgAble);
  65. usRegInputReg_ZH[259 - REG_INPUT_START_ZH] =
  66. (unsigned short) (APPL.Ctl.bDhgAble);
  67. usRegInputReg_ZH[260 - REG_INPUT_START_ZH] =
  68. (int) (APPL.Enjoy100kW.Aps); // 有功功率设定值
  69. usRegInputReg_ZH[261 - REG_INPUT_START_ZH] = (unsigned short) (APPL.Ctl.Cmd);
  70. usRegInputReg_ZH[271 - REG_INPUT_START_ZH] =
  71. (unsigned short) (APPL.Enjoy100kW.CommState);
  72. usRegInputReg_ZH[272 - REG_INPUT_START_ZH] =
  73. (int) (APPL.Enjoy100kW.Ap);
  74. usRegInputReg_ZH[273 - REG_INPUT_START_ZH] =
  75. (unsigned short) (APPL.Enjoy100kW.Tigbt);
  76. usRegInputReg_ZH[276 - REG_INPUT_START_ZH] =
  77. (unsigned short) (APPL.Enjoy100kW.Uab);
  78. usRegInputReg_ZH[277 - REG_INPUT_START_ZH] =
  79. (unsigned short) (APPL.Enjoy100kW.Ubc);
  80. usRegInputReg_ZH[278 - REG_INPUT_START_ZH] =
  81. (unsigned short) (APPL.Enjoy100kW.Uca);
  82. usRegInputReg_ZH[279 - REG_INPUT_START_ZH] =
  83. (unsigned short) (APPL.Enjoy100kW.Ia);
  84. usRegInputReg_ZH[280 - REG_INPUT_START_ZH] =
  85. (unsigned short) (APPL.Enjoy100kW.Ib);
  86. usRegInputReg_ZH[281 - REG_INPUT_START_ZH] =
  87. (unsigned short) (APPL.Enjoy100kW.Ic);
  88. usRegInputReg_ZH[282 - REG_INPUT_START_ZH] =
  89. (int) (APPL.Enjoy100kW.TotalBusVolt);
  90. usRegInputReg_ZH[283 - REG_INPUT_START_ZH] =
  91. (int) (APPL.Enjoy100kW.TotalBusCurr);
  92. usRegInputReg_ZH[301 - REG_INPUT_START_ZH] =
  93. (unsigned short) (APPL.GaoteBms.CommState);
  94. usRegInputReg_ZH[302 - REG_INPUT_START_ZH] =
  95. (unsigned short) (APPL.GaoteBms.HvState);
  96. usRegInputReg_ZH[303 - REG_INPUT_START_ZH] =
  97. (int) (APPL.GaoteBms.BatV);
  98. usRegInputReg_ZH[304 - REG_INPUT_START_ZH] = (int) (APPL.GaoteBms.BatI);
  99. usRegInputReg_ZH[307 - REG_INPUT_START_ZH] =
  100. (unsigned short) (APPL.GaoteBms.MaxCellV * 1000);
  101. usRegInputReg_ZH[308 - REG_INPUT_START_ZH] =
  102. (unsigned short) (APPL.GaoteBms.AvgCellV * 1000);
  103. usRegInputReg_ZH[309 - REG_INPUT_START_ZH] =
  104. (unsigned short) (APPL.GaoteBms.MinCellV * 1000);
  105. usRegInputReg_ZH[310 - REG_INPUT_START_ZH] =
  106. (unsigned short) APPL.GaoteBms.MaxCellT;
  107. usRegInputReg_ZH[311 - REG_INPUT_START_ZH] =
  108. (unsigned short) APPL.GaoteBms.AvgCellT;
  109. usRegInputReg_ZH[312 - REG_INPUT_START_ZH] =
  110. (unsigned short) APPL.GaoteBms.MinCellT;
  111. usRegInputReg_ZH[315 - REG_INPUT_START_ZH] =
  112. (unsigned short) APPL.GaoteBms.CellVDiff;
  113. usRegInputReg_ZH[316 - REG_INPUT_START_ZH] =
  114. (unsigned short) APPL.GaoteBms.CellTDiff;
  115. usRegInputReg_ZH[317 - REG_INPUT_START_ZH] =
  116. (unsigned short) APPL.GaoteBms.ISORes;
  117. usRegInputReg_ZH[318 - REG_INPUT_START_ZH] =
  118. (unsigned short) APPL.GaoteBms.NegRes;
  119. usRegInputReg_ZH[351 - REG_INPUT_START_ZH] =
  120. (unsigned short) APPL.Envicool5kW.CommState;
  121. usRegInputReg_ZH[352 - REG_INPUT_START_ZH] =
  122. (unsigned short) (APPL.Envicool5kW.OutWaterTemp * 10);
  123. usRegInputReg_ZH[353 - REG_INPUT_START_ZH] =
  124. (unsigned short) (APPL.Envicool5kW.InWaterTemp * 10);
  125. usRegInputReg_ZH[354 - REG_INPUT_START_ZH] =
  126. (unsigned short) (APPL.Envicool5kW.OutWaterPre * 10);
  127. usRegInputReg_ZH[355 - REG_INPUT_START_ZH] =
  128. (unsigned short) (APPL.Envicool5kW.InWaterPre * 10);
  129. usRegInputReg_ZH[356 - REG_INPUT_START_ZH] =
  130. (unsigned short) (APPL.Envicool5kW.EnvTemp * 10);
  131. usRegInputReg_ZH[371 - REG_INPUT_START_ZH] =
  132. (unsigned short) APPL.Adl200.CommState;
  133. usRegInputReg_ZH[372 - REG_INPUT_START_ZH] =
  134. (unsigned short) APPL.Adl200.PosAe;
  135. usRegInputReg_ZH[373 - REG_INPUT_START_ZH] =
  136. (unsigned short) APPL.Adl200.NegAe;
  137. usRegInputReg_ZH[374 - REG_INPUT_START_ZH] = (unsigned short) 0;
  138. usRegInputReg_ZH[375 - REG_INPUT_START_ZH] = (int) APPL.Adl200.Ap;
  139. usRegInputReg_ZH[382 - REG_INPUT_START_ZH] =
  140. (unsigned short) (APPL.Dehumi.CommState);
  141. usRegInputReg_ZH[383 - REG_INPUT_START_ZH] =
  142. (unsigned short) (APPL.Dehumi.TempInner);
  143. usRegInputReg_ZH[384 - REG_INPUT_START_ZH] =
  144. (unsigned short) (APPL.Dehumi.HumiInner);
  145. // usRegInputReg_ZH[392 - REG_INPUT_START_ZH] = (unsigned short)(APPL.th);
  146. // usRegInputReg_ZH[393 - REG_INPUT_START_ZH] = (unsigned
  147. // short)(env_get_temp(DEVM_RH811AD053F, 1)); usRegInputReg_ZH[394 -
  148. // REG_INPUT_START_ZH] = (unsigned short)(env_get_humi(DEVM_RH811AD053F,
  149. // 1));
  150. usRegInputReg_ZH[397 - REG_INPUT_START_ZH] =
  151. (unsigned short) (APPL.Co.CommState);
  152. usRegInputReg_ZH[398 - REG_INPUT_START_ZH] =
  153. (unsigned short) (APPL.Co.Density);
  154. usRegInputReg_ZH[421 - REG_INPUT_START_ZH] =
  155. (unsigned short) 0; // 软件版本号
  156. usRegInputReg_ZH[422 - REG_INPUT_START_ZH] = (233 & 0xffff0000) >> 16;
  157. usRegInputReg_ZH[423 - REG_INPUT_START_ZH] = (233 & 0x0000ffff);
  158. usRegInputReg_ZH[424 - REG_INPUT_START_ZH] = (100 & 0xffff0000) >> 16;
  159. usRegInputReg_ZH[425 - REG_INPUT_START_ZH] = (100 & 0x0000ffff);
  160. usRegInputReg_ZH[501 - REG_INPUT_START_ZH] = PACK_NBR;
  161. usRegInputReg_ZH[502 - REG_INPUT_START_ZH] = PACK_CELL_NBR;
  162. memcpy(&usRegInputReg_ZH[506 - REG_INPUT_START_ZH], APPL.GaoteBms.CellVolt,
  163. PACK_NBR * PACK_CELL_NBR * sizeof(APPL.GaoteBms.CellVolt[0]));
  164. memcpy(&usRegInputReg_ZH[922 - REG_INPUT_START_ZH], APPL.GaoteBms.CellTemp,
  165. PACK_NBR * PACK_CELL_NBR * sizeof(APPL.GaoteBms.CellTemp[0]));
  166. }
  167. // process 03
  168. static void prepareRegHoldingBuf_ZH(fmodbus_t *ctx, int iAddress) {
  169. }
  170. // 06
  171. static void onWriteRegHoldingBuf_ZH(fmodbus_t *ctx) {
  172. if (usRegHoldingBuf_ZH[0 - REG_HOLDING_START_ZH] != 0) {
  173. syslog(LOG_INFO, "%s,get cmd(%d) form host", __func__,
  174. usRegHoldingBuf_ZH[0 - REG_HOLDING_START_ZH]);
  175. APPL.Ctl.Cmd = usRegHoldingBuf_ZH[0 - REG_HOLDING_START_ZH];
  176. usRegHoldingBuf_ZH[0 - REG_HOLDING_START_ZH] = 0;
  177. }
  178. if (usRegHoldingBuf_ZH[1 - REG_HOLDING_START_ZH] != 0) {
  179. syslog(LOG_INFO, "%s,get cmd(%d) from pda", __func__,
  180. usRegHoldingBuf_ZH[1 - REG_HOLDING_START_ZH]);
  181. APPL.Ctl.Cmd = usRegHoldingBuf_ZH[1 - REG_HOLDING_START_ZH];
  182. usRegHoldingBuf_ZH[1 - REG_HOLDING_START_ZH] = 0;
  183. }
  184. if ((short) usRegHoldingBuf_ZH[2 - REG_HOLDING_START_ZH] !=
  185. (short) (APPL.Enjoy100kW.Aps)) {
  186. syslog(LOG_INFO, "%s,get new aps(%d) form host", __func__,
  187. (short) usRegHoldingBuf_ZH[2 - REG_HOLDING_START_ZH]);
  188. APPL.chan485[1].Cmd = CMD_485_PCS_SET_APS;
  189. APPL.chan485[1].CmdParam =
  190. (short) usRegHoldingBuf_ZH[13 - REG_HOLDING_START_ZH];
  191. }
  192. usRegHoldingBuf_ZH[3 - REG_HOLDING_START_ZH] =
  193. 1; // CTN idx 始终为1,只有一台柜子
  194. }
  195. eMBErrorCode eMBRegInputCB(fmodbus_t *ctx, UCHAR *pucRegBuffer,
  196. USHORT usAddress, USHORT usNRegs) {
  197. eMBErrorCode eStatus = MB_ENOERR;
  198. int iRegIndex;
  199. // struct chan_t* chan = &STA.chan[ctx->chanidx];
  200. // if (chan->mbsidx >= 1 && chan->mbsidx <= PCS_NBR_MAX)
  201. if (ctx->mbsidx == MBSIDX_CTN) {
  202. // if ((usAddress >= REG_INPUT_START_PCS) && (usAddress + usNRegs <=
  203. // REG_INPUT_START_PCS + REG_INPUT_NREGS_PCS)) if ((usAddress >=
  204. // REG_HOLDING_START_ZH) && (usAddress + usNRegs <= REG_HOLDING_START_ZH +
  205. // REG_HOLDING_NREGS_ZH))
  206. if ((usAddress >= REG_INPUT_START_ZH) &&
  207. (usAddress + usNRegs <= REG_INPUT_START_ZH + REG_INPUT_REG_ZH)) {
  208. // iRegIndex = (int)(usAddress - usRegInputStart_PCS[chan->mbsidx]);
  209. onReadInputBuf_ZH(ctx);
  210. iRegIndex = (int) (usAddress - REG_INPUT_START_ZH);
  211. while (usNRegs > 0) {
  212. *pucRegBuffer++ = (UCHAR) (usRegInputReg_ZH[iRegIndex] >> 8);
  213. *pucRegBuffer++ = (UCHAR) (usRegInputReg_ZH[iRegIndex] & 0xFF);
  214. iRegIndex++;
  215. usNRegs--;
  216. }
  217. } else {
  218. eStatus = MB_ENOREG;
  219. }
  220. return eStatus;
  221. }
  222. return MB_ENOREG;
  223. }
  224. eMBErrorCode eMBRegHoldingCB(fmodbus_t *ctx, UCHAR *pucRegBuffer,
  225. USHORT usAddress, USHORT usNRegs,
  226. eMBRegisterMode eMode) {
  227. eMBErrorCode eStatus = MB_ENOERR;
  228. int iRegIndex;
  229. int i = 0;
  230. // struct chan_t* chan = &STA.chan[ctx->chanidx];
  231. // if( chan->dbg > 0 ){
  232. // log_dbg("%s, chanidx:%d, mbsidx:%d, mbsdevm:%d, mbsdevidx:%d,
  233. // usAddress:%d, usNRegs:%d, eMode:%d",
  234. // __func__,
  235. // ctx->chanidx,
  236. // chan->mbsidx,
  237. // chan->mbsdevm,
  238. // chan->mbsdevidx,
  239. // usAddress,
  240. // usNRegs,
  241. // eMode);
  242. // }
  243. // if( chan->en == 0 ){
  244. // return MB_EIO;
  245. // }
  246. if (ctx->mbsidx == MBSIDX_CTN) { // ctn modbus tcp slave
  247. if ((usAddress >= REG_HOLDING_START_ZH) &&
  248. (usAddress + usNRegs <= REG_HOLDING_START_ZH + REG_HOLDING_NREGS_ZH)) {
  249. iRegIndex = (int) (usAddress - REG_HOLDING_START_ZH);
  250. switch (eMode) {
  251. /* Pass current register values to the protocol stack. */
  252. case MB_REG_READ:
  253. prepareRegHoldingBuf_ZH(ctx, usAddress);
  254. while (usNRegs > 0) {
  255. *pucRegBuffer++ = (UCHAR) (usRegHoldingBuf_ZH[iRegIndex] >> 8);
  256. *pucRegBuffer++ = (UCHAR) (usRegHoldingBuf_ZH[iRegIndex] & 0xFF);
  257. iRegIndex++;
  258. usNRegs--;
  259. }
  260. break;
  261. /* Update current register values with new values from the
  262. * protocol stack. */
  263. case MB_REG_WRITE:
  264. while (usNRegs > 0) {
  265. usRegHoldingBuf_ZH[iRegIndex] = *pucRegBuffer++ << 8;
  266. usRegHoldingBuf_ZH[iRegIndex] |= *pucRegBuffer++;
  267. iRegIndex++;
  268. usNRegs--;
  269. }
  270. onWriteRegHoldingBuf_ZH(ctx);
  271. break;
  272. }
  273. } else {
  274. eStatus = MB_ENOREG;
  275. }
  276. return eStatus;
  277. }
  278. return MB_ENOERR;
  279. }
  280. eMBErrorCode eMBRegCoilsCB(fmodbus_t *ctx, UCHAR *pucRegBuffer,
  281. USHORT usAddress, USHORT usNCoils,
  282. eMBRegisterMode eMode) {
  283. return MB_ENOREG;
  284. }
  285. eMBErrorCode eMBRegDiscreteCB(fmodbus_t *ctx, UCHAR *pucRegBuffer,
  286. USHORT usAddress, USHORT usNDiscrete) {
  287. return MB_ENOREG;
  288. }
  289. int mbs_start_ctn(int port) {
  290. int ret = 0;
  291. const UCHAR ucSlaveID[] = {0xAA, 0xBB, 0xCC};
  292. pthread_t xthrd;
  293. if (eMBTCPInit(&MB[MBSIDX_CTN], port) != MB_ENOERR) {
  294. syslog(LOG_INFO, "%s, eMBTCPInit fail", __func__);
  295. ret = -1;
  296. } else if (eMBSetSlaveID(MB[MBSIDX_CTN], 0x34, TRUE, ucSlaveID, 3) !=
  297. MB_ENOERR) {
  298. syslog(LOG_INFO, "%s, eMBSetSlaveID fail", __func__);
  299. ret = -2;
  300. } else {
  301. MB[MBSIDX_CTN]->mbsidx = MBSIDX_CTN;
  302. if (pthread_create(&xthrd, NULL, pvPollingThread, MB[MBSIDX_CTN]) != 0) {
  303. syslog(LOG_INFO, "%s, pthread_create fail", __func__);
  304. ret = -3;
  305. } else {
  306. syslog(LOG_INFO, "%s, start ok", __func__);
  307. }
  308. }
  309. return ret;
  310. }