freertos.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * File Name : freertos.c
  5. * Description : Code for freertos applications
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2025 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "FreeRTOS.h"
  21. #include "task.h"
  22. #include "main.h"
  23. #include "cmsis_os.h"
  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "dma.h"
  27. #include "spi.h"
  28. #include "queue.h"
  29. #include "kv_flash.h"
  30. /* USER CODE END Includes */
  31. /* Private typedef -----------------------------------------------------------*/
  32. typedef StaticQueue_t osStaticMessageQDef_t;
  33. /* USER CODE BEGIN PTD */
  34. /* USER CODE END PTD */
  35. /* Private define ------------------------------------------------------------*/
  36. /* USER CODE BEGIN PD */
  37. /* USER CODE END PD */
  38. /* Private macro -------------------------------------------------------------*/
  39. /* USER CODE BEGIN PM */
  40. bool DB_init_flag = false; // 数据库初始化标志位
  41. extern uint8_t dataReceive485[BUFFER_SIZE485]; // 485串口接收缓冲区
  42. extern uint8_t dataReceivep[BUFFER_SIZEP]; // 调试串口接收buffer
  43. extern uint32_t uartIRQ_rx_len ; // 485串口接收数据长度
  44. sysmode Systemmode;
  45. extern bool erase_APP2;
  46. extern bool erase_APPdata_buffer;
  47. extern bool save_JsRoot_0100_flag;
  48. extern uint32_t expected_file_size; // 升级文件大小值
  49. extern uint16_t upgrade_mode_subcode; // 记录使用的subcode(0x0100 或 0x0200)
  50. /*控制台打印信息控制符*/
  51. volatile uint8_t debug_print_enabled = 0; // 默认关闭调试打印
  52. volatile uint8_t fdc_print_enabled = 0; // 默认关闭电容打印
  53. volatile uint8_t ads_print_enabled = 0; // 默认关闭ADS打印
  54. volatile uint8_t kv_print_enabled = 0; // 默认关闭KV数据库打印
  55. /*阀杆相关参数定义*/
  56. volatile float ADS_v0 = 0.0f; // ads1256 通道0原始电压值
  57. volatile float ADS_v0_offset = 0.008f; // ads1256 通道0电压偏移 0.008
  58. volatile float filtered_ADS_v0 = 0.0f; // 滤波之后的阀杆压力值(kpa)
  59. volatile float MPXV_P0 = 0.0f; // 电压转换后的阀杆压力值(kpa)
  60. volatile float Value_open_mm = 0.0f; // 阀杆行程毫米
  61. volatile float Value_open_percent = 0.0f; // 阀杆开行程百分比
  62. //volatile float // 阀杆压力值滤波滑动窗口大小
  63. /*油水相关参数定义*/ // 多线程环境修改的共享变量
  64. volatile float oil_para_indu = 18.0f; // 并联电感值
  65. volatile float oil_para_cap = 33.0f; // 并联电容值
  66. volatile float oil_cap = 0.0f;// 软件IIC 1号(PB10PB11)测得电容值
  67. volatile float oil_cap_offset = 0.0f;// 油水电容偏移值 43.1f
  68. volatile float filtered_oil_cap = 0.0f; // 滤波之后的油水电容值
  69. volatile float oil_percent = 0.0f; // 油水百分比
  70. //volatile float // 油水电容值滤波滑动窗口大小
  71. /*余油相关参数定义*/
  72. volatile float res_oil_para_indu = 18.0f; // 并联电感值
  73. volatile float res_oil_para_cap = 33.0f; // 并联电容值
  74. volatile float res_oil_cap = 0.0f; // // 软件IIC 2号(PB10PB11)测得电容值
  75. volatile float res_oil_cap_offset = 0.0f;// 余油电容偏移值 43.1f
  76. volatile float filtered_res_oil_cap = 0.0f; // 滤波之后的电容值
  77. volatile float ADS_v1 = 0.0f; // ads1256 通道1原始电压值
  78. volatile float ADS_v1_offset = 0.008f; // ads1256 通道1电压偏移值
  79. volatile float filtered_ADS_v1 = 0.0f; // 滤波之后的余油电压值
  80. volatile float MPXV_P1 = 0.0f; // 余油压力值(kpa)
  81. volatile float res_oil_height = 0.0f; // 余油高度值(mm)
  82. //volatile float // 余油压力值滤波滑动窗口大小
  83. /*温度相关参数定义*/
  84. volatile float ADS_v2 = 0.0f; // ads1256 通道2原始电压值
  85. volatile float ADS_v2_offset = 0.0f; // ads1256 通道2电压偏移值
  86. volatile float filtered_ADS_v2 = 0.0f; // 滤波之后的电压值
  87. volatile float NTC_temp = 0.0f; // 电压查RT表转换后的温度值(℃)
  88. //volatile float // 温度滤波滑动窗口大小
  89. /* USER CODE END PM */
  90. /* Private variables ---------------------------------------------------------*/
  91. /* USER CODE BEGIN Variables */
  92. extern IWDG_HandleTypeDef hiwdg;
  93. /* USER CODE END Variables */
  94. /* Definitions for HighestTask */
  95. osThreadId_t HighestTaskHandle;
  96. const osThreadAttr_t HighestTask_attributes = {
  97. .name = "HighestTask",
  98. .stack_size = 256 * 4,
  99. .priority = (osPriority_t) osPriorityRealtime,
  100. };
  101. /* Definitions for ReadTask */
  102. osThreadId_t ReadTaskHandle;
  103. const osThreadAttr_t ReadTask_attributes = {
  104. .name = "ReadTask",
  105. .stack_size = 256 * 4,
  106. .priority = (osPriority_t) osPriorityNormal,
  107. };
  108. /* Definitions for DealTask */
  109. osThreadId_t DealTaskHandle;
  110. const osThreadAttr_t DealTask_attributes = {
  111. .name = "DealTask",
  112. .stack_size = 512 * 4,
  113. .priority = (osPriority_t) osPriorityNormal,
  114. };
  115. /* Definitions for CommonTask */
  116. osThreadId_t CommonTaskHandle;
  117. const osThreadAttr_t CommonTask_attributes = {
  118. .name = "CommonTask",
  119. .stack_size = 512 * 4,
  120. .priority = (osPriority_t) osPriorityBelowNormal,
  121. };
  122. /* Definitions for ReadTask02 */
  123. osThreadId_t ReadTask02Handle;
  124. const osThreadAttr_t ReadTask02_attributes = {
  125. .name = "ReadTask02",
  126. .stack_size = 256 * 4,
  127. .priority = (osPriority_t) osPriorityNormal,
  128. };
  129. /* Definitions for FilterTask */
  130. osThreadId_t FilterTaskHandle;
  131. const osThreadAttr_t FilterTask_attributes = {
  132. .name = "FilterTask",
  133. .stack_size = 128 * 4,
  134. .priority = (osPriority_t) osPriorityAboveNormal,
  135. };
  136. /* Definitions for uart485rxqueue */
  137. osMessageQueueId_t uart485rxqueueHandle;
  138. uint8_t uart485queueBuffer[ 20 * sizeof( Uart485Rx_msg ) ];
  139. osStaticMessageQDef_t uart485queueControlBlock;
  140. const osMessageQueueAttr_t uart485rxqueue_attributes = {
  141. .name = "uart485rxqueue",
  142. .cb_mem = &uart485queueControlBlock,
  143. .cb_size = sizeof(uart485queueControlBlock),
  144. .mq_mem = &uart485queueBuffer,
  145. .mq_size = sizeof(uart485queueBuffer)
  146. };
  147. /* Definitions for printqueue */
  148. osMessageQueueId_t printqueueHandle;
  149. uint8_t printqueueBuffer[ 32 * sizeof( Print_msg ) ];
  150. osStaticMessageQDef_t printqueueControlBlock;
  151. const osMessageQueueAttr_t printqueue_attributes = {
  152. .name = "printqueue",
  153. .cb_mem = &printqueueControlBlock,
  154. .cb_size = sizeof(printqueueControlBlock),
  155. .mq_mem = &printqueueBuffer,
  156. .mq_size = sizeof(printqueueBuffer)
  157. };
  158. /* Definitions for consolemsgqueue */
  159. osMessageQueueId_t consolemsgqueueHandle;
  160. uint8_t consolemsgqueueBuffer[ 32 * sizeof( Console_msg ) ];
  161. osStaticMessageQDef_t consolemsgqueueControlBlock;
  162. const osMessageQueueAttr_t consolemsgqueue_attributes = {
  163. .name = "consolemsgqueue",
  164. .cb_mem = &consolemsgqueueControlBlock,
  165. .cb_size = sizeof(consolemsgqueueControlBlock),
  166. .mq_mem = &consolemsgqueueBuffer,
  167. .mq_size = sizeof(consolemsgqueueBuffer)
  168. };
  169. /* Definitions for filterqueue3 */
  170. osMessageQueueId_t filterqueue3Handle;
  171. uint8_t filterqueue3Buffer[ 30 * sizeof( Filter_msg3 ) ];
  172. osStaticMessageQDef_t filterqueue3ControlBlock;
  173. const osMessageQueueAttr_t filterqueue3_attributes = {
  174. .name = "filterqueue3",
  175. .cb_mem = &filterqueue3ControlBlock,
  176. .cb_size = sizeof(filterqueue3ControlBlock),
  177. .mq_mem = &filterqueue3Buffer,
  178. .mq_size = sizeof(filterqueue3Buffer)
  179. };
  180. /* Definitions for filterqueue2 */
  181. osMessageQueueId_t filterqueue2Handle;
  182. uint8_t filterqueue2Buffer[ 30 * sizeof( Filter_msg2 ) ];
  183. osStaticMessageQDef_t filterqueue2ControlBlock;
  184. const osMessageQueueAttr_t filterqueue2_attributes = {
  185. .name = "filterqueue2",
  186. .cb_mem = &filterqueue2ControlBlock,
  187. .cb_size = sizeof(filterqueue2ControlBlock),
  188. .mq_mem = &filterqueue2Buffer,
  189. .mq_size = sizeof(filterqueue2Buffer)
  190. };
  191. /* Definitions for filterqueue1 */
  192. osMessageQueueId_t filterqueue1Handle;
  193. uint8_t filterqueue1Buffer[ 30 * sizeof( Filter_msg1 ) ];
  194. osStaticMessageQDef_t filterqueue1ControlBlock;
  195. const osMessageQueueAttr_t filterqueue1_attributes = {
  196. .name = "filterqueue1",
  197. .cb_mem = &filterqueue1ControlBlock,
  198. .cb_size = sizeof(filterqueue1ControlBlock),
  199. .mq_mem = &filterqueue1Buffer,
  200. .mq_size = sizeof(filterqueue1Buffer)
  201. };
  202. /* Definitions for filterqueue4 */
  203. osMessageQueueId_t filterqueue4Handle;
  204. uint8_t filterqueue4Buffer[ 30 * sizeof( Filter_msg4 ) ];
  205. osStaticMessageQDef_t filterqueue4ControlBlock;
  206. const osMessageQueueAttr_t filterqueue4_attributes = {
  207. .name = "filterqueue4",
  208. .cb_mem = &filterqueue4ControlBlock,
  209. .cb_size = sizeof(filterqueue4ControlBlock),
  210. .mq_mem = &filterqueue4Buffer,
  211. .mq_size = sizeof(filterqueue4Buffer)
  212. };
  213. /* Definitions for filterqueue5 */
  214. osMessageQueueId_t filterqueue5Handle;
  215. uint8_t filterqueue5Buffer[ 30 * sizeof( Filter_msg5 ) ];
  216. osStaticMessageQDef_t filterqueue5ControlBlock;
  217. const osMessageQueueAttr_t filterqueue5_attributes = {
  218. .name = "filterqueue5",
  219. .cb_mem = &filterqueue5ControlBlock,
  220. .cb_size = sizeof(filterqueue5ControlBlock),
  221. .mq_mem = &filterqueue5Buffer,
  222. .mq_size = sizeof(filterqueue5Buffer)
  223. };
  224. /* Private function prototypes -----------------------------------------------*/
  225. /* USER CODE BEGIN FunctionPrototypes */
  226. void pack_filtered_cap(void); // float filtered_cap --> uint32_t uint_filtered_cap
  227. void UART1_Watchdog_Check(void);
  228. osStatus_t QueuePutOverwrite(osMessageQueueId_t queue_id, const void *msg_ptr, uint8_t priority, uint32_t timeout);
  229. void ProcessFDC2214( uint8_t* init_ready_flag, uint8_t* valid_flag, uint8_t channel, uint8_t inductor, uint8_t par_capacitor, float zeroValue, uint8_t device_index);
  230. void CheckFDC2214_ID(uint8_t device_index, uint8_t* init_ready_flag, uint8_t* deviceValid);
  231. void TProcessFDC2214( uint8_t* init_ready_flag, uint8_t* valid_flag, uint8_t channel, uint8_t inductor, uint8_t par_capacitor, float zeroValue, uint8_t device_index);
  232. void TCheckFDC2214_ID(uint8_t device_index, uint8_t* init_ready_flag, uint8_t* deviceValid);
  233. /* USER CODE END FunctionPrototypes */
  234. void HighestLEDTask(void *argument);
  235. void ReaddataTask(void *argument);
  236. void DealcallbackTask(void *argument);
  237. void CommonPrintTask(void *argument);
  238. void ReaddataTask02(void *argument);
  239. void FilterdataTask(void *argument);
  240. void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
  241. /**
  242. * @brief FreeRTOS initialization
  243. * @param None
  244. * @retval None
  245. */
  246. void MX_FREERTOS_Init(void) {
  247. /* USER CODE BEGIN Init */
  248. Systemmode = Debugmode; // Debugmode releasemode // 发布模式 IAPbootloader // 升级模式
  249. Set_485_Baudrate(JsRoot.baudrate);
  250. Restart_UART1_DMA();
  251. Restart_UART2_DMA();
  252. JsRoot.work = &JsWork;
  253. // JsRoot.addr = 0xFF;
  254. printf ("\r\n API_MUL app1 2025_08_20 \r\n");
  255. /* USER CODE END Init */
  256. /* USER CODE BEGIN RTOS_MUTEX */
  257. /* add mutexes, ... */
  258. /* USER CODE END RTOS_MUTEX */
  259. /* USER CODE BEGIN RTOS_SEMAPHORES */
  260. /* add semaphores, ... */
  261. /* USER CODE END RTOS_SEMAPHORES */
  262. /* USER CODE BEGIN RTOS_TIMERS */
  263. /* start timers, add new ones, ... */
  264. /* USER CODE END RTOS_TIMERS */
  265. /* Create the queue(s) */
  266. /* creation of uart485rxqueue */
  267. uart485rxqueueHandle = osMessageQueueNew (20, sizeof(Uart485Rx_msg), &uart485rxqueue_attributes);
  268. /* creation of printqueue */
  269. printqueueHandle = osMessageQueueNew (32, sizeof(Print_msg), &printqueue_attributes);
  270. /* creation of consolemsgqueue */
  271. consolemsgqueueHandle = osMessageQueueNew (32, sizeof(Console_msg), &consolemsgqueue_attributes);
  272. /* creation of filterqueue3 */
  273. filterqueue3Handle = osMessageQueueNew (30, sizeof(Filter_msg3), &filterqueue3_attributes);
  274. /* creation of filterqueue2 */
  275. filterqueue2Handle = osMessageQueueNew (30, sizeof(Filter_msg2), &filterqueue2_attributes);
  276. /* creation of filterqueue1 */
  277. filterqueue1Handle = osMessageQueueNew (30, sizeof(Filter_msg1), &filterqueue1_attributes);
  278. /* creation of filterqueue4 */
  279. filterqueue4Handle = osMessageQueueNew (30, sizeof(Filter_msg4), &filterqueue4_attributes);
  280. /* creation of filterqueue5 */
  281. filterqueue5Handle = osMessageQueueNew (30, sizeof(Filter_msg5), &filterqueue5_attributes);
  282. /* USER CODE BEGIN RTOS_QUEUES */
  283. /* add queues, ... */
  284. /* USER CODE END RTOS_QUEUES */
  285. /* Create the thread(s) */
  286. /* creation of HighestTask */
  287. HighestTaskHandle = osThreadNew(HighestLEDTask, NULL, &HighestTask_attributes);
  288. /* creation of ReadTask */
  289. ReadTaskHandle = osThreadNew(ReaddataTask, NULL, &ReadTask_attributes);
  290. /* creation of DealTask */
  291. DealTaskHandle = osThreadNew(DealcallbackTask, NULL, &DealTask_attributes);
  292. /* creation of CommonTask */
  293. CommonTaskHandle = osThreadNew(CommonPrintTask, NULL, &CommonTask_attributes);
  294. /* creation of ReadTask02 */
  295. ReadTask02Handle = osThreadNew(ReaddataTask02, NULL, &ReadTask02_attributes);
  296. /* creation of FilterTask */
  297. FilterTaskHandle = osThreadNew(FilterdataTask, NULL, &FilterTask_attributes);
  298. /* USER CODE BEGIN RTOS_THREADS */
  299. /* add threads, ... */
  300. /* USER CODE END RTOS_THREADS */
  301. /* USER CODE BEGIN RTOS_EVENTS */
  302. /* add events, ... */
  303. /* USER CODE END RTOS_EVENTS */
  304. }
  305. /* USER CODE BEGIN Header_HighestLEDTask */
  306. /**
  307. * @brief Function implementing the HighestTask thread.
  308. * @param argument: Not used
  309. * @retval None
  310. */
  311. /* USER CODE END Header_HighestLEDTask */
  312. void HighestLEDTask(void *argument)
  313. {
  314. /* USER CODE BEGIN HighestLEDTask */
  315. /* Infinite loop */
  316. LEDStatus_t current_status;
  317. uint8_t last_status = 0;
  318. uint32_t runtimecount = 0;
  319. for(;;)
  320. {
  321. HAL_IWDG_Refresh(&hiwdg);
  322. if(Systemmode == releasemode)
  323. current_status = LED_COMM;
  324. if(Systemmode == Debugmode) // Debugmode
  325. current_status = LED_WARNING_2;
  326. if(Systemmode == IAPbootloader)
  327. current_status = LED_IAP;
  328. // 只有当状态发生变化时才调用
  329. if (current_status != last_status)
  330. {
  331. last_status = current_status;
  332. UpdateLEDStatus(current_status);
  333. }
  334. LED_FlashHandler(&led_red, &led_green);
  335. LED_FlashHandler(&led_green, &led_red);
  336. if(runtimecount > 100)
  337. {
  338. runtimecount = 0;
  339. JsRoot.age ++ ;
  340. if(JsRoot.age > 65535)
  341. JsRoot.age = 0;
  342. }
  343. runtimecount++;
  344. osDelay(2);
  345. }
  346. /* USER CODE END HighestLEDTask */
  347. }
  348. /* USER CODE BEGIN Header_ReaddataTask */
  349. /**
  350. * @brief Function implementing the ReadTask thread.
  351. * @param argument: Not used
  352. * @retval None
  353. */
  354. /* USER CODE END Header_ReaddataTask */
  355. void ReaddataTask(void *argument)
  356. {
  357. /* USER CODE BEGIN ReaddataTask */
  358. /* Infinite loop */
  359. /*----------------ADS1256读取电压值----------------*/
  360. Filter_msg3 msg3;
  361. Filter_msg4 msg4;
  362. Filter_msg5 msg5;
  363. static int dropped_cnt1,dropped_cnt2,dropped_cnt3 = 0; // 监测未消费数据丢弃计数器
  364. ADS1256_Init(&hspi1);
  365. static uint8_t ads_channel_index = 0;
  366. for(;;)
  367. {
  368. if (HAL_GPIO_ReadPin(ADS_DRDY_GPIO_Port, ADS_DRDY_Pin) == GPIO_PIN_RESET)
  369. {
  370. int32_t adc_value = ADS1256_ReadChannel(ads_channel_index);
  371. // int32_t adc_value = ADS1256_Readdata();
  372. // Vin ---- R1 ----(Vout)---- R2 ---- GND R1 = 3.3kΩ R2 = 2.2kΩ
  373. // Vout = Vin × 2.2k / (3.3k + 2.2k) = Vin × 2.2 / 5.5 = Vin × 0.4
  374. float voltage = ADS1256_ConvertToVoltage(adc_value, 2.5f, 1); // VREF=2.5V,PGA=1
  375. switch (ads_channel_index)
  376. {
  377. case 0:
  378. /*----------通道0用于阀杆压力-------------*/
  379. voltage = voltage / 0.4f;
  380. ADS_v0 = voltage + ADS_v0_offset; // ADS_v0_offset = 0.008f;
  381. msg3.data = ADS_v0;
  382. ADS_PRINTF("ADS_v0 %.5f \r\n",ADS_v0);
  383. if (QueuePutOverwrite(filterqueue3Handle, &msg3, 0, 0) != osOK) { // 将数据放入队列
  384. dropped_cnt1++;
  385. ADS_PRINTF("\r\nQueue full, MPXV_P0=%.3f not sent. Dropped=%d", MPXV_P0, dropped_cnt1);
  386. }
  387. break;
  388. case 1:
  389. /*----------通道1用于余油压力-------------*/
  390. voltage = voltage / 0.4f;
  391. ADS_v1 = voltage - ADS_v1_offset; // ADS_v1_offset = 0.008f;
  392. msg4.data = ADS_v1;
  393. ADS_PRINTF("ADS_v1 %.5f \r\n",ADS_v1);
  394. if (QueuePutOverwrite(filterqueue4Handle, &msg4, 0, 0) != osOK) { // 将数据放入队列
  395. dropped_cnt2++;
  396. ADS_PRINTF("\r\nQueue full, MPXV_P1=%.3f not sent. Dropped=%d", MPXV_P1, dropped_cnt2);
  397. }
  398. break;
  399. case 2:
  400. /*----------通道2用于温度-------------*/
  401. ADS_v2 = voltage - ADS_v2_offset ; // ADS_v0_offset = 0.000f;
  402. msg5.data = ADS_v2;
  403. ADS_PRINTF("ADS_v2 %.5f \r\n",ADS_v2);
  404. if (QueuePutOverwrite(filterqueue5Handle, &msg5, 0, 0) != osOK) { // 将数据放入队列
  405. dropped_cnt3++;
  406. ADS_PRINTF("\r\nQueue full, ADS_v2=%.3f not sent. Dropped=%d", ADS_v2, dropped_cnt3);
  407. }
  408. break;
  409. }
  410. // 切换到下一个通道
  411. ads_channel_index++;
  412. if (ads_channel_index > 2)
  413. ads_channel_index = 0;
  414. }
  415. osDelay(10);
  416. }
  417. /* USER CODE END ReaddataTask */
  418. }
  419. /* USER CODE BEGIN Header_DealcallbackTask */
  420. /**
  421. * @brief Function implementing the DealTask thread.
  422. * @param argument: Not used
  423. * @retval None
  424. */
  425. /* USER CODE END Header_DealcallbackTask */
  426. void DealcallbackTask(void *argument)
  427. {
  428. /* USER CODE BEGIN DealcallbackTask */
  429. /* Infinite loop */
  430. for(;;)
  431. {
  432. Process_Consolecallback(); // 处理控制台命令
  433. Process_Uart485callback(); // 处理485指令应答
  434. osDelay(10);
  435. if(erase_APP2){
  436. Flash_ErasePages(APP2_ADDR, APP_SIZE / 4); // 擦除整个 APP2 区域(80KB)擦除 40 页
  437. erase_APP2 = false;
  438. }
  439. if(erase_APPdata_buffer){ //
  440. Flash_ErasePages(IAPDataBuffer_ADDR, APP_SIZE / 4); // 擦除整个 IAPDataBuffer 区域(80KB)擦除 40 页
  441. erase_APPdata_buffer = false;
  442. }
  443. if(save_JsRoot_0100_flag){
  444. JsRoot.subcode = upgrade_mode_subcode;
  445. DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_IAP_SUBCODE , JsRoot.subcode ); // 存入到SNAPSHOT数据库
  446. JsRoot.iapSize = expected_file_size; // 文件大小存到缓存区
  447. DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_IAP_SIZE , JsRoot.iapSize ); // 存入到SNAPSHOT数据库
  448. save_JsRoot_0100_flag = false;
  449. }
  450. if(JsRoot.iapLoadStatus == 300 && DB_init_flag == true) // 已完成APP数据缓存区的下载,接下来开始复制到APP2区
  451. {
  452. Flash_ErasePages(APP2_ADDR, APP_SIZE / 4); // 擦除整个 APP2 区域(80KB)擦除 40 页(2048字节/页)
  453. osDelay(100);
  454. Flash_Write64(APP2_ADDR, (uint64_t*)IAPDataBuffer_ADDR, APP_SIZE / 8); // 将APP缓存区的数据复制到APP2
  455. osDelay(100);
  456. printf("\r\n Copy IAPDataBuffer to APP2");
  457. uint8_t APP2_md5_bytes[4]; // 将结构体里 char 型的MD5码转成 uint8_t
  458. for (int i = 0; i < 4; i++) {
  459. sscanf(&JsRoot.iapMd5[i*2], "%2hhx", &APP2_md5_bytes[i]);
  460. }
  461. printf("\r\n Read FlashMd5 Complete");
  462. // 再验一遍MD5
  463. uint8_t cal_app2_md5[16];
  464. MD5_CTX context;
  465. MD5Init(&context);
  466. if( JsRoot.subcode == 0x0200 ){
  467. MD5Update(&context, (uint8_t*)APP2_ADDR, JsRoot.iapSize); // 0200 -0
  468. }else{
  469. MD5Update(&context, (uint8_t*)APP2_ADDR, JsRoot.iapSize - 16); // 0100 -16
  470. }
  471. MD5Final(cal_app2_md5, &context); // 计算APP2区的MD5码
  472. printf("\r\n Calculate Md5 Complete");
  473. printf("APP2_md5_bytes : ");
  474. for(int i = 0; i < 4; i++) {
  475. printf("%02X ", APP2_md5_bytes[i]);
  476. }
  477. printf("\n");
  478. printf("cal_app2_md5 : ");
  479. for(int i = 0; i < 4; i++) {
  480. printf("%02X ", cal_app2_md5[i]);
  481. }
  482. printf("\n");
  483. // 比较md5结果
  484. if (memcmp(cal_app2_md5, APP2_md5_bytes, 4) == 0) //验证复制后的APP2的MD5码和APP缓存区存入到数据库的MD5是否一致
  485. {
  486. printf("\r\n Copy IAPDataBuffer to APP2 success ");
  487. JsRoot.iapLoadStatus = 2; // 代表程序在APP2区运行
  488. JsRoot.ubootback = 0; // 跟随JsRoot.iapLoadStatus = 2 先置为0
  489. DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_UBOOTBACK , JsRoot.ubootback ); // bootloader 状态码存入到SNAPSHOT数据库
  490. DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_IAP_LOAD , JsRoot.iapLoadStatus ); // 装载状态存入到SNAPSHOT数据库
  491. osDelay(300);
  492. NVIC_SystemReset();
  493. }else{
  494. printf("\r\nCopy IAPDataBuffer to APP2 Failed!!! ");
  495. JsRoot.ubootback = 401; // 代表APP2区文件完整性校验错误
  496. JsRoot.iapLoadStatus = 0; // 代表程序在APP1区运行
  497. DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_UBOOTBACK , JsRoot.ubootback ); // bootloader 状态码存入到SNAPSHOT数据库
  498. DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_IAP_LOAD , JsRoot.iapLoadStatus ); // 装载状态存入到SNAPSHOT数据库
  499. send_upgrade_end_response(0x42, 0xAABB, 0x05, 0x0000); //MD5校验错误
  500. }
  501. }
  502. // 如果检测到APP2区文件完整性错误,再尝试3次将APP缓存区复制到APP2区
  503. // if(JsRoot.ubootback == 401)
  504. // {
  505. // // 复制flash
  506. // }
  507. check_upgrade_data4001_timeout();
  508. }
  509. /* USER CODE END DealcallbackTask */
  510. }
  511. /* USER CODE BEGIN Header_CommonPrintTask */
  512. /**
  513. * @brief Function implementing the CommonTask thread.
  514. * @param argument: Not used
  515. * @retval None
  516. */
  517. /* USER CODE END Header_CommonPrintTask */
  518. void CommonPrintTask(void *argument)
  519. {
  520. /* USER CODE BEGIN CommonPrintTask */
  521. /* Infinite loop */
  522. Print_msg Printmsg;
  523. for(;;)
  524. {
  525. if(printqueueHandle == NULL){
  526. printf("Failed to create print queue!\n");
  527. osDelay(1);
  528. continue;
  529. }
  530. osStatus_t status = osMessageQueueGet(printqueueHandle, &Printmsg, NULL, 0);
  531. if ( status== osOK)
  532. {
  533. printf("%s", Printmsg.msg);
  534. }
  535. else if (status == osErrorParameter) {
  536. printf("[CRITICAL] Queue corruption detected! Reinit...\n");
  537. osMessageQueueDelete(printqueueHandle);
  538. printqueueHandle = osMessageQueueNew(32, sizeof(Print_msg), NULL);
  539. }
  540. else{
  541. // printf("[ERROR] Failed to read from print queue: %d\n", (int)status);
  542. }
  543. if(DB_init_flag == false)
  544. {
  545. DB_InitAllConfigs(); // 数据库初始化
  546. DB_init_flag= true;
  547. }
  548. osDelay(15);
  549. }
  550. /* USER CODE END CommonPrintTask */
  551. }
  552. /* USER CODE BEGIN Header_ReaddataTask02 */
  553. /**
  554. * @brief Function implementing the ReadTask02 thread.
  555. * @param argument: Not used
  556. * @retval None
  557. */
  558. /* USER CODE END Header_ReaddataTask02 */
  559. void ReaddataTask02(void *argument)
  560. {
  561. /* USER CODE BEGIN ReaddataTask02 */
  562. /* Infinite loop */
  563. uint8_t fdc2214_initready1, fdc2214_initready2 = 0;
  564. uint8_t device1IDValid, device2IDValid = 0; // 设备ID是否有效的标志
  565. uint32_t lastCheck1Time, lastCheck2Time = 0; // 记录上次检查时间
  566. const uint32_t checkInterval = 5000; // 5秒检查间隔(毫秒)
  567. for(;;)
  568. {
  569. uint32_t now = HAL_GetTick();
  570. // 检查设备1
  571. if ((now - lastCheck1Time) >= checkInterval)
  572. {
  573. lastCheck1Time = now;
  574. CheckFDC2214_ID(1, &fdc2214_initready1,&device1IDValid);
  575. }
  576. if (device1IDValid)
  577. {
  578. /*--------------1号电容用于测量油水电容--------------*/
  579. ProcessFDC2214(&fdc2214_initready1, &device1IDValid, 0, oil_para_indu, oil_para_cap, oil_cap_offset, 1);
  580. }
  581. // 检查设备2
  582. if ((now - lastCheck2Time) >= checkInterval)
  583. {
  584. lastCheck2Time = now;
  585. TCheckFDC2214_ID(2, &fdc2214_initready2, &device2IDValid);
  586. }
  587. if (device2IDValid)
  588. {
  589. /*--------------2号电容用于测量余油电容--------------*/
  590. TProcessFDC2214(&fdc2214_initready2, &device2IDValid, 0, res_oil_para_indu, res_oil_para_cap, res_oil_cap_offset, 2);
  591. }
  592. osDelay(10);
  593. }
  594. /* USER CODE END ReaddataTask02 */
  595. }
  596. /* USER CODE BEGIN Header_FilterdataTask */
  597. /**
  598. * @brief Function implementing the FilterTask thread.
  599. * @param argument: Not used
  600. * @retval None
  601. */
  602. /* USER CODE END Header_FilterdataTask */
  603. void FilterdataTask(void *argument)
  604. {
  605. /* USER CODE BEGIN FilterdataTask */
  606. /* Infinite loop */
  607. SlidingWindowFilter filter1, filter2, filter3, filter4, filter5;
  608. SlidingFilter_Init(&filter1); // 初始化滑动窗口
  609. SlidingFilter_Init(&filter2);
  610. SlidingFilter_Init(&filter3);
  611. SlidingFilter_Init(&filter4);
  612. SlidingFilter_Init(&filter5);
  613. Filter_msg1 msg1;
  614. Filter_msg2 msg2;
  615. Filter_msg3 msg3;
  616. Filter_msg4 msg4;
  617. Filter_msg5 msg5;
  618. for(;;)
  619. {
  620. if (filterqueue1Handle != NULL) {
  621. /*---------油水电容值滤波----------*/
  622. osStatus_t status = osMessageQueueGet(filterqueue1Handle, &msg1, 0, 0);
  623. if (status == osOK) {
  624. filtered_oil_cap = SlidingFilter_Update(&filter1, msg1.data); // 滤波
  625. oil_percent = Estimate_Percentage_piecewise(filtered_oil_cap);
  626. // CommonPrintf("filtered_oil_cap=[%.5f], oil_percent=[%.1f%%]\r\n", filtered_oil_cap, oil_percent);
  627. }
  628. }
  629. if (filterqueue2Handle != NULL) {
  630. /*---------余油电容值滤波----------*/
  631. osStatus_t status = osMessageQueueGet(filterqueue2Handle, &msg2, 0, 0);
  632. if (status == osOK) {
  633. filtered_res_oil_cap = SlidingFilter_Update(&filter2, msg2.data);
  634. // CommonPrintf("filtered_res_oil_cap=[%.5f]\r\n", filtered_res_oil_cap);
  635. }
  636. }
  637. if (filterqueue3Handle != NULL) {
  638. /*---------阀杆压力值滤波----------*/
  639. osStatus_t status = osMessageQueueGet(filterqueue3Handle, &msg3, 0, 0);
  640. if (status == osOK) {
  641. filtered_ADS_v0 = SlidingFilter_Update(&filter3, msg3.data);
  642. MPXV_P0 = ((filtered_ADS_v0 - 2.5f) / 2.0f) * 7.0f; // kPa
  643. // CommonPrintf("P0 raw=%.3f, filtered=%.3f\r\n", msg3.data, filtered_MPXV_P0);
  644. }
  645. }
  646. if (filterqueue4Handle != NULL) {
  647. /*---------余油压力值滤波----------*/
  648. osStatus_t status = osMessageQueueGet(filterqueue4Handle, &msg4, 0, 0);
  649. if (status == osOK) {
  650. filtered_ADS_v1 = SlidingFilter_Update(&filter4, msg4.data);
  651. MPXV_P1 = ((filtered_ADS_v1 - 2.5f) / 2.0f) * 7.0f; // kPa
  652. // CommonPrintf("P1 raw=%.3f, filtered=%.3f\r\n", msg4.data, filtered_MPXV_P1);
  653. }
  654. }
  655. if (filterqueue5Handle != NULL) {
  656. /*---------温度值滤波----------*/
  657. osStatus_t status = osMessageQueueGet(filterqueue5Handle, &msg5, 0, 0);
  658. if (status == osOK) {
  659. filtered_ADS_v2 = SlidingFilter_Update(&filter5, msg5.data); // 滤波
  660. float r_ntc = NTC_CalculateResistance(filtered_ADS_v2, 3.3f, 49.9f); // 电压, ADC基准, 分压电阻
  661. NTC_temp = NTC_GetTemperature(r_ntc); // 查RT表得出温度值
  662. }
  663. }
  664. osDelay(5);
  665. }
  666. /* USER CODE END FilterdataTask */
  667. }
  668. /* Private application code --------------------------------------------------*/
  669. /* USER CODE BEGIN Application */
  670. void pack_filtered_cap(void) // float filtered_cap --> uint32_t uint_filtered_cap
  671. {
  672. // float filtered_value = filtered_cap1;
  673. // memcpy(&uint_filtered_cap, &filtered_value, sizeof(float)); // float --> uint32_t
  674. }
  675. // 队列安全写入(满时覆盖最旧数据)
  676. osStatus_t QueuePutOverwrite(osMessageQueueId_t queue_id, const void *msg_ptr, uint8_t priority, uint32_t timeout)
  677. {
  678. osStatus_t status;
  679. // 先尝试直接放入
  680. status = osMessageQueuePut(queue_id, msg_ptr, priority, timeout);
  681. if (status == osOK) {
  682. return osOK; // 成功
  683. }
  684. // 如果队列已满,先取出最旧数据(非阻塞方式)
  685. if (status == osErrorResource) {
  686. uint8_t temp_buffer[MAX_FRAME_SIZE]; // 临时存储被丢弃的数据
  687. osMessageQueueGet(queue_id, temp_buffer, NULL, 0); // 0 表示立即返回
  688. // 再尝试放入
  689. printf("[QueuePutOverwrite] full \r\n");
  690. return osMessageQueuePut(queue_id, msg_ptr, priority, timeout);
  691. }
  692. printf("[QueuePutOverwrite] error \r\n");
  693. // 其他错误直接返回
  694. return status;
  695. }
  696. void ProcessFDC2214( uint8_t* init_ready_flag, uint8_t* valid_flag, uint8_t channel, uint8_t inductor, uint8_t par_capacitor, float zeroValue, uint8_t device_index)
  697. {
  698. Filter_msg1 msg1;
  699. if (!(*init_ready_flag)) {
  700. *init_ready_flag = (FDC2214_Init() == 0) ? 1 : 0;
  701. if (!(*init_ready_flag)) {
  702. FDC_PRINTF("\r\nRetrying %d TFDC2214 init in 2s ...", device_index);
  703. msg1.data = 0;
  704. if (QueuePutOverwrite(filterqueue1Handle, &msg1, 0, 0) != osOK) {
  705. }
  706. osDelay(2000);
  707. return;
  708. } else {
  709. *valid_flag = 1;
  710. }
  711. }
  712. if (*valid_flag) {
  713. float cap = 0.0f ;
  714. cap = getcap(channel, inductor, par_capacitor) - zeroValue; // 采集数据 通道0,电感,电容 /* 并联 18uh - 13pf : 测量47pf , -30.6 , 并联 18uh - 33pf : 测量47pf , -43.1 */
  715. oil_cap = cap; // 油水检测原始电容值
  716. msg1.data = cap;
  717. FDC_PRINTF("msg1.data [%.5f] oil_cap [%.5f]\r\n",msg1.data, oil_cap);
  718. if (QueuePutOverwrite(filterqueue1Handle, &msg1, 0, 0) != osOK) {
  719. FDC_PRINTF("\r\nQueue full, cap=%.3f not sent", cap);
  720. }
  721. }
  722. }
  723. void CheckFDC2214_ID(uint8_t device_index, uint8_t* init_ready_flag, uint8_t* deviceValid)
  724. {
  725. Filter_msg1 msg1;
  726. uint16_t id = 0;
  727. id = FDC2214_Read16(TFDC2214_Addr, 0x7F);
  728. if (id == FDC2214_ID) {
  729. FDC_PRINTF("[TFDC2214-%d] ok: ID=0x%04X\r\n", device_index, id);
  730. *deviceValid = 1;
  731. } else {
  732. *deviceValid = 0;
  733. *init_ready_flag = 0;
  734. msg1.data = 0;
  735. res_oil_cap = 0;
  736. filtered_oil_cap = 0;
  737. oil_percent = 0;
  738. // 循环读取队列直到清空
  739. while (osMessageQueueGet(filterqueue1Handle, &msg1, NULL, 0) == osOK) {
  740. // 读取成功,继续循环直到队列为空
  741. }
  742. FDC_PRINTF("[TFDC2214-%d] error: ID=0x%04X\r\n", device_index, id);
  743. }
  744. }
  745. void TProcessFDC2214( uint8_t* init_ready_flag, uint8_t* valid_flag, uint8_t channel, uint8_t inductor, uint8_t par_capacitor, float zeroValue, uint8_t device_index)
  746. {
  747. Filter_msg2 msg2;
  748. if (!(*init_ready_flag)) {
  749. *init_ready_flag = (TFDC2214_Init() == 0) ? 1 : 0;
  750. if (!(*init_ready_flag)) {
  751. FDC_PRINTF("\r\nRetrying %d TFDC2214 init in 2s ...", device_index);
  752. msg2.data = 0;
  753. if (QueuePutOverwrite(filterqueue2Handle, &msg2, 0, 0) != osOK) {
  754. }
  755. osDelay(2000);
  756. return;
  757. } else {
  758. *valid_flag = 1;
  759. }
  760. }
  761. if (*valid_flag) {
  762. float cap = 0.0f ;
  763. cap = Tgetcap(channel, inductor, par_capacitor) - zeroValue; // 采集数据 通道0,电感,电容 /* 并联 18uh - 13pf : 测量47pf , -30.6 , 并联 18uh - 33pf : 测量47pf , -43.1 */
  764. res_oil_cap = cap; // 余油检测原始电容值
  765. msg2.data = cap;
  766. FDC_PRINTF("msg2.data [%.5f] res_oil_cap [%.5f]\r\n",msg2.data,res_oil_cap);
  767. if (QueuePutOverwrite(filterqueue2Handle, &msg2, 0, 0) != osOK) {
  768. FDC_PRINTF("\r\nQueue full, cap=%.3f not sent", cap);
  769. }
  770. }
  771. }
  772. void TCheckFDC2214_ID(uint8_t device_index, uint8_t* init_ready_flag, uint8_t* deviceValid)
  773. {
  774. Filter_msg2 msg2;
  775. uint16_t id = 0;
  776. id = TFDC2214_Read16(TFDC2214_Addr, 0x7F);
  777. if (id == TFDC2214_ID) {
  778. FDC_PRINTF("[TFDC2214-%d] ok: ID=0x%04X\r\n", device_index, id);
  779. *deviceValid = 1;
  780. } else {
  781. *deviceValid = 0;
  782. *init_ready_flag = 0;
  783. msg2.data = 0;
  784. if (QueuePutOverwrite(filterqueue2Handle, &msg2, 0, 0) != osOK) {
  785. }
  786. // 循环读取队列直到清空
  787. while (osMessageQueueGet(filterqueue2Handle, &msg2, NULL, 0) == osOK) {
  788. // 读取成功,继续循环直到队列为空
  789. }
  790. FDC_PRINTF("[TFDC2214-%d] error: ID=0x%04X\r\n", device_index, id);
  791. }
  792. }
  793. /* USER CODE END Application */