modbus.c 9.9 KB

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