mbs.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. #include <pthread.h>
  2. #include <stdbool.h>
  3. #include "mbs.h"
  4. #include "freemodbus/modbus/include/mb.h"
  5. #include "freemodbus/modbus/include/mbctx.h"
  6. #include "freemodbus/port/port.h"
  7. enum mbs_idx_t
  8. {
  9. MBSIDX_CESS2000 = 0,
  10. MBSIDX_EMA = 1,
  11. };
  12. // 0:cess2000 modbus tcp slave
  13. fmodbus_t *MB[8];
  14. /* ----------------------- Defines ------------------------------------------*/
  15. /* ctn modbus tcp slave*/
  16. #define REG_HOLDING_START_CESS2000 0x0000
  17. #define REG_HOLDING_NREGS_CESS2000 0x5400
  18. // static USHORT usRegHoldingStart_CTN[CTN_NBR_MAX + 1];
  19. static USHORT usRegHoldingBuf_CESS2000[REG_HOLDING_NREGS_CESS2000] = {0};
  20. #define REG_HOLDING_START_EMA 0x0000
  21. #define REG_HOLDING_NREGS_EMA 0x5400
  22. // static USHORT usRegHoldingStart_CTN[CTN_NBR_MAX + 1];
  23. static USHORT usRegHoldingBuf_EMA[REG_HOLDING_NREGS_EMA] = {0};
  24. static enum ThreadState {
  25. STOPPED,
  26. RUNNING,
  27. SHUTDOWN
  28. } ePollThreadState;
  29. static pthread_mutex_t xLock = PTHREAD_MUTEX_INITIALIZER;
  30. // static BOOL bDoExit;
  31. void *pvPollingThread(void *pvParameter)
  32. {
  33. fmodbus_t *ctx = (fmodbus_t *)pvParameter;
  34. // struct chan_t* chan = &sta.chan[ctx->chanidx];
  35. printf("%s, ++, mbsidx:%d", __func__, ctx->mbsidx);
  36. if (eMBEnable(ctx) == MB_ENOERR)
  37. {
  38. do
  39. {
  40. if (eMBPoll(ctx) != MB_ENOERR)
  41. break;
  42. } while (true);
  43. }
  44. (void)eMBDisable(ctx);
  45. printf("%s, --, mbsidx:%d", __func__, ctx->mbsidx);
  46. pthread_exit(0);
  47. return NULL;
  48. }
  49. // process 03
  50. static void prepareRegHoldingBuf_CESS2000(fmodbus_t *ctx)
  51. {
  52. // struct chan_t* chan = &sta.chan[ctx->chanidx];
  53. // int mbsidx = chan->mbsidx;
  54. // int mbsdevidx = chan->mbsdevidx;
  55. // struct cess2000_t *dev = &cess2000[1];
  56. // short temp = 0;
  57. // // struct bcu_t* bcu = &sta.catl280a[1].bcu[1];
  58. // // int bmuidx, moduleidx, cellidx, tempidx;
  59. // // if( chan->dbg > 0 ){
  60. // // printf("%s, chanidx:%d, mbsidx:%d, mbsdevm:%d, mbsdevidx:%d",
  61. // // __func__, ctx->chanidx, chan->mbsidx, chan->mbsdevm, chan->mbsdevidx);
  62. // // }
  63. usRegHoldingBuf_CESS2000[0 - REG_HOLDING_START_CESS2000] = 1;
  64. usRegHoldingBuf_CESS2000[1 - REG_HOLDING_START_CESS2000] = 2;
  65. usRegHoldingBuf_CESS2000[2 - REG_HOLDING_START_CESS2000] = 3;
  66. usRegHoldingBuf_CESS2000[3 - REG_HOLDING_START_CESS2000] = 4;
  67. usRegHoldingBuf_CESS2000[4 - REG_HOLDING_START_CESS2000] = 4;
  68. usRegHoldingBuf_CESS2000[5 - REG_HOLDING_START_CESS2000] = 5; // reserved
  69. usRegHoldingBuf_CESS2000[6 - REG_HOLDING_START_CESS2000] = 5; // reserved
  70. usRegHoldingBuf_CESS2000[7 - REG_HOLDING_START_CESS2000] = 6;
  71. usRegHoldingBuf_CESS2000[8 - REG_HOLDING_START_CESS2000] = 7; // 本级心跳,先不管
  72. usRegHoldingBuf_CESS2000[9 - REG_HOLDING_START_CESS2000] = 7; // reserved
  73. usRegHoldingBuf_CESS2000[10 - REG_HOLDING_START_CESS2000] = 1;
  74. usRegHoldingBuf_CESS2000[11 - REG_HOLDING_START_CESS2000] = 2;
  75. usRegHoldingBuf_CESS2000[12 - REG_HOLDING_START_CESS2000] = 1; // 当前有功功率
  76. usRegHoldingBuf_CESS2000[13 - REG_HOLDING_START_CESS2000] = 1; // 有功功率设定值
  77. usRegHoldingBuf_CESS2000[14 - REG_HOLDING_START_CESS2000] = 1; // 预留
  78. usRegHoldingBuf_CESS2000[15 - REG_HOLDING_START_CESS2000] = 2; // 预留
  79. usRegHoldingBuf_CESS2000[16 - REG_HOLDING_START_CESS2000] = 3; // soc
  80. usRegHoldingBuf_CESS2000[17 - REG_HOLDING_START_CESS2000] = 4; // soh
  81. usRegHoldingBuf_CESS2000[125 - REG_HOLDING_START_CESS2000] = 4; // 额定容量
  82. usRegHoldingBuf_CESS2000[126 - REG_HOLDING_START_CESS2000] = 5; // 额定功率
  83. usRegHoldingBuf_CESS2000[138 - REG_HOLDING_START_CESS2000] = 6; // 硬件版本号
  84. usRegHoldingBuf_CESS2000[139 - REG_HOLDING_START_CESS2000] = 6; // 软件版本号
  85. }
  86. // 06
  87. static void procRegHoldingBuf_CESS2000(fmodbus_t *ctx)
  88. {
  89. // printf("%s, ++ register write", __func__);
  90. // if (usRegHoldingBuf_CESS2000[0 - REG_HOLDING_START_CESS2000] != 0)
  91. // {
  92. // log_info("%s,get cmd(%d) form host", __func__, usRegHoldingBuf_CESS2000[0 - REG_HOLDING_START_CESS2000]);
  93. // ctn_set_cmd(usRegHoldingBuf_CESS2000[0 - REG_HOLDING_START_CESS2000]);
  94. // usRegHoldingBuf_CESS2000[0 - REG_HOLDING_START_CESS2000] = 0;
  95. // }
  96. // if ((short)usRegHoldingBuf_CESS2000[13 - REG_HOLDING_START_CESS2000] != ctn_get_aps())
  97. // {
  98. // log_info("%s,get new aps(%d) form host", __func__,(short)usRegHoldingBuf_CESS2000[13 - REG_HOLDING_START_CESS2000]);
  99. // ctn_set_aps((short)usRegHoldingBuf_CESS2000[13 - REG_HOLDING_START_CESS2000]);
  100. // }
  101. // else
  102. // {
  103. // printf("cyx : %s, aps not change, set value : %d, ctn value : %d", __func__, (ushort)usRegHoldingBuf_CESS2000[13 - REG_HOLDING_START_CESS2000], ctn_get_aps());
  104. // }
  105. // ctn_set_bsytikchk_from_host(usRegHoldingBuf_CESS2000[10002 - REG_HOLDING_START_CESS2000]);
  106. // printf("%s, --", __func__);
  107. }
  108. static void prepareRegHoldingBuf_EMA(fmodbus_t *ctx)
  109. {
  110. // float temp_f = 0;
  111. // unsigned short temp_u16 = 0;
  112. // signed short temp_s16 = 0;
  113. // signed int temp_s32 = 0;
  114. // unsigned short *ptemp = NULL;
  115. // // log_info("%s,running!!!!!",__func__);
  116. // if (ems_get_mode() == EMSMOD_NONE)
  117. // {
  118. // usRegHoldingBuf_EMA[1000 - REG_HOLDING_START_EMA] = 0;
  119. // usRegHoldingBuf_EMA[1001 - REG_HOLDING_START_EMA] = 0;
  120. // }
  121. // else if (ems_get_mode() == EMSMOD_PCURV)
  122. // {
  123. // usRegHoldingBuf_EMA[1000 - REG_HOLDING_START_EMA] = 0;
  124. // usRegHoldingBuf_EMA[1001 - REG_HOLDING_START_EMA] = 1;
  125. // }
  126. // temp_f = 600.0;
  127. // usRegHoldingBuf_EMA[1002 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  128. // usRegHoldingBuf_EMA[1003 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  129. // usRegHoldingBuf_EMA[1004 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  130. // usRegHoldingBuf_EMA[1005 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  131. // temp_f = ctn_get_soc();
  132. // usRegHoldingBuf_EMA[1006 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  133. // usRegHoldingBuf_EMA[1007 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  134. // // cell fault state-------reserve
  135. // temp_f = 2000.0;
  136. // usRegHoldingBuf_EMA[1010 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  137. // usRegHoldingBuf_EMA[1011 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  138. // temp_f = 1800;
  139. // usRegHoldingBuf_EMA[1012 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  140. // usRegHoldingBuf_EMA[1013 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  141. // temp_f = pcs_get_chg_e_total();
  142. // usRegHoldingBuf_EMA[1014 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  143. // usRegHoldingBuf_EMA[1015 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  144. // temp_f = pcs_get_dhg_e_total();
  145. // usRegHoldingBuf_EMA[1016 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  146. // usRegHoldingBuf_EMA[1017 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  147. // usRegHoldingBuf_EMA[1018 - REG_HOLDING_START_EMA] = 0;
  148. // usRegHoldingBuf_EMA[1019 - REG_HOLDING_START_EMA] = ctn_get_tick();
  149. // temp_s32 = ctn_cal_get_cycle();
  150. // usRegHoldingBuf_EMA[1020 - REG_HOLDING_START_EMA] = *(unsigned int *)&temp_s32 >> 16;
  151. // usRegHoldingBuf_EMA[1021 - REG_HOLDING_START_EMA] = *(unsigned int *)&temp_s32;
  152. // usRegHoldingBuf_EMA[1022 - REG_HOLDING_START_EMA] = 0;
  153. // usRegHoldingBuf_EMA[1023 - REG_HOLDING_START_EMA] = ctn_get_state();
  154. // temp_s32 = ctn_get_ap();
  155. // usRegHoldingBuf_EMA[1024 - REG_HOLDING_START_EMA] = *(unsigned int *)&temp_s32 >> 16;
  156. // usRegHoldingBuf_EMA[1025 - REG_HOLDING_START_EMA] = *(unsigned int *)&temp_s32;
  157. // temp_f = pcs_get_grid_freq();
  158. // usRegHoldingBuf_EMA[1026 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f)) >> 16;
  159. // usRegHoldingBuf_EMA[1027 - REG_HOLDING_START_EMA] = *((unsigned int *)(&temp_f));
  160. // usRegHoldingBuf_EMA[1028 - REG_HOLDING_START_EMA] = 0;
  161. // usRegHoldingBuf_EMA[1029 - REG_HOLDING_START_EMA] = ctn_get_err();
  162. }
  163. static void procRegHoldingBuf_EMA(fmodbus_t *ctx)
  164. {
  165. // unsigned int temp = 0;
  166. // int aps = 0;
  167. // temp = usRegHoldingBuf_EMA[2000 - REG_HOLDING_START_EMA];
  168. // // log_info("%s,temp(%d)",__func__,temp);
  169. // temp = (temp << 16) + usRegHoldingBuf_EMA[2001 - REG_HOLDING_START_EMA];
  170. // // log_info("%s,temp(%d)",__func__,temp);
  171. // aps = *((float *)(&temp));
  172. // // if(aps != 0){
  173. // log_info("%s,get aps(%d),tepm(%d),2000(%d),2001(%d)form host", __func__, aps, temp, usRegHoldingBuf_EMA[2000 - REG_HOLDING_START_EMA], usRegHoldingBuf_EMA[2001 - REG_HOLDING_START_EMA]);
  174. // if (ems_get_mode() == EMSMOD_NONE)
  175. // ctn_set_aps(aps);
  176. //}
  177. }
  178. eMBErrorCode eMBRegInputCB(fmodbus_t *ctx, UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs)
  179. {
  180. eMBErrorCode eStatus = MB_ENOERR;
  181. int iRegIndex;
  182. // struct chan_t* chan = &sta.chan[ctx->chanidx];
  183. // if( chan->dbg > 0 ){
  184. // printf("%s, chanidx:%d, mbsidx:%d, mbsdevm:%d, mbsdevidx:%d, usAddress:%d, usNRegs:%d",
  185. // __func__, ctx->chanidx, chan->mbsidx, chan->mbsdevm, chan->mbsdevidx,usAddress, usNRegs);
  186. // }
  187. /*********************
  188. if(chan->mbsidx >= 1 && chan->mbsidx <= PCS_NBR_MAX){ // pcs modbus rtu slave
  189. if( ( usAddress >= REG_INPUT_START_PCS )
  190. && ( usAddress + usNRegs <= REG_INPUT_START_PCS + REG_INPUT_NREGS_PCS ) ){
  191. iRegIndex = ( int )( usAddress - usRegInputStart_PCS[chan->mbsidx] );
  192. while( usNRegs > 0 ){
  193. //_prepareInputReg_PCS(ctx);
  194. *pucRegBuffer++ = ( unsigned char )( usRegInputBuf_PCS[chan->mbsidx][iRegIndex] >> 8 );
  195. *pucRegBuffer++ = ( unsigned char )( usRegInputBuf_PCS[chan->mbsidx][iRegIndex] & 0xFF );
  196. iRegIndex++;
  197. usNRegs--;
  198. }
  199. }else{
  200. eStatus = MB_ENOREG;
  201. }
  202. return eStatus;
  203. }
  204. *******************/
  205. return MB_ENOREG;
  206. }
  207. eMBErrorCode eMBRegHoldingCB(fmodbus_t *ctx, UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode)
  208. {
  209. eMBErrorCode eStatus = MB_ENOERR;
  210. int iRegIndex;
  211. int i = 0;
  212. // struct chan_t* chan = &sta.chan[ctx->chanidx];
  213. // if( chan->dbg > 0 ){
  214. // printf("%s, chanidx:%d, mbsidx:%d, mbsdevm:%d, mbsdevidx:%d, usAddress:%d, usNRegs:%d, eMode:%d",
  215. // __func__, ctx->chanidx, chan->mbsidx, chan->mbsdevm, chan->mbsdevidx,
  216. // usAddress, usNRegs, eMode);
  217. // }
  218. // if( chan->en == 0 ){
  219. // return MB_EIO;
  220. // }
  221. if (ctx->mbsidx == MBSIDX_CESS2000)
  222. { // ctn modbus tcp slave
  223. if ((usAddress >= REG_HOLDING_START_CESS2000) && (usAddress + usNRegs <= REG_HOLDING_START_CESS2000 + REG_HOLDING_NREGS_CESS2000))
  224. {
  225. iRegIndex = (int)(usAddress - REG_HOLDING_START_CESS2000);
  226. switch (eMode)
  227. {
  228. /* Pass current register values to the protocol stack. */
  229. case MB_REG_READ:
  230. prepareRegHoldingBuf_CESS2000(ctx);
  231. while (usNRegs > 0)
  232. {
  233. *pucRegBuffer++ = (UCHAR)(usRegHoldingBuf_CESS2000[iRegIndex] >> 8);
  234. *pucRegBuffer++ = (UCHAR)(usRegHoldingBuf_CESS2000[iRegIndex] & 0xFF);
  235. iRegIndex++;
  236. usNRegs--;
  237. }
  238. break;
  239. /* Update current register values with new values from the
  240. * protocol stack. */
  241. case MB_REG_WRITE:
  242. while (usNRegs > 0)
  243. {
  244. usRegHoldingBuf_CESS2000[iRegIndex] = *pucRegBuffer++ << 8;
  245. usRegHoldingBuf_CESS2000[iRegIndex] |= *pucRegBuffer++;
  246. iRegIndex++;
  247. usNRegs--;
  248. }
  249. procRegHoldingBuf_CESS2000(ctx);
  250. break;
  251. }
  252. }
  253. else
  254. {
  255. eStatus = MB_ENOREG;
  256. }
  257. return eStatus;
  258. }
  259. else if (ctx->mbsidx == MBSIDX_EMA)
  260. { // ctn modbus tcp slave
  261. if ((usAddress >= REG_HOLDING_START_EMA) && (usAddress + usNRegs <= REG_HOLDING_START_EMA + REG_HOLDING_NREGS_EMA))
  262. {
  263. iRegIndex = (int)(usAddress - REG_HOLDING_START_EMA);
  264. // log_info("%s,%d",__func__,iRegIndex);
  265. switch (eMode)
  266. {
  267. /* Pass current register values to the protocol stack. */
  268. case MB_REG_READ:
  269. prepareRegHoldingBuf_EMA(ctx);
  270. while (usNRegs > 0)
  271. {
  272. *pucRegBuffer++ = (UCHAR)(usRegHoldingBuf_EMA[iRegIndex] >> 8);
  273. *pucRegBuffer++ = (UCHAR)(usRegHoldingBuf_EMA[iRegIndex] & 0xFF);
  274. iRegIndex++;
  275. usNRegs--;
  276. }
  277. break;
  278. /* Update current register values with new values from the
  279. * protocol stack. */
  280. case MB_REG_WRITE:
  281. while (usNRegs > 0)
  282. {
  283. usRegHoldingBuf_EMA[iRegIndex] = *pucRegBuffer++ << 8;
  284. usRegHoldingBuf_EMA[iRegIndex] |= *pucRegBuffer++;
  285. iRegIndex++;
  286. usNRegs--;
  287. }
  288. procRegHoldingBuf_EMA(ctx);
  289. break;
  290. }
  291. }
  292. else
  293. {
  294. eStatus = MB_ENOREG;
  295. }
  296. return eStatus;
  297. }
  298. return eStatus;
  299. }
  300. eMBErrorCode eMBRegCoilsCB(fmodbus_t *ctx, UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode)
  301. {
  302. return MB_ENOREG;
  303. }
  304. eMBErrorCode eMBRegDiscreteCB(fmodbus_t *ctx, UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNDiscrete)
  305. {
  306. return MB_ENOREG;
  307. }
  308. static pthread_t xthrd;
  309. int mbs_start_cess2000(int port)
  310. {
  311. int ret = 0;
  312. const UCHAR ucSlaveID[] = {0xAA, 0xBB, 0xCC};
  313. //if (eMBTCPInit(&MB[MBSIDX_CESS2000], port) != MB_ENOERR)
  314. if (eMBInit(&MB[MBSIDX_CESS2000], MB_RTU, 1, "/dev/ttymxc1", 115200, MB_PAR_NONE) != MB_ENOERR)
  315. {
  316. printf("%s, eMBTCPInit fail", __func__);
  317. ret = -1;
  318. }
  319. // else if (eMBSetSlaveID(MB[MBSIDX_CESS2000], 0x34, TRUE, ucSlaveID, 3) != MB_ENOERR)
  320. // {
  321. // printf("%s, eMBSetSlaveID fail", __func__);
  322. // ret = -2;
  323. // }
  324. else
  325. {
  326. MB[MBSIDX_CESS2000]->mbsidx = MBSIDX_CESS2000;
  327. if (pthread_create(&xthrd, NULL, pvPollingThread, MB[MBSIDX_CESS2000]) != 0)
  328. {
  329. printf("%s, pthread_create fail", __func__);
  330. ret = -3;
  331. }
  332. else
  333. {
  334. pthread_detach(xthrd);
  335. printf("%s, start ok", __func__);
  336. }
  337. }
  338. return ret;
  339. }
  340. int mbs_start_EMA(int port)
  341. {
  342. int ret = 0;
  343. const UCHAR ucSlaveID[] = {0xAA, 0xBB, 0xCC};
  344. pthread_t xthrd;
  345. if (eMBTCPInit(&MB[MBSIDX_EMA], port) != MB_ENOERR)
  346. {
  347. printf("%s, eMBTCPInit fail", __func__);
  348. ret = -1;
  349. }
  350. else if (eMBSetSlaveID(MB[MBSIDX_EMA], 0x34, TRUE, ucSlaveID, 3) != MB_ENOERR)
  351. {
  352. printf("%s, eMBSetSlaveID fail", __func__);
  353. ret = -2;
  354. }
  355. else
  356. {
  357. MB[MBSIDX_EMA]->mbsidx = MBSIDX_EMA;
  358. if (pthread_create(&xthrd, NULL, pvPollingThread, MB[MBSIDX_EMA]) != 0)
  359. {
  360. printf("%s, pthread_create fail", __func__);
  361. ret = -3;
  362. }
  363. else
  364. {
  365. printf("%s, port:%d,start ok", __func__, port);
  366. }
  367. }
  368. return ret;
  369. }