main.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /*
  2. * Copyright (c) 2006-2026, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2026-02-03 RT-Thread first version
  9. */
  10. /*********************↓ define ↓************************/
  11. #define DBG_TAG "main"
  12. #define DBG_LVL DBG_LOG
  13. #define VALID 0x9D
  14. /*********************↑ define ↑************************/
  15. /*********************↓ include ↓************************/
  16. #include <rtthread.h>
  17. #include <rtdbg.h>
  18. #include "main.h"
  19. #include "ym310_mqtt.h"
  20. /*********************↑ include ↑************************/
  21. /*********************↓ extern ↓************************/
  22. extern SYS_INFO sys_info;
  23. extern DEV_INFO dev_info;
  24. extern LIMIT limit;
  25. /*********************↑ extern ↑************************/
  26. /********************↓ declaration ↓***********************/
  27. static void load_from_ef(void);
  28. void Read_para(void);
  29. void RESET_ALL_PARA(void);
  30. static void validate_and_fix_params(void);
  31. /********************↑ declaration ↑***********************/
  32. /*********************↓ global variables ↓************************/
  33. volatile char ef_cfged = 0;
  34. volatile char up_flag = 0;
  35. volatile char upload_ecode = 0;
  36. volatile char update_res = 0;
  37. volatile char upload_res = 0;
  38. /*********************↑ global variables ↑************************/
  39. /* 打印系统参数的函数 */
  40. static void print_system_params(void)
  41. {
  42. LOG_I("========== System Parameters ==========");
  43. LOG_I(" VERSION : %s", version_with_time());
  44. rt_kprintf("\n");
  45. LOG_I(" [SYS_INFO]");
  46. LOG_I(" imei : %s", sys_info.imei[0] ? sys_info.imei : "(empty)");
  47. LOG_I(" iccid : %s", sys_info.iccid[0] ? sys_info.iccid : "(empty)");
  48. LOG_I(" csq : %u", sys_info.csq);
  49. LOG_I(" update_url : %s", sys_info.update_url);
  50. LOG_I(" customer_cfg :");
  51. LOG_I(" sub_topic : %s", sys_info.customer_cfg.sub_topic[0] ? sys_info.customer_cfg.sub_topic : "(empty)");
  52. LOG_I(" pub_topic : %s", sys_info.customer_cfg.pub_topic[0] ? sys_info.customer_cfg.pub_topic : "(empty)");
  53. LOG_I(" host : %s", sys_info.customer_cfg.host[0] ? sys_info.customer_cfg.host : "(empty)");
  54. LOG_I(" port : %u", sys_info.customer_cfg.port);
  55. LOG_I(" qos : %u", sys_info.customer_cfg.qos);
  56. LOG_I(" enable : 0x%02X %s", sys_info.customer_cfg.enable,
  57. (sys_info.customer_cfg.enable == VALID) ? "(开启)" : "(关闭)");
  58. LOG_I(" lastwill : %s", sys_info.customer_cfg.lastwill[0] ? sys_info.customer_cfg.lastwill : "(empty)");
  59. LOG_I(" username : %s", sys_info.customer_cfg.username[0] ? sys_info.customer_cfg.username : "(empty)");
  60. LOG_I(" password : %s", sys_info.customer_cfg.password[0] ? "(已设置)" : "(empty)");
  61. if (strstr(sys_info.customer_cfg.client_id, "USE_IMEI") != NULL)
  62. {
  63. LOG_I(" client_id : %s", sys_info.imei[0] ? sys_info.imei : "(empty)");
  64. }
  65. else
  66. {
  67. LOG_I(" client_id : %s", sys_info.customer_cfg.client_id[0] ? sys_info.customer_cfg.client_id : "(empty)");
  68. }
  69. rt_kprintf("\n");
  70. LOG_I(" [DEV_INFO]");
  71. // LOG_I(" work_state : %u %s", dev_info.work_state,
  72. // dev_info.work_state == 0 ? "(待机)" : dev_info.work_state == 1 ? "(工作)"
  73. // : dev_info.work_state == 2 ? "(充电)"
  74. // : "");
  75. LOG_I(" power_state : %u %s", dev_info.power_state, dev_info.power_state ? "(开机)" : "(关机)");
  76. LOG_I(" light_work_duration : %u", dev_info.light_work_duration);
  77. LOG_I(" time_ctrl_enable : %u", dev_info.time_ctrl_enable);
  78. LOG_I(" time_start : %u", dev_info.time_start);
  79. LOG_I(" time_end : %u", dev_info.time_end);
  80. // LOG_I(" undervolt_protect : %u", dev_info.undervolt_protect);
  81. // LOG_I(" temp_protect : %u", dev_info.temp_protect);
  82. // LOG_I(" tilt_protect : %u", dev_info.tilt_protect);
  83. // LOG_I(" rain_protect : %u", dev_info.rain_protect);
  84. LOG_I(" light_flag : %u", dev_info.light_flag);
  85. // LOG_I(" hv_count : %u", dev_info.hv_count);
  86. // LOG_I(" charge_voltage : %u mV (%d.%03d V)",
  87. // dev_info.charge_voltage,
  88. // dev_info.charge_voltage / 1000,
  89. // dev_info.charge_voltage % 1000);
  90. // LOG_I(" battery_voltage : %u mV (%d.%03d V)",
  91. // dev_info.battery_voltage,
  92. // dev_info.battery_voltage / 1000,
  93. // dev_info.battery_voltage % 1000);
  94. //
  95. // LOG_I(" board_temp : %d (°C)", dev_info.board_temp);
  96. // LOG_I(" lamp_fault : %u %s", dev_info.lamp_fault, dev_info.lamp_fault ? "(故障)" : "(正常)");
  97. // LOG_I(" idle_flag : %u", dev_info.idle_flag);
  98. LOG_I(" data_interval : %u min", dev_info.data_interval);
  99. LOG_I(" clean_interval : %u min", dev_info.clean_interval);
  100. LOG_I(" clean_enable : %u %s", dev_info.clean_enable, dev_info.clean_enable ? "(开启)" : "(关闭)");
  101. LOG_I(" gps_mode : %u", dev_info.GPS_MODE);
  102. LOG_I(" longitude : %s", dev_info.longitude[0] ? dev_info.longitude : "(empty)");
  103. LOG_I(" latitude : %s", dev_info.latitude[0] ? dev_info.latitude : "(empty)");
  104. rt_kprintf("\n");
  105. LOG_I(" [LIMIT]");
  106. LOG_I(" vsunrise : %u", limit.vsunrise);
  107. LOG_I(" vsunset : %u", limit.vsunset);
  108. LOG_I(" vcutof : %u", limit.vcutof);
  109. LOG_I(" vfloat : %u", limit.vfloat);
  110. LOG_I(" vrecharge : %u", limit.vrecharge);
  111. LOG_I(" uvstart : %u", limit.uvstart);
  112. LOG_I(" uvoff : %u", limit.uvoff);
  113. LOG_I(" uvon : %u", limit.uvon);
  114. LOG_I(" overtemp : %u", limit.overtemp);
  115. LOG_I(" lowtemp : %u", limit.lowtemp);
  116. LOG_I(" unovert : %u", limit.unovert);
  117. LOG_I(" unlowt : %u", limit.unlowt);
  118. LOG_I(" battype : %u", limit.battype);
  119. }
  120. void save_sys_info(void)
  121. {
  122. int ret = ef_set_env_blob(EF_SYS_INFO, &sys_info, sizeof(sys_info));
  123. LOG_W("sys_info save %d ", ret);
  124. if (ret == EF_NO_ERR)
  125. {
  126. parabak_backup(PARABAK_ID_SYS_INFO);
  127. }
  128. }
  129. void save_dev_info(void)
  130. {
  131. int ret = ef_set_env_blob(EF_DEV_INFO, &dev_info, sizeof(dev_info));
  132. LOG_W("dev_info save %d ", ret);
  133. if (ret == EF_NO_ERR)
  134. {
  135. parabak_backup(PARABAK_ID_DEV_INFO);
  136. }
  137. }
  138. void save_limit(void)
  139. {
  140. int ret = ef_set_env_blob(EF_LIMIT, &limit, sizeof(limit));
  141. LOG_W("limit save %d ", ret);
  142. if (ret == EF_NO_ERR)
  143. {
  144. parabak_backup(PARABAK_ID_LIMIT);
  145. }
  146. }
  147. static sys_info_reset(void)
  148. {
  149. rt_memset(&sys_info, 0, sizeof(sys_info));
  150. rt_strncpy(sys_info.customer_cfg.sub_topic, "/yfkj/scd/sub", sizeof(sys_info.customer_cfg.sub_topic) - 1);
  151. rt_strncpy(sys_info.customer_cfg.pub_topic, "/yfkj/scd/pub", sizeof(sys_info.customer_cfg.pub_topic) - 1);
  152. rt_strncpy(sys_info.customer_cfg.host, "120.27.222.26", sizeof(sys_info.customer_cfg.host) - 1);
  153. sys_info.customer_cfg.port = 1883;
  154. sys_info.customer_cfg.qos = 0;
  155. sys_info.customer_cfg.enable = 0; /* 默认关闭 */
  156. save_sys_info();
  157. }
  158. static dev_info_reset(void)
  159. {
  160. rt_memset(&dev_info, 0, sizeof(dev_info));
  161. dev_info.light_work_duration = 4;
  162. dev_info.data_interval = 10;
  163. dev_info.clean_interval = 30;
  164. dev_info.clean_enable = 0; // 自清虫
  165. dev_info.power_state = 1;
  166. dev_info.time_start = 20;
  167. dev_info.time_end = 2;
  168. dev_info.light_flag = 0;
  169. dev_info.GPS_MODE = 1;
  170. save_dev_info();
  171. }
  172. static limit_reset(void)
  173. {
  174. rt_memset(&limit, 0, sizeof(limit));
  175. limit.uvoff = 3700; // 欠压恢复 = 3.7V
  176. limit.uvon = 3500; // 欠压开启 = 3.5V
  177. limit.overtemp = 700; // 高温保护 = 70度
  178. limit.unovert = 500; // 高温恢复 = 50
  179. limit.lowtemp = 100; // 低温保护 = 10
  180. limit.unlowt = 150; // 低温恢复 = 15
  181. limit.vsunrise = 3300; // 日出电压=3.3V
  182. limit.vsunset = 1500; // 日落电压=1.5V
  183. save_limit();
  184. }
  185. static void load_from_ef(void)
  186. {
  187. size_t read_len;
  188. read_len = ef_get_env_blob(EF_SYS_INFO, &sys_info, sizeof(sys_info), NULL);
  189. if (read_len != sizeof(sys_info))
  190. {
  191. int bak_state = parabak_self_check(PARABAK_ID_SYS_INFO, NULL);
  192. if (bak_state == 1)
  193. {
  194. LOG_I("sys_info EF read failed but backup valid, will restore later");
  195. }
  196. else
  197. {
  198. LOG_W("No valid sys_info in EF, use default > read_len %d ", read_len);
  199. Recode_e_code(e_para_setdef, 1, "sys_info使用默认参数");
  200. sys_info_reset();
  201. }
  202. }
  203. read_len = ef_get_env_blob(EF_DEV_INFO, &dev_info, sizeof(dev_info), NULL);
  204. if (read_len != sizeof(dev_info))
  205. {
  206. int bak_state = parabak_self_check(PARABAK_ID_DEV_INFO, NULL);
  207. if (bak_state == 1)
  208. {
  209. LOG_I("dev_info EF read failed but backup valid, will restore later");
  210. }
  211. else
  212. {
  213. LOG_W("No valid dev_info in EF, use default > read_len %d ", read_len);
  214. Recode_e_code(e_para_setdef, 2, "dev_info使用默认参数");
  215. dev_info_reset();
  216. }
  217. }
  218. read_len = ef_get_env_blob(EF_LIMIT, &limit, sizeof(limit), NULL);
  219. if (read_len != sizeof(limit))
  220. {
  221. int bak_state = parabak_self_check(PARABAK_ID_LIMIT, NULL);
  222. if (bak_state == 1)
  223. {
  224. LOG_I("limit EF read failed but backup valid, will restore later");
  225. }
  226. else
  227. {
  228. LOG_W("No valid limit in EF, use default > read_len %d ", read_len);
  229. Recode_e_code(e_para_setdef, 3, "limit使用默认参数");
  230. limit_reset();
  231. }
  232. }
  233. LOG_I("Loaded from EasyFlash");
  234. }
  235. void RESET_ALL_PARA(void)
  236. {
  237. ef_env_set_default();
  238. sys_info_reset();
  239. dev_info_reset();
  240. limit_reset();
  241. Recode_e_code(e_para_setdef, 0, "强制恢复默认参数");
  242. }
  243. void Read_para(void)
  244. {
  245. uint32_t start_time = 0;
  246. ef_get_env_blob("start_time", &start_time, sizeof(start_time), NULL);
  247. start_time++;
  248. ef_set_env_blob("start_time", &start_time, sizeof(start_time));
  249. LOG_I("System started on %d times.", start_time);
  250. ef_get_env_blob("up_flag", &up_flag, sizeof(up_flag), NULL);
  251. ef_get_env_blob("upload_ecode", &upload_ecode, sizeof(upload_ecode), NULL);
  252. ef_get_env_blob("update_res", &update_res, sizeof(update_res), NULL);
  253. ef_get_env_blob("upload_res", &upload_res, sizeof(upload_res), NULL);
  254. }
  255. /*********************↓ parameter validation ↓***********************/
  256. /**
  257. * @brief 校验并修正设备参数和限制参数的范围
  258. *
  259. * 默认值参考 dev_info_reset() 和 limit_reset()
  260. * 只校验这两个函数中出现的参数
  261. */
  262. static void validate_and_fix_params(void)
  263. {
  264. uint8_t need_save_dev = 0;
  265. uint8_t need_save_limit = 0;
  266. char ecode_buf[50];
  267. LOG_I("========== Parameter Validation Started ==========");
  268. /* ========== DEV_INFO 参数校验(默认值参考 dev_info_reset) ========== */
  269. /* 1. data_interval: 数据上报间隔 (5-180分钟),默认10 */
  270. if (dev_info.data_interval < 5 || dev_info.data_interval > 180)
  271. {
  272. uint16_t old_val = dev_info.data_interval;
  273. LOG_W("data_interval out of range [5,180]: %u, reset to default 10", old_val);
  274. rt_snprintf(ecode_buf, sizeof(ecode_buf), "上报间隔非法值=%u 恢复默认=10", old_val);
  275. Recode_e_code(e_para_setdef, 10, ecode_buf);
  276. dev_info.data_interval = 10;
  277. need_save_dev = 1;
  278. }
  279. /* 2. light_work_duration: 光控工作时长 (0-10小时),默认4 */
  280. if (dev_info.light_work_duration > 10)
  281. {
  282. uint16_t old_val = dev_info.light_work_duration;
  283. LOG_W("light_work_duration out of range [0,10]: %u, reset to default 4", old_val);
  284. rt_snprintf(ecode_buf, sizeof(ecode_buf), "工作时长非法值=%u 恢复默认=4", old_val);
  285. Recode_e_code(e_para_setdef, 11, ecode_buf);
  286. dev_info.light_work_duration = 4;
  287. need_save_dev = 1;
  288. }
  289. /* 3. clean_interval: 清扫间隔 (5-180分钟),默认30 */
  290. if (dev_info.clean_interval < 5 || dev_info.clean_interval > 180)
  291. {
  292. uint16_t old_val = dev_info.clean_interval;
  293. LOG_W("clean_interval out of range [5,180]: %u, reset to default 30", old_val);
  294. rt_snprintf(ecode_buf, sizeof(ecode_buf), "清扫间隔非法值=%u 恢复默认=30", old_val);
  295. Recode_e_code(e_para_setdef, 12, ecode_buf);
  296. dev_info.clean_interval = 30;
  297. need_save_dev = 1;
  298. }
  299. /* 4. clean_enable: 自清虫标志 (0-1),默认0 */
  300. if (dev_info.clean_enable > 1)
  301. {
  302. uint8_t old_val = dev_info.clean_enable;
  303. LOG_W("clean_enable out of range [0,1]: %u, reset to default 0", old_val);
  304. rt_snprintf(ecode_buf, sizeof(ecode_buf), "自清虫标志非法值=%u 恢复默认=0", old_val);
  305. Recode_e_code(e_para_setdef, 13, ecode_buf);
  306. dev_info.clean_enable = 0;
  307. need_save_dev = 1;
  308. }
  309. /* 5. power_state: 开关机状态 (0-1),默认1 */
  310. if (dev_info.power_state > 1)
  311. {
  312. uint8_t old_val = dev_info.power_state;
  313. LOG_W("power_state out of range [0,1]: %u, reset to default 1", old_val);
  314. rt_snprintf(ecode_buf, sizeof(ecode_buf), "开关机状态非法值=%u 恢复默认=1", old_val);
  315. Recode_e_code(e_para_setdef, 14, ecode_buf);
  316. dev_info.power_state = 1;
  317. need_save_dev = 1;
  318. }
  319. /* 6. time_start: 时控开始小时 (0-23),默认20 */
  320. if (dev_info.time_start > 23)
  321. {
  322. uint8_t old_val = dev_info.time_start;
  323. LOG_W("time_start out of range [0,23]: %u, reset to default 20", old_val);
  324. rt_snprintf(ecode_buf, sizeof(ecode_buf), "时控开始非法值=%u 恢复默认=20", old_val);
  325. Recode_e_code(e_para_setdef, 15, ecode_buf);
  326. dev_info.time_start = 20;
  327. need_save_dev = 1;
  328. }
  329. /* 7. time_end: 时控结束小时 (0-23),默认2 */
  330. if (dev_info.time_end > 23)
  331. {
  332. uint8_t old_val = dev_info.time_end;
  333. LOG_W("time_end out of range [0,23]: %u, reset to default 2", old_val);
  334. rt_snprintf(ecode_buf, sizeof(ecode_buf), "时控结束非法值=%u 恢复默认=2", old_val);
  335. Recode_e_code(e_para_setdef, 16, ecode_buf);
  336. dev_info.time_end = 2;
  337. need_save_dev = 1;
  338. }
  339. /* 8. light_flag: 光控切换标志位 (0-1),默认0 */
  340. if (dev_info.light_flag > 1)
  341. {
  342. uint8_t old_val = dev_info.light_flag;
  343. LOG_W("light_flag out of range [0,1]: %u, reset to default 0", old_val);
  344. rt_snprintf(ecode_buf, sizeof(ecode_buf), "光控源非法值=%u 恢复默认=0", old_val);
  345. Recode_e_code(e_para_setdef, 17, ecode_buf);
  346. dev_info.light_flag = 0;
  347. need_save_dev = 1;
  348. }
  349. /* 9. GPS_MODE: GPS模式 (0-1),默认1 */
  350. if ((dev_info.GPS_MODE > 1) || (((strlen(dev_info.latitude_FORCE) < 5) || (strlen(dev_info.longitude_FORCE) < 5)) && (dev_info.GPS_MODE == 0)))
  351. {
  352. uint8_t old_val = dev_info.GPS_MODE;
  353. LOG_W("GPS_MODE out of range [0,1]: %u, reset to default 1", old_val);
  354. rt_snprintf(ecode_buf, sizeof(ecode_buf), "GPS模式非法值=%u 恢复默认=1", old_val);
  355. Recode_e_code(e_para_setdef, 18, ecode_buf);
  356. dev_info.GPS_MODE = 1;
  357. need_save_dev = 1;
  358. }
  359. /* ========== LIMIT 参数校验(默认值参考 limit_reset) ========== */
  360. /* 10. uvoff: 欠压恢复电压 (1000-5000 mV),默认3700 */
  361. if (limit.uvoff < 1000 || limit.uvoff > 5000)
  362. {
  363. uint16_t old_val = limit.uvoff;
  364. LOG_W("uvoff out of range [1000,5000]: %u, reset to default 3700", old_val);
  365. rt_snprintf(ecode_buf, sizeof(ecode_buf), "欠压恢复非法值=%u 恢复默认=3700", old_val);
  366. Recode_e_code(e_para_setdef, 20, ecode_buf);
  367. limit.uvoff = 3700;
  368. need_save_limit = 1;
  369. }
  370. /* 11. uvon: 欠压保护电压 (1000-5000 mV),默认3500 */
  371. if (limit.uvon < 1000 || limit.uvon > 5000)
  372. {
  373. uint16_t old_val = limit.uvon;
  374. LOG_W("uvon out of range [1000,5000]: %u, reset to default 3500", old_val);
  375. rt_snprintf(ecode_buf, sizeof(ecode_buf), "欠压开启非法值=%u恢复默认=3500", old_val);
  376. Recode_e_code(e_para_setdef, 21, ecode_buf);
  377. limit.uvon = 3500;
  378. need_save_limit = 1;
  379. }
  380. /* 12. overtemp: 高温保护温度 (300-800, 即30-80°C),默认700 */
  381. if (limit.overtemp < 300 || limit.overtemp > 800)
  382. {
  383. uint16_t old_val = limit.overtemp;
  384. LOG_W("overtemp out of range [300,800]: %u, reset to default 700", old_val);
  385. rt_snprintf(ecode_buf, sizeof(ecode_buf), "高温保护非法值=%u 恢复默认=700", old_val);
  386. Recode_e_code(e_para_setdef, 22, ecode_buf);
  387. limit.overtemp = 700;
  388. need_save_limit = 1;
  389. }
  390. /* 13. unovert: 高温恢复温度 (200-700, 即20-70°C),默认500 */
  391. if (limit.unovert < 200 || limit.unovert > 700)
  392. {
  393. uint16_t old_val = limit.unovert;
  394. LOG_W("unovert out of range [200,700]: %u, reset to default 500", old_val);
  395. rt_snprintf(ecode_buf, sizeof(ecode_buf), "高温恢复非法值=%u 恢复默认=500", old_val);
  396. Recode_e_code(e_para_setdef, 23, ecode_buf);
  397. limit.unovert = 500;
  398. need_save_limit = 1;
  399. }
  400. /* 14. lowtemp: 低温保护温度 (-200-100, 即-20-10°C),默认100 (10°C) */
  401. if ((int16_t)limit.lowtemp < -200 || (int16_t)limit.lowtemp > 100)
  402. {
  403. int16_t old_val = (int16_t)limit.lowtemp;
  404. LOG_W("lowtemp out of range [-200,100]: %d, reset to default 100", old_val);
  405. rt_snprintf(ecode_buf, sizeof(ecode_buf), "低温保护非法值=%d 恢复默认=100", old_val);
  406. Recode_e_code(e_para_setdef, 24, ecode_buf);
  407. limit.lowtemp = 100;
  408. need_save_limit = 1;
  409. }
  410. /* 15. unlowt: 低温恢复温度 (-150-150, 即-15-15°C),默认150 (15°C) */
  411. if ((int16_t)limit.unlowt < -150 || (int16_t)limit.unlowt > 150)
  412. {
  413. int16_t old_val = (int16_t)limit.unlowt;
  414. LOG_W("unlowt out of range [-150,150]: %d, reset to default 150", old_val);
  415. rt_snprintf(ecode_buf, sizeof(ecode_buf), "低温恢复非法值=%d 恢复默认=150", old_val);
  416. Recode_e_code(e_para_setdef, 25, ecode_buf);
  417. limit.unlowt = 150;
  418. need_save_limit = 1;
  419. }
  420. /* 16. vsunrise: 日出电压 (1000-5000 mV),默认3300 */
  421. if (limit.vsunrise < 1000 || limit.vsunrise > 5000)
  422. {
  423. uint16_t old_val = limit.vsunrise;
  424. LOG_W("vsunrise out of range [1000,5000]: %u, reset to default 3300", old_val);
  425. rt_snprintf(ecode_buf, sizeof(ecode_buf), "日出电压非法值=%u 恢复默认=3300", old_val);
  426. Recode_e_code(e_para_setdef, 26, ecode_buf);
  427. limit.vsunrise = 3300;
  428. need_save_limit = 1;
  429. }
  430. /* 17. vsunset: 日落电压 (1000-5000 mV),默认1500 */
  431. if (limit.vsunset < 1000 || limit.vsunset > 5000)
  432. {
  433. uint16_t old_val = limit.vsunset;
  434. LOG_W("vsunset out of range [1000,5000]: %u, reset to default 1500", old_val);
  435. rt_snprintf(ecode_buf, sizeof(ecode_buf), "日落电压非法值=%u 恢复默认=1500", old_val);
  436. Recode_e_code(e_para_setdef, 27, ecode_buf);
  437. limit.vsunset = 1500;
  438. need_save_limit = 1;
  439. }
  440. /* ========== 保存修正后的参数 ========== */
  441. if (need_save_dev)
  442. {
  443. save_dev_info();
  444. LOG_I("DEV_INFO validation completed: parameters fixed and saved");
  445. }
  446. if (need_save_limit)
  447. {
  448. save_limit();
  449. LOG_I("LIMIT validation completed: parameters fixed and saved");
  450. }
  451. if (!need_save_dev && !need_save_limit)
  452. {
  453. LOG_I("Parameter validation completed: all parameters are valid");
  454. }
  455. LOG_I("========== Parameter Validation Finished ==========");
  456. }
  457. /*********************↑ parameter validation ↑***********************/
  458. /* App工程 - 打印SCD APP花字 */
  459. static void print_app_logo(void)
  460. {
  461. rt_kprintf("\033[38;5;37m");
  462. rt_kprintf("╔══════════════════════════════════════════════════════════╗\n");
  463. rt_kprintf("║ ║\n");
  464. rt_kprintf("║ ███████╗ ██████╗██████╗ █████╗ ██████╗ ██████╗ ║\n");
  465. rt_kprintf("║ ██╔════╝██╔════╝██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗ ║\n");
  466. rt_kprintf("║ ███████╗██║ ██║ ██║ ███████║██████╔╝██████╔╝ ║\n");
  467. rt_kprintf("║ ╚════██║██║ ██║ ██║ ██╔══██║██╔═══╝ ██╔═══╝ ║\n");
  468. rt_kprintf("║ ███████║╚██████╗██████╔╝ ██║ ██║██║ ██║ ║\n");
  469. rt_kprintf("║ ╚══════╝ ╚═════╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ║\n");
  470. rt_kprintf("║ ║\n");
  471. rt_kprintf("║ APP V%s ║\n", version_with_time());
  472. rt_kprintf("╚══════════════════════════════════════════════════════════╝\n");
  473. rt_kprintf("\033[0m\n");
  474. }
  475. int main(void)
  476. {
  477. // rt_thread_mdelay(10);
  478. print_app_logo();
  479. rt_thread_mdelay(1000);
  480. int countdown = 0;
  481. if (easyflash_init() == EF_NO_ERR)
  482. {
  483. Read_para();
  484. load_from_ef();
  485. validate_and_fix_params(); // 添加参数范围校验
  486. ef_cfged = 1;
  487. parabak_auto_check();
  488. print_system_params(); // 打印所有参数
  489. }
  490. if ((up_flag != VALID) && (upload_ecode != VALID)) // 初始化联网
  491. {
  492. if (ym310_driver_init() != RT_EOK)
  493. {
  494. LOG_E("YM310 init failed!");
  495. return -1;
  496. }
  497. }
  498. else if (up_flag == VALID) // 开始执行升级操作
  499. {
  500. while (1)
  501. {
  502. countdown++;
  503. rt_thread_mdelay(1000);
  504. if (countdown > 10 * 60)
  505. {
  506. break;
  507. }
  508. }
  509. rt_kprintf("wait for upguard time out ! %d\n", countdown);
  510. up_flag = 0;
  511. ef_set_env_blob("up_flag", &up_flag, sizeof(up_flag));
  512. Recode_e_code(e_update_timeout, countdown, "MAIN:等待升级完成超时");
  513. rt_thread_mdelay(500);
  514. rt_hw_cpu_reset();
  515. }
  516. else if (upload_ecode == VALID) // 开始执行升级操作
  517. {
  518. while (1)
  519. {
  520. countdown++;
  521. rt_thread_mdelay(1000);
  522. if (countdown > 10 * 60)
  523. {
  524. break;
  525. }
  526. }
  527. rt_kprintf("wait for upguard time out ! %d\n", countdown);
  528. upload_ecode = 0;
  529. ef_set_env_blob("upload_ecode", &upload_ecode, sizeof(upload_ecode));
  530. Recode_e_code(e_update_timeout, countdown, "MAIN:等待上报EC完成超时");
  531. rt_thread_mdelay(500);
  532. rt_hw_cpu_reset();
  533. }
  534. // while(1)
  535. // {
  536. // Recode_e_code(e_test_fun, 6, "3-6是一条msh测试数据123456789");
  537. // rt_thread_mdelay(1000);
  538. // }
  539. return RT_EOK;
  540. }