Module_Modbus.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * Module_Modbus.c
  3. *
  4. * Created on: 2020年3月11日
  5. * Author: 7564
  6. */
  7. #include <sys/time.h>
  8. #include <sys/timeb.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <sys/types.h>
  12. #include <sys/ioctl.h>
  13. #include <sys/socket.h>
  14. #include <sys/ipc.h>
  15. #include <sys/shm.h>
  16. #include <sys/shm.h>
  17. #include <sys/mman.h>
  18. #include <linux/wireless.h>
  19. #include <arpa/inet.h>
  20. #include <netinet/in.h>
  21. #include <unistd.h>
  22. #include <stdarg.h>
  23. #include <stdio.h> /*標準輸入輸出定義*/
  24. #include <stdlib.h> /*標準函數庫定義*/
  25. #include <unistd.h> /*Unix 標準函數定義*/
  26. #include <fcntl.h> /*檔控制定義*/
  27. #include <termios.h> /*PPSIX 終端控制定義*/
  28. #include <errno.h> /*錯誤號定義*/
  29. #include <errno.h>
  30. #include <string.h>
  31. #include <time.h>
  32. #include <ctype.h>
  33. #include <ifaddrs.h>
  34. #include <stdbool.h>
  35. #include "../../define.h"
  36. #include "modbus.h"
  37. #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
  38. #define PASS 1
  39. #define FAIL -1
  40. #define YES 1
  41. #define NO 0
  42. #define MODBUS_SERVER_PORT 502
  43. #define MODBUS_DEBUG OFF
  44. modbus_t *ctx;
  45. int server_socket;
  46. modbus_mapping_t *mb_mapping;
  47. int header_length;
  48. uint8_t bits[MODBUS_MAX_READ_BITS] = {0};
  49. uint16_t regs[MODBUS_MAX_READ_REGISTERS] = {0};
  50. struct SysConfigAndInfo *ShmSysConfigAndInfo;
  51. struct StatusCodeData *ShmStatusCodeData;
  52. unsigned char _gunCount = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
  53. struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
  54. void PRINTF_FUNC(char *string, ...);
  55. int StoreLogMsg(const char *fmt, ...);
  56. #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  57. #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  58. #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  59. int StoreLogMsg(const char *fmt, ...)
  60. {
  61. char Buf[4096+256];
  62. char buffer[4096];
  63. time_t CurrentTime;
  64. struct tm *tm;
  65. va_list args;
  66. va_start(args, fmt);
  67. int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
  68. va_end(args);
  69. memset(Buf,0,sizeof(Buf));
  70. CurrentTime = time(NULL);
  71. tm=localtime(&CurrentTime);
  72. sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
  73. tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
  74. buffer,
  75. tm->tm_year+1900,tm->tm_mon+1);
  76. system(Buf);
  77. return rc;
  78. }
  79. void PRINTF_FUNC(char *string, ...)
  80. {
  81. va_list args;
  82. char buffer[4096];
  83. va_start(args, string);
  84. vsnprintf(buffer, sizeof(buffer), string, args);
  85. va_end(args);
  86. if (DEBUG)
  87. PRINTF_FUNC("%s \n", buffer);
  88. else
  89. DEBUG_INFO("%s \n", buffer);
  90. }
  91. //=================================
  92. // Save data to share memory Function
  93. //=================================
  94. bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
  95. {
  96. for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
  97. {
  98. if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
  99. {
  100. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
  101. return true;
  102. }
  103. }
  104. for (byte index = 0; index < CCS_QUANTITY; index++)
  105. {
  106. if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
  107. {
  108. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
  109. return true;
  110. }
  111. }
  112. for (byte index = 0; index < GB_QUANTITY; index++)
  113. {
  114. if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
  115. {
  116. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
  117. return true;
  118. }
  119. }
  120. return false;
  121. }
  122. //==========================================
  123. // Init all share memory
  124. //==========================================
  125. int InitShareMemory()
  126. {
  127. int result = PASS;
  128. int MeterSMId;
  129. //creat ShmSysConfigAndInfo
  130. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  131. {
  132. #ifdef SystemLogMessage
  133. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
  134. #endif
  135. result = FAIL;
  136. }
  137. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  138. {
  139. #ifdef SystemLogMessage
  140. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
  141. #endif
  142. result = FAIL;
  143. }
  144. else
  145. {}
  146. //creat ShmStatusCodeData
  147. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  148. {
  149. #ifdef SystemLogMessage
  150. DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
  151. #endif
  152. result = FAIL;
  153. }
  154. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  155. {
  156. #ifdef SystemLogMessage
  157. DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
  158. #endif
  159. result = FAIL;
  160. }
  161. return result;
  162. }
  163. void Initialization()
  164. {
  165. bool isPass = false;
  166. while(!isPass)
  167. {
  168. isPass = true;
  169. for (byte _index = 0; _index < _gunCount; _index++)
  170. {
  171. if (!FindChargingInfoData(_index, &chargingInfo[0]))
  172. {
  173. DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
  174. isPass = false;
  175. break;
  176. }
  177. }
  178. }
  179. }
  180. //================================================
  181. // Main process
  182. //================================================
  183. int InitModbus()
  184. {
  185. int result = PASS;
  186. ctx = modbus_new_tcp(NULL, MODBUS_SERVER_PORT);
  187. server_socket = modbus_tcp_listen(ctx, 1);
  188. mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, MODBUS_MAX_WRITE_BITS, MODBUS_MAX_READ_REGISTERS, MODBUS_MAX_WR_READ_REGISTERS);
  189. if (mb_mapping == NULL)
  190. {
  191. PRINTF_FUNC("mb_mapping error.\r\n");
  192. modbus_free(ctx);
  193. result = FAIL;
  194. }
  195. modbus_set_debug(ctx, MODBUS_DEBUG);
  196. return result;
  197. }
  198. void updateInfo()
  199. {
  200. // Start or Stop Charging
  201. if (mb_mapping->tab_registers[0] == YES)
  202. ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = YES;
  203. else
  204. ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = NO;
  205. // Hard Reset
  206. if (mb_mapping->tab_registers[1] == YES && chargingInfo[0]->SystemStatus == S_IDLE)
  207. {
  208. sleep(3);
  209. system("reboot -f");
  210. }
  211. // State
  212. mb_mapping->tab_registers[2] = chargingInfo[0]->SystemStatus;
  213. // Plug Status
  214. mb_mapping->tab_registers[3] = chargingInfo[0]->ConnectorPlugIn;
  215. // Max Current
  216. mb_mapping->tab_registers[4] = (ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent >> 8) & 0xFF;
  217. mb_mapping->tab_registers[5] = ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent & 0xFF;
  218. // Soc
  219. mb_mapping->tab_registers[10] = chargingInfo[0]->EvBatterySoc;
  220. // Output Pow
  221. mb_mapping->tab_registers[11] = ((int)chargingInfo[0]->PresentChargingPower >> 24) & 0xFF;
  222. mb_mapping->tab_registers[12] = ((int)chargingInfo[0]->PresentChargingPower >> 16) & 0xFF;
  223. mb_mapping->tab_registers[13] = ((int)chargingInfo[0]->PresentChargingPower >> 8) & 0xFF;
  224. mb_mapping->tab_registers[14] = chargingInfo[0]->PresentChargingPower;
  225. // Output Vol
  226. mb_mapping->tab_registers[20] = ((int)chargingInfo[0]->PresentChargingVoltage >> 24) & 0xFF;
  227. mb_mapping->tab_registers[21] = ((int)chargingInfo[0]->PresentChargingVoltage >> 16) & 0xFF;
  228. mb_mapping->tab_registers[22] = ((int)chargingInfo[0]->PresentChargingVoltage >> 8) & 0xFF;
  229. mb_mapping->tab_registers[23] = chargingInfo[0]->PresentChargingVoltage;
  230. // Output Cur
  231. mb_mapping->tab_registers[25] = ((int)chargingInfo[0]->PresentChargingCurrent >> 24) & 0xFF;
  232. mb_mapping->tab_registers[26] = ((int)chargingInfo[0]->PresentChargingCurrent >> 16) & 0xFF;
  233. mb_mapping->tab_registers[27] = ((int)chargingInfo[0]->PresentChargingCurrent >> 8) & 0xFF;
  234. mb_mapping->tab_registers[28] = chargingInfo[0]->PresentChargingCurrent;
  235. // Remain Time
  236. mb_mapping->tab_registers[30] = (chargingInfo[0]->PresentChargedDuration >> 24) & 0xFF;
  237. mb_mapping->tab_registers[31] = (chargingInfo[0]->PresentChargedDuration >> 16) & 0xFF;
  238. mb_mapping->tab_registers[32] = (chargingInfo[0]->PresentChargedDuration >> 8) & 0xFF;
  239. mb_mapping->tab_registers[33] = chargingInfo[0]->PresentChargedDuration;
  240. // Charging Time
  241. mb_mapping->tab_registers[35] = (chargingInfo[0]->RemainChargingDuration >> 24) & 0xFF;
  242. mb_mapping->tab_registers[36] = (chargingInfo[0]->RemainChargingDuration >> 16) & 0xFF;
  243. mb_mapping->tab_registers[37] = (chargingInfo[0]->RemainChargingDuration >> 8) & 0xFF;
  244. mb_mapping->tab_registers[38] = chargingInfo[0]->RemainChargingDuration;
  245. }
  246. int main(void)
  247. {
  248. PRINTF_FUNC("Psu Task boot .... \n");
  249. if(InitShareMemory() == FAIL)
  250. {
  251. #ifdef SystemLogMessage
  252. DEBUG_ERROR("InitShareMemory NG\n");
  253. #endif
  254. if(ShmStatusCodeData != NULL)
  255. {
  256. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
  257. }
  258. sleep(5);
  259. return 0;
  260. }
  261. Initialization();
  262. int rc;
  263. uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
  264. if(InitModbus() == FAIL)
  265. {
  266. PRINTF_FUNC("InitModbus NG\r\n");
  267. return FAIL;
  268. }
  269. else
  270. {
  271. PRINTF_FUNC("Modbus TCP initial OK.\r\n");
  272. }
  273. //=================================
  274. // Modbus TCP loop
  275. //=================================
  276. for(;;)
  277. {
  278. modbus_tcp_accept(ctx, &server_socket);
  279. while((rc = modbus_receive(ctx, query)) > 0)
  280. {
  281. modbus_reply(ctx, query, rc, mb_mapping);
  282. // Update EVSE info
  283. updateInfo();
  284. usleep(100000);
  285. }
  286. if(rc == -1)
  287. PRINTF_FUNC("Client disconnect...\r\n");
  288. else
  289. PRINTF_FUNC("Client communication error...\r\n");
  290. }
  291. return FAIL;
  292. }