settings_api.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /********************************* (C) ROTEK ***********************************
  2. * @module settings_api
  3. * @file settings_api.c
  4. * @version 1.0.0
  5. * @date XX.XX.XXXX
  6. * $brief Settings
  7. *******************************************************************************
  8. * @history Version Author Comment
  9. * XX.XX.XXXX 1.0.0 Telenkov D.A. First release.
  10. *******************************************************************************
  11. */
  12. #include "stm32f4xx.h"
  13. #include "settings_api.h"
  14. #include "common_config.h"
  15. #ifndef BT6702_SERVICE
  16. #include "snmp_api.h"
  17. #include "log.h"
  18. #endif
  19. #include "sys_api.h"
  20. #include "FreeRTOS.h"
  21. #include "task.h"
  22. #include "semphr.h"
  23. #include "main.h"
  24. #include "parameters.h"
  25. #include "mbedtls/certs.h"
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #ifdef PRINTF_STDLIB
  29. #include <stdio.h>
  30. #endif
  31. #ifdef PRINTF_CUSTOM
  32. #include "tinystdio.h"
  33. #endif
  34. //#define DBG if(0)
  35. #if defined ( __ICCARM__ )
  36. #define DEVICE_MAC "00-00-00-00-00-03"
  37. #endif
  38. const float UPSPowerMass[] = {1000, 1500, 2000, 3000, 6000, 10000};
  39. const float UPSEfficiencyFactorMass[] = {0.83, 0.87, 0.87, 0.88, 0.9, 0.91};
  40. SemaphoreHandle_t flash_mutex;
  41. /**
  42. * @brief Флаг подтверждения новых сетевых параметров пользователем
  43. */
  44. bool fConfirmWebParams = false;
  45. /**
  46. * @brief Общая структура настроек
  47. */
  48. SETTINGS_t sSettings;
  49. /**
  50. * @brief Установить параметры обновления ПО по умолчанию
  51. */
  52. void SETTINGS_SetBootParamsDef(void)
  53. {
  54. sSettings.bootParams.loadMode = 0;
  55. sSettings.bootParams.bootTry = 0;
  56. }
  57. /**
  58. * @brief Установить параметры сетевого подключения по умолчанию
  59. */
  60. void SETTINGS_SetWebParamsDef(void)
  61. {
  62. strcpy(sSettings.sWebParams.ip, "192.168.0.254");
  63. strcpy(sSettings.sWebParams.gate, "192.168.0.1");
  64. strcpy(sSettings.sWebParams.mask, "255.255.255.0");
  65. sSettings.sWebParams.dhcpEnable = 0;
  66. }
  67. /**
  68. * @brief Установить временные параметры сетевого подключения по умолчанию
  69. */
  70. void SETTINGS_SetTempWebParamsDef(void)
  71. {
  72. strcpy(sSettings.sWebTempParams.ip, "192.168.0.254");
  73. strcpy(sSettings.sWebTempParams.gate, "192.168.0.1");
  74. strcpy(sSettings.sWebTempParams.mask, "255.255.255.0");
  75. sSettings.sWebTempParams.dhcpEnable = 0;
  76. }
  77. /**
  78. * @brief Установить Информацию об устройстве по умолчанию
  79. */
  80. void SETTINGS_SetInfoDef(void)
  81. {
  82. SYS_t *sSys = NULL;
  83. sSys = pvPortMalloc(sizeof(*sSys));
  84. if (sSys) {
  85. SYS_Load(sSys);
  86. strcpy(sSettings.sInfo.mac, sSys->mac);
  87. strcpy(sSettings.sInfo.serialNumber, sSys->serial);
  88. strcpy(sSettings.sInfo.productionData, sSys->proddate);
  89. strcpy(sSettings.sFlags.testState, sSys->testState);
  90. vPortFree(sSys);
  91. }
  92. else {
  93. strcpy(sSettings.sInfo.productionData, "09.07.2017");
  94. strcpy(sSettings.sInfo.mac, DEVICE_MAC);
  95. strcpy(sSettings.sInfo.serialNumber, DEVICE_SERIAL);
  96. strcpy(sSettings.sFlags.testState, "T2OK");
  97. }
  98. strcpy(sSettings.sInfo.comments, "");
  99. }
  100. /**
  101. * @brief Установить флаги по умолчанию
  102. */
  103. void SETTINGS_SetFlagsDef(void)
  104. {
  105. sSettings.sFlags.netsettingsChanged = false;
  106. }
  107. /**
  108. * @brief Сброс всех настроек в значения по умолчанию кроме сетевых настроек
  109. */
  110. void SETTINGS_SetPartDefault(void)
  111. {
  112. SETTINGS_SetBootParamsDef();
  113. SETTINGS_SetFlagsDef();
  114. #define XSETTING(type, name, setter, type_reset) if (type_reset == ALL_DEFAULT) setter();
  115. SETTINGS_TABLE
  116. #undef XSETTING
  117. sSettings.CritSecCRC = SETTINGS_GetCritSecCRC();
  118. sSettings.controlWorld = SETTINGS_CONTROL_WORD;
  119. }
  120. /**
  121. * @brief Сброс всех настроек в значения по умолчанию
  122. */
  123. void SETTINGS_SetAllDefault(void)
  124. {
  125. SETTINGS_SetBootParamsDef();
  126. SETTINGS_SetWebParamsDef();
  127. SETTINGS_SetTempWebParamsDef();
  128. SETTINGS_SetInfoDef();
  129. SETTINGS_SetFlagsDef();
  130. SETTINGS_SetUPSSerialSettingsDef();
  131. #define XSETTING(type, name, setter, type_reset) setter();
  132. SETTINGS_TABLE
  133. #undef XSETTING
  134. sSettings.CritSecCRC = SETTINGS_GetCritSecCRC();
  135. sSettings.controlWorld = SETTINGS_CONTROL_WORD;
  136. }
  137. /**
  138. * @brief Установка настроек для отладки
  139. */
  140. void SETTINGS_SetDefaultDebug(void)
  141. {
  142. SETTINGS_SetWebParamsDef();
  143. SETTINGS_SetTempWebParamsDef();
  144. SETTINGS_SetBootParamsDef();
  145. SETTINGS_SetFlagsDef();
  146. #define XSETTING(type, name, setter, type_reset) if (type_reset != PART_DEFAULT_2) setter();
  147. SETTINGS_TABLE
  148. #undef XSETTING
  149. sSettings.CritSecCRC = SETTINGS_GetCritSecCRC();
  150. sSettings.controlWorld = SETTINGS_CONTROL_WORD;
  151. }
  152. /**
  153. * @brief Запись структуры настроек во flesh
  154. */
  155. void SETTINGS_Save(void)
  156. {
  157. xSemaphoreTake(flash_mutex, portMAX_DELAY);
  158. /* Calc critical section CRC and store to the settings structure */
  159. sSettings.CritSecCRC = SETTINGS_GetCritSecCRC();
  160. SETTINGS_WriteToFlash((uint8_t*)&sSettings, sizeof(sSettings));
  161. xSemaphoreGive(flash_mutex);
  162. }
  163. /**
  164. * @brief Загрузка структуры настроек из flesh
  165. */
  166. void SETTINGS_Load(void)
  167. {
  168. uint32_t loadCRC; // CRC из flash
  169. uint32_t newCRC; // CRC загруженной структуры настроек
  170. bool need_default = false;
  171. WEB_PARAMS_t sWebParamsBackup;
  172. BOOT_PARAMS_t bootParamsBackup;
  173. SETTINGS_ReadFromFlash((uint8_t*)&sSettings, sizeof(sSettings));
  174. /* Считываем CRC из флеш памяти */
  175. loadCRC = (*(uint32_t*)CRC_ADDRESS);
  176. /* Рассчитываем CRC для структуры настроек */
  177. newCRC = SETTINGS_GetCRC();
  178. if (loadCRC != newCRC) {
  179. /* SETTINGS_SetAllDefault();
  180. SETTINGS_Save();*/
  181. need_default = true;
  182. }
  183. /* CRC совпала, проверяем контрольное слово если слово не совпадает
  184. то это значит, что поплыла структура нстроек, прошиваем дефолт */
  185. else if (sSettings.controlWorld != SETTINGS_CONTROL_WORD)
  186. {
  187. need_default = true;
  188. }
  189. /* Прошиваем дефолтные настройки если нужно */
  190. if (need_default) {
  191. /* Бэкапим сетевые параметры загрузчика */
  192. memcpy(&sWebParamsBackup, &sSettings.sWebParams, sizeof(sWebParamsBackup));
  193. /* Бэкапим флаги загрузчика */
  194. memcpy(&bootParamsBackup, &sSettings.bootParams, sizeof(bootParamsBackup));
  195. loadCRC = sSettings.CritSecCRC;
  196. newCRC = SETTINGS_GetCritSecCRC();
  197. SETTINGS_SetAllDefault();
  198. if (loadCRC == newCRC) {
  199. /* Применяем флаги загрузчика */
  200. memcpy(&sSettings.bootParams, &bootParamsBackup, sizeof(sSettings.bootParams));
  201. /* Применяем сетевые параметры загрузчика */
  202. memcpy(&sSettings.sWebParams, &sWebParamsBackup, sizeof(sSettings.sWebParams));
  203. }
  204. SETTINGS_Save();
  205. }
  206. }
  207. /**
  208. * @brief
  209. */
  210. void SETTINGS_WriteToFlash(uint8_t *data, uint32_t size)
  211. {
  212. uint32_t baseAddress = SETTINGS_SECTOR;
  213. uint32_t checkCrc = 0;
  214. uint32_t crc = SETTINGS_GetCRC();
  215. bool fAlarm = 0;
  216. FLASH_Status status;
  217. for (uint8_t i = 0; i < 3; i++)
  218. {
  219. fAlarm = 0;
  220. FLASH_Unlock();
  221. SETTINGS_EraseFlashSector();
  222. for (uint32_t i = 0; i < size; i++)
  223. if ((status = FLASH_ProgramByte(baseAddress++, *data++)) != FLASH_COMPLETE) {
  224. DBG printf("FLASH_ProgramByte error: status = %d\r\n", status);
  225. break;
  226. }
  227. if ((status = FLASH_ProgramWord((uint32_t)CRC_ADDRESS, crc)) != FLASH_COMPLETE) {
  228. DBG printf("FLASH_ProgramWord error: status = %d\r\n", status);
  229. }
  230. FLASH_Lock();
  231. /* Считываем что записали */
  232. SETTINGS_ReadFromFlash((uint8_t*)&sSettings, sizeof(sSettings));
  233. checkCrc = SETTINGS_GetCRC();
  234. /* Проверяем CRC того что было записано */
  235. if (checkCrc == crc)
  236. break;
  237. else
  238. fAlarm = 1; // Авария
  239. }
  240. /* Произошел сбой при записи - висим */
  241. if (fAlarm)
  242. while (1)
  243. {};
  244. }
  245. /**
  246. * @brief
  247. */
  248. void SETTINGS_ReadFromFlash(uint8_t *data, uint32_t size)
  249. {
  250. uint32_t baseAddress = SETTINGS_SECTOR;
  251. for (uint32_t i = 0; i < size; i++)
  252. *data++ = (*(uint32_t*)baseAddress++);;
  253. }
  254. /**
  255. * @brief Очистка сектора настроек
  256. * @retval
  257. */
  258. void SETTINGS_EraseFlashSector(void)
  259. {
  260. FLASH_Status status;
  261. if ((status = FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3)) != FLASH_COMPLETE) {
  262. DBG printf("SETTINGS_EraseFlashSector error: status = %d/r/n", status);
  263. }
  264. }
  265. /**
  266. * @brief
  267. * @retval
  268. */
  269. uint32_t SETTINGS_GetCRC(void)
  270. {
  271. CRC_ResetDR();
  272. return CRC_CalcBlockCRC((uint32_t*)&sSettings, sizeof(sSettings)/4 - 1);
  273. }
  274. /**
  275. * @brief
  276. * @retval
  277. */
  278. uint32_t SETTINGS_GetCritSecCRC(void)
  279. {
  280. CRC_ResetDR();
  281. uint32_t critsec_len = (uint32_t)((uint8_t *)(&sSettings.CritSecCRC) - (uint8_t *)&sSettings) / 4;
  282. return CRC_CalcBlockCRC((uint32_t *)&sSettings, critsec_len);
  283. }
  284. /**
  285. * @brief Сброс флага boottry в регистре RTC
  286. */
  287. void SETTINGS_ResetBootTry(void)
  288. {
  289. uint8_t bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2);
  290. if (bootTry > 0 )
  291. {
  292. bootTry = 0;
  293. RTC_WriteBackupRegister(RTC_BKP_DR2, 0);
  294. /* Check FW update flag */
  295. if (RTC_ReadBackupRegister(RTC_BKP_DR3)) {
  296. /* Отправка трапа об успешном обновлении ПО */
  297. #ifndef BT6702_SERVICE
  298. SNMP_SendUserTrap(FW_VERSION_UPDATED);
  299. log_event_data(LOG_UPDATE_SOFT, "Успешно");
  300. #endif
  301. /* Clear FW update flag */
  302. RTC_WriteBackupRegister(RTC_BKP_DR3, 0);
  303. }
  304. }
  305. /* if (sSettings.bootParams.bootTry != 0)
  306. {
  307. sSettings.bootParams.bootTry = 0;
  308. // Отправка трапа об успешном обновлении ПО
  309. SNMP_SendUserTrap(FW_VERSION_UPDATED);
  310. //taskENTER_CRITICAL();
  311. SETTINGS_Save();
  312. //taskEXIT_CRITICAL();
  313. } */
  314. }
  315. /**
  316. * @brief Преобразует mac адрес строкового формата в массив uint8_t
  317. * @param mac - буфер для вывода mac адреса
  318. */
  319. void SETTINGS_GetMac(uint8_t *mac)
  320. {
  321. char dummy[2];
  322. char *macPtr = sSettings.sInfo.mac;
  323. #if defined ( __ICCARM__ )
  324. macPtr = DEVICE_MAC;
  325. #endif
  326. for (uint8_t i = 0; i < 6; i++)
  327. {
  328. strncpy(dummy, macPtr+i*3, 2);
  329. mac[i] = (uint8_t)strtol(dummy, NULL, 16);
  330. }
  331. }
  332. /**
  333. * @brief Установить дату производства
  334. */
  335. void SETTINGS_SetProDate(char *proDate, uint8_t len)
  336. {
  337. SYS_t *sSys = NULL;
  338. sSys = pvPortMalloc(sizeof(*sSys));
  339. if (sSys) {
  340. SYS_Load(sSys);
  341. strcpy(sSys->proddate, proDate);
  342. SYS_Save(sSys);
  343. memset(sSettings.sInfo.productionData, 0, 40);
  344. memcpy(sSettings.sInfo.productionData, proDate, len);
  345. vPortFree(sSys);
  346. SETTINGS_Save();
  347. }
  348. }
  349. /**
  350. * @brief Установить статус тестирования "T2OK"
  351. */
  352. void SETTINGS_SetT2OK(void)
  353. {
  354. SYS_t *sSys = NULL;
  355. sSys = pvPortMalloc(sizeof(*sSys));
  356. if (sSys) {
  357. SYS_Load(sSys);
  358. memset(sSettings.sFlags.testState, 0, 16);
  359. memcpy(sSettings.sFlags.testState, "T2OK", 4);
  360. strcpy(sSys->testState, sSettings.sFlags.testState);
  361. SYS_Save(sSys);
  362. vPortFree(sSys);
  363. SETTINGS_Save();
  364. }
  365. }
  366. /**
  367. * @brief Включить DHCP
  368. */
  369. void SETTINGS_SetDHCPOn(void)
  370. {
  371. sSettings.sWebParams.dhcpEnable = 1;
  372. }
  373. void init_settings(void)
  374. {
  375. flash_mutex = xSemaphoreCreateMutex();
  376. }
  377. /********************************* (C) ROTEK **********************************/