modbus.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include "at32f403a_407.h"
  2. #include "common_config.h"
  3. #include "modbus.h"
  4. #include "modbus_params.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"
  7. #include "mb.h"
  8. #include "mbport.h"
  9. #include "mbrtu.h"
  10. #include "tim_delay.h"
  11. #include "settings_api.h"
  12. #include "iap.h"
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdbool.h>
  16. #define REG_HOLDING_START ( 1 )
  17. #define REG_HOLDING_NREGS ( 5 )
  18. static USHORT usRegHoldingStart = REG_HOLDING_START;
  19. extern UCHAR rcvAddress;
  20. //osThreadId modbus_task_handle;
  21. static void modbus_task(void *params);
  22. //osThreadId modbus_params_handle;
  23. static void modbus_params(void *params);
  24. //osTimerId reset_timer_handle;
  25. //osTimerId settings_timer_handle;
  26. //osTimerId modbus_timer_handle;
  27. mb_delay_action_t mb_action = MB_NO_ACTION;
  28. uint8_t new_slave_addr;
  29. bool mb_package_flag = false;
  30. //
  31. void mb_init(void)
  32. {
  33. uint32_t baud;
  34. eMBParity par;
  35. UCHAR mb_addr = cm_gpio_get_mb_addr();
  36. unsigned int stop_bits = 1;
  37. const UCHAR ucSlaveID[] = {0xAA, 0xBB, 0xCC};
  38. iap_init();
  39. mb_init_params();
  40. settings_set_modbus_params(settings.com_settings.mb_port);
  41. baud = settings_get_mb_baud(&mb_port_settings);
  42. par = settings_get_mb_par(&mb_port_settings);
  43. mb_helper_tim_init(baud);
  44. eMBInit(MB_RTU, mb_addr, 4, baud, par, stop_bits);
  45. eMBSetSlaveID(0x34, TRUE, ucSlaveID, 3);
  46. eMBEnable();
  47. xTaskCreate(modbus_task, "modbus_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  48. xTaskCreate(modbus_params, "modbus_params", 4*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  49. #if 0
  50. osTimerDef(vResetTimer, modbus_reset);
  51. reset_timer_handle = osTimerCreate(osTimer(vResetTimer), osTimerOnce, NULL);
  52. osTimerDef(vSettingsTimer, settings_timer);
  53. settings_timer_handle = osTimerCreate(osTimer(vSettingsTimer), osTimerOnce, NULL);
  54. osTimerDef(vModbusTimer, modbus_port_timer);
  55. modbus_timer_handle = osTimerCreate(osTimer(vModbusTimer), osTimerOnce, NULL);
  56. #endif
  57. }
  58. //
  59. void modbus_task(void *params)
  60. {
  61. (void)params;
  62. for (;;)
  63. {
  64. eMBPoll();
  65. }
  66. }
  67. //
  68. void modbus_params(void *params)
  69. {
  70. for (;;)
  71. {
  72. if (mb_action != MB_NO_ACTION)
  73. {
  74. switch (mb_action)
  75. {
  76. // Установка нового адреса
  77. case MB_CHANGE_ADDR :
  78. //settings.com_settings.mb_addr = new_slave_addr;
  79. eMBSetSlaveAddr(new_slave_addr);
  80. break;
  81. case MB_CHANGE_PORT_SETTINGS :
  82. #if 0
  83. osDelay(200);
  84. eMBRTUStop();
  85. settings_set_modbus_params(temp_modbus_port);
  86. settings_init_mb_port(settings.com_settings.mb_addr);
  87. MBDBG settings_print_modbus();
  88. eMBRTUStart();
  89. eMBEnable();
  90. mb_package_flag = false;
  91. osTimerStart(modbus_timer_handle, 9800);
  92. #endif
  93. break;
  94. // Полное восстановление дефолтных настроек
  95. case MB_DEF_SETTINGS :
  96. #if 0
  97. settings_set_default(true);
  98. settings_save();
  99. #endif
  100. break;
  101. // Частичное восстановление дефолтных настроек
  102. case MB_PART_DEF_SETTINGS :
  103. #if 0
  104. settings_set_default(false);
  105. settings_save();
  106. #endif
  107. break;
  108. case MB_SAVE_SETTINGS :
  109. #if 0
  110. settings_save();
  111. #endif
  112. break;
  113. case MB_SAVE_SYS_SETTINGS :
  114. #if 0
  115. if (set_sys_settings_flag) {
  116. memcpy(&sys_settings, &temp_sys_settings, sizeof(sys_settings));
  117. sys_settings_save();
  118. }
  119. #endif
  120. break;
  121. case MB_RESET :
  122. vTaskDelay(100);
  123. NVIC_SystemReset();
  124. break;
  125. default : break;
  126. }
  127. mb_action = MB_NO_ACTION;
  128. }
  129. vTaskDelay(10);
  130. }
  131. }
  132. // Отложенная перезагрузка в Bootloader
  133. void modbus_reset(void const * params)
  134. {
  135. #if 0
  136. MBDBG printf("Switch to bootloader!\r\n");
  137. rtc_set_load_mode(1);
  138. HAL_NVIC_SystemReset();
  139. #endif
  140. }
  141. // Запуск таймера на изменение системных настроек
  142. void settings_timer(void const * params)
  143. {
  144. #if 0
  145. set_sys_settings_flag = false;
  146. psw_ok = false;
  147. #endif
  148. }
  149. // Запуск таймера для изменение настроек modbus
  150. void modbus_port_timer(void const * params)
  151. {
  152. #if 0
  153. eMBRTUStop();
  154. // Были транзакции по modbus с новыми настройками.
  155. // Нужно сохранить новые настройки.
  156. if (mb_package_flag)
  157. {
  158. settings.com_settings.mb_port = temp_modbus_port;
  159. settings_set_modbus_params(settings.com_settings.mb_port);
  160. settings_init_mb_port(settings.com_settings.mb_addr);
  161. settings_save();
  162. }
  163. // Нужно вернуть старые настройки
  164. else
  165. {
  166. temp_modbus_port = settings.com_settings.mb_port;
  167. settings_set_modbus_params(settings.com_settings.mb_port);
  168. settings_init_mb_port(settings.com_settings.mb_addr);
  169. }
  170. MBDBG settings_print_modbus();
  171. eMBRTUStart();
  172. eMBEnable();
  173. #endif
  174. }
  175. // ------------------------------------------------------------------- //
  176. // Modbus callback's
  177. // ------------------------------------------------------------------- //
  178. // 04 (0x04) Read Input Registers
  179. eMBErrorCode
  180. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
  181. {
  182. return MB_ENOREG;
  183. }
  184. // 03 (0x03) Read Holding Registers
  185. // 16 (0x10) Write Multiple registers
  186. #if 0
  187. eMBErrorCode
  188. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
  189. {
  190. return MB_ENOREG;
  191. }
  192. #endif
  193. // 17 (0x11) Report Slave ID (Serial Line only)
  194. eMBException
  195. eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
  196. {
  197. return MB_EX_ILLEGAL_FUNCTION;
  198. }
  199. // чтение/запись значений из нескольких регистров флагов (Coil Status).
  200. // чтения N регистров параметров
  201. eMBErrorCode
  202. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
  203. {
  204. return MB_ENOREG;
  205. }
  206. eMBErrorCode
  207. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
  208. {
  209. return MB_ENOREG;
  210. }
  211. // 0x42
  212. eMBException
  213. eMBSetAddrIdCB( UCHAR * pucFrame, USHORT * usLen )
  214. {
  215. return MB_EX_ILLEGAL_FUNCTION;
  216. }
  217. // 0x43
  218. eMBException
  219. eMBSetAddrSerialCB( UCHAR * pucFrame, USHORT * usLen )
  220. {
  221. return MB_EX_ILLEGAL_FUNCTION;
  222. }
  223. // 03 (0x03) Read Holding Registers
  224. // чтение N регистров управления и уставок
  225. // 16 (0x10) Write Multiple registers
  226. // запись N регистров управления и уставок (0x10)
  227. eMBErrorCode
  228. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
  229. {
  230. eMBErrorCode eStatus = MB_ENOERR;
  231. int iRegIndex;
  232. mb_delay_action_t mb_act = MB_NO_ACTION;
  233. uint16_t regs_cnt = usNRegs;
  234. uint16_t index_param;
  235. uint8_t *ptr_buf = pucRegBuffer;
  236. uint16_t size;
  237. #if 0
  238. printf("usAddress: 0x%X\r\n", usAddress);
  239. printf("usNRegs: %u\r\n", usNRegs);
  240. printf("eMode: %u\r\n", eMode);
  241. printf("pucRegBuffer :%X\r\n", pucRegBuffer[0]);
  242. #endif
  243. mb_package_flag = true;
  244. iRegIndex = (int)(usAddress - usRegHoldingStart);
  245. #if 1
  246. switch (eMode)
  247. {
  248. case MB_REG_READ :
  249. while (regs_cnt)
  250. {
  251. // Поиск регистра
  252. if (!mb_find_param(iRegIndex, &index_param, &size))
  253. {
  254. return MB_ENOREG; // нет запрашиваемого регистра
  255. }
  256. else
  257. {
  258. MBDBG printf("reg: %X, index: %u, size: %u\r\n", iRegIndex, index_param, size);
  259. MBDBG printf("reg: %X\r\n", iRegIndex);
  260. mb_get_param(ptr_buf, index_param); // Вызов функции записи
  261. iRegIndex += size;
  262. ptr_buf += 2*size;
  263. regs_cnt -= size;
  264. }
  265. }
  266. break;
  267. case MB_REG_WRITE :
  268. while (regs_cnt)
  269. {
  270. // Поиск регистра
  271. if (!mb_find_param(iRegIndex, &index_param, &size))
  272. {
  273. return MB_ENOREG; // нет запрашиваемого регистра
  274. }
  275. else
  276. {
  277. MBDBG printf("reg: %X, index: %u, size: %u\r\n", iRegIndex, index_param, size);
  278. mb_act = mb_set_param(ptr_buf, index_param); // Вызов функции записи
  279. if (mb_act != MB_NO_ACTION)
  280. mb_action = mb_act;
  281. iRegIndex += size;
  282. ptr_buf += 2*size;
  283. regs_cnt -= size;
  284. if (mb_act == MB_PAS_ERR)
  285. return MB_EINVAL;
  286. }
  287. }
  288. break;
  289. }
  290. #endif
  291. return eStatus;
  292. }