/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c * Description : Code for freertos applications ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "FreeRTOS.h" #include "task.h" #include "main.h" #include "cmsis_os.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ extern UART_HandleTypeDef huart5; extern UART_HandleTypeDef huart7; extern UART_HandleTypeDef huart8; extern IWDG_HandleTypeDef hiwdg; /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ void uart_comm_state(void); void Modbus_comm_state(void); void modbus_reinit(); void uart_reinit(); extern uint8_t get_count(uint8_t,uint16_t); /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #include "typedef.h" #include "lwip/sockets.h" PC_req PC_rq_recv,PC_rq; extern PC_resp PC_resp_format; //PC_resp update_PC_cmd,RxCmd; uint8_t check_frame[250],rxFrame[250],Rx[250],_state,eth_thraed_cnt; extern uint32_t thread_cnt; /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ int sock = 1,check; uint8_t task3_flag,rev_ok,fail; uint32_t length ,socket_length,task1_cnt,prev_task2_cnt,task2_cnt,task3_cnt,PC_Req,connection_fail; struct sockaddr_in cilent_accept; uint32_t error_count_check,No_error_count_check,Timeout_count,connection_count; uint32_t task1,task2,task3; int sfd,cfd,addrlen,prev_sfd; struct sockaddr_in sLocalAddr,client_addr; int sock; uint32_t socket_length; extern uint32_t ETH_PLUG_IN,ETH_PLUG_OUT; extern uint8_t start_Eth_thread_cnt,flag,plug_in; extern uint16_t On_TIME,Off_TIME,Cycle_TIME; //extern uint32_t ETH_PLUG_IN; struct sockaddr_in cilent_accept; /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ /* Definitions for defaultTask */ osThreadId_t defaultTaskHandle; const osThreadAttr_t defaultTask_attributes = { .name = "defaultTask", .stack_size = 1024 * 4, .priority = (osPriority_t) osPriorityHigh, }; /* Definitions for myTask02 */ osThreadId_t myTask02Handle; const osThreadAttr_t myTask02_attributes = { .name = "myTask02", .stack_size = 2048 * 4, .priority = (osPriority_t) osPriorityNormal, }; /* Definitions for myTask03 */ osThreadId_t myTask03Handle; const osThreadAttr_t myTask03_attributes = { .name = "myTask03", .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityNormal, }; /* Definitions for myQueue01 */ osMessageQueueId_t myQueue01Handle; const osMessageQueueAttr_t myQueue01_attributes = { .name = "myQueue01" }; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /* USER CODE END FunctionPrototypes */ void ETH_comm_Task(void *argument); void Application_Task(void *argument); void uart_modbus_task(void *argument); extern void MX_LWIP_Init(void); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ /* Hook prototypes */ void vApplicationIdleHook(void); /* USER CODE BEGIN 2 */ void vApplicationIdleHook( void ) { /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle task. It is essential that code added to this hook function never attempts to block in any way (for example, call xQueueReceive() with a block time specified, or call vTaskDelay()). If the application makes use of the vTaskDelete() API function (as this demo application does) then it is also important that vApplicationIdleHook() is permitted to return to its calling function, because it is the responsibility of the idle task to clean up memory allocated by the kernel to any task that has since been deleted. */ } /* USER CODE END 2 */ /** * @brief FreeRTOS initialization * @param None * @retval None */ void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* USER CODE BEGIN RTOS_MUTEX */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */ /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_TIMERS */ /* start timers, add new ones, ... */ /* USER CODE END RTOS_TIMERS */ /* Create the queue(s) */ /* creation of myQueue01 */ myQueue01Handle = osMessageQueueNew (284, sizeof(uint8_t), &myQueue01_attributes); /* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ /* USER CODE END RTOS_QUEUES */ /* Create the thread(s) */ /* creation of defaultTask */ defaultTaskHandle = osThreadNew(ETH_comm_Task, NULL, &defaultTask_attributes); /* creation of myTask02 */ myTask02Handle = osThreadNew(Application_Task, NULL, &myTask02_attributes); /* creation of myTask03 */ myTask03Handle = osThreadNew(uart_modbus_task, NULL, &myTask03_attributes); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* USER CODE END RTOS_THREADS */ /* USER CODE BEGIN RTOS_EVENTS */ /* add events, ... */ /* USER CODE END RTOS_EVENTS */ } /* USER CODE BEGIN Header_ETH_comm_Task */ /** * @brief Function implementing the defaultTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_ETH_comm_Task */ void ETH_comm_Task(void *argument) { /* init code for LWIP */ MX_LWIP_Init(); /* USER CODE BEGIN ETH_comm_Task */ /* Infinite loop */ sfd = lwip_socket(AF_INET,SOCK_STREAM,0); if(sfd<0) { lwip_close(sfd); error_count_check = 1; } sLocalAddr.sin_family = AF_INET; sLocalAddr.sin_len = sizeof cilent_accept; sLocalAddr.sin_addr.s_addr = IPADDR_ANY; sLocalAddr.sin_port = htons(2000); if(lwip_bind(sfd, (const struct sockaddr *)&sLocalAddr,sizeof(sLocalAddr))<0) { lwip_close(sfd); No_error_count_check = 1; } if(lwip_listen(sfd,10)<0) { lwip_close(sfd); } for(;;) { task1_cnt++; if(plug_in) //link change happened { plug_in=0; task3_flag=1; } addrlen = sizeof(client_addr); cfd = lwip_accept(sfd,(struct sockaddr*)&client_addr,(socklen_t *)&addrlen); Timeout_count++; if(cfd>0) { if(prev_sfd>0) { lwip_close(prev_sfd); } prev_sfd = cfd; connection_count++; } else { connection_fail++; } osDelay(100); //osDelay(60); } /* USER CODE END ETH_comm_Task */ } /* USER CODE BEGIN Header_Application_Task */ /** * @brief Function implementing the myTask02 thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_Application_Task */ void Application_Task(void *argument) { /* USER CODE BEGIN Application_Task */ /* Infinite loop */ for(;;) { task2_cnt++; get_time(); //to update current time if(prev_sfd > 0) { check=lwip_recv(prev_sfd, &rxFrame, 250, MSG_DONTWAIT); if(rxFrame[0]=='*' && rxFrame[249]=='#') { start_Eth_thread_cnt=1; plug_in=0; PC_Req++; memcpy((uint8_t*)&PC_rq_recv,rxFrame,11); memcpy((uint8_t*)&check_frame,rxFrame,250); // osMessageQueuePut(myQueue01Handle,rxFrame, NULL, 0); // memset(rxFrame,'0',11); // } // if(PC_rq_recv.start =='*' && PC_rq_recv.stop =='#') // { PC_resp_format.start = '*'; PC_resp_format.stop = '#'; PC_resp_format.count = PC_rq_recv.count; PC_resp_format.version = VERSION1; if(PC_rq_recv.contol_word==1) { PC_resp_format.ON_Time = PC_rq_recv.ON_Time; PC_resp_format.OFF_Time = PC_rq_recv.OFF_Time; PC_resp_format.CYCLE_Time= PC_rq_recv.CYCLE_Time; } else { PC_resp_format.ON_Time = On_TIME; PC_resp_format.OFF_Time = Off_TIME; PC_resp_format.CYCLE_Time= Cycle_TIME; } osDelay(1); lwip_write(prev_sfd, (uint8_t*)&PC_resp_format,284); memcpy((uint8_t*)&PC_rq,(uint8_t*)&PC_rq_recv,11); memset(rxFrame,'0',250); } } osDelay(5); } /* USER CODE END Application_Task */ } /* USER CODE BEGIN Header_uart_modbus_task */ /** * @brief Function implementing the myTask03 thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_uart_modbus_task */ void uart_modbus_task(void *argument) { /* USER CODE BEGIN uart_modbus_task */ /* Infinite loop */ get_count(START,0); for(;;) { task3_cnt++; if(task3_flag) { HAL_IWDG_Refresh(&hiwdg); task3_flag=0; } else if(plug_in==0 && prev_task2_cnt< task2_cnt) //check conn established when link change happenned { HAL_IWDG_Refresh(&hiwdg); prev_task2_cnt=task2_cnt; } uart_comm_state(); Modbus_comm_state(); modbus_reinit(); uart_reinit(); osDelay(10); } /* USER CODE END uart_modbus_task */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ /* USER CODE END Application */