Skip to main content
Explorer
August 30, 2022
Question

ethernetif_set_link thread is not running. I would like to detect link up or down. I am using STM32F429ZIT6 - Nucleo, FreeRTOS CMSIS v1, LWIP v2.1.2 I am able to break in "tcpip_thread" so I assume it's not a scheduler issue. Anybody has an Idea?

  • August 30, 2022
  • 4 replies
  • 1243 views
int main(void)
{
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
 
 /* MCU Configuration--------------------------------------------------------*/
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 
 /* USER CODE BEGIN Init */
 
 /* USER CODE END Init */
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* USER CODE BEGIN SysInit */
 
 /* USER CODE END SysInit */
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_TIM1_Init();
 MX_TIM2_Init();
 MX_USART3_UART_Init();
 /* USER CODE BEGIN 2 */
 HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
 HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1);
 
 
 
 /* USER CODE END 2 */
 
 /* 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 */
 
 /* USER CODE BEGIN RTOS_QUEUES */
 /* add queues, ... */
 /* USER CODE END RTOS_QUEUES */
 
 /* Create the thread(s) */
 /* definition and creation of defaultTask */
 osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 2048); 
 defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
 
 /* USER CODE BEGIN RTOS_THREADS */
 /* add threads, ... */
 /* USER CODE END RTOS_THREADS */
 
 /* Start scheduler */
 osKernelStart();
 
 /* We should never get here as control is now taken by the scheduler */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}
 
 
 
void StartDefaultTask(void const * argument)
{
 /* init code for LWIP */
	MX_LWIP_Init();
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
}

 if I call MX_LWIP_Init(); before

osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 2048);

defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

then it runs just fine but my main app is not running anymore.

It looklike an issue with FreeRTOS but I am beginner with it so I can't tell for sure.

    This topic has been closed for replies.

    4 replies

    Super User
    August 30, 2022

    Is that REALLY your code? Your StartDefaultTask() will exit immediately after calling MX_LWIP_Init(). What happens to a task when it returns/hits the end of the function? Hint - normally tasks don't ever return. If all you want to do in StartDefaultTask() is start/init LWIP, then add an infinite loop after that calling osDelay() to allow other tasks to run.

    I don't see your "main app" in the code above. Could be a priority issue where a higher priority task never gives lower priority tasks (like ethernetif_set_link) a chance to run.

    DPatr.2Author
    Explorer
    August 30, 2022

    Its not all of my code. Here's the "main" loop of the application.

    I also handles TIM1 & TIM2 for "other stuff"

    void StartDefaultTask(void const * argument)
    {
     /* init code for LWIP */
    	MX_LWIP_Init();
     /* USER CODE BEGIN 5 */
     /* Infinite loop */
     
    	struct sockaddr_in address, client_addr;
    	socklen_t sin_size;
    	int s_create;
    	int addrlen = sizeof(address);
    	int opt = 1;
    	int socket_check;
     
    	/*Create a socket*/
    	s_create = lwip_socket(AF_INET, SOCK_STREAM, 0);
    	socket_check = lwip_setsockopt(s_create, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt));
     
    	memset(&address,0,sizeof(address));
    	address.sin_family = AF_INET;
    	address.sin_addr.s_addr = htonl(IPADDR_ANY);
    	address.sin_port = htons(HTTP_PORT); // C++ Client/Server might need to use 8080
     
    	socket_check = lwip_bind(s_create, (struct sockaddr*)&address, sizeof(address));
    	socket_check = lwip_listen(s_create, 1);	//returns 0 on succes, -1 on failure
     
     
    	char recvBuff[100];
     
    	acqBuff_0.size = 0;
    	acqBuff_0.startIndex = 0;
    	acqBuff_1.size = 0;
    	acqBuff_1.startIndex = 0;
     
    	manager.masterIndex = 0;
    	manager.ready = 0;
    	manager.selector = 0;
     
    	HAL_TIM_OC_Stop_IT(&htim1, TIM_CHANNEL_1);
    	HAL_GPIO_WritePin(TRIG_IN_LED_GPIO_Port, TRIG_IN_LED_Pin, 0);
    	HAL_GPIO_WritePin(TRIG_OUT_LED_GPIO_Port, TRIG_OUT_LED_Pin, 0);
     
     
     for(;;)
     {
     
     
    	 HAL_GPIO_WritePin(MCU_STATUS_LED_GPIO_Port, MCU_STATUS_LED_Pin, 1);
     
     
    	 sin_size = sizeof(struct sockaddr_in);
    	 new_socket = lwip_accept(s_create, (struct sockaddr *)&client_addr, &sin_size); 
    	 if (new_socket > 0){
     
    		 msgSize = sprintf(printMsg, "New client connected from IP: %s, Port: %d\r\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    		 HAL_UART_Transmit(&huart3, (uint8_t*)printMsg, msgSize, 10);
    		 ledTimer = HAL_GetTick();
    		 connectionClosed = 0;
     
    		
    		 while(!connectionClosed){
     
     
    			 memset(recvBuff, 0, sizeof(recvBuff));
    			 retVal = lwip_recv(new_socket, recvBuff, sizeof(recvBuff), MSG_DONTWAIT);
    			
    			 // Process buffer
    			 processMsg(recvBuff);
     
    			 //Toggle LED every second
    			 updateLED();
     
    			 // Send acquired Z-Encoder Data
    			 if(manager.ready){
    			 if(manager.selector){ //buffer_0 is full and ready to be sent.
     
    			 	 acqBuff_0.startIndex = manager.masterIndex; // insert current index into structure
    			 	 retVal = lwip_write(new_socket, &acqBuff_0, (4*(acqBuff_0.size) + 8));
     
     
    			 	 acqBuff_0.size = acqBuff_0.size - (retVal-8)/4;
    			 	 memset(acqBuff_0.data, -2, sizeof(acqBuff_0.data));
     
    			 	 manager.masterIndex += (retVal-8)/4;	// Increment Index according to size of buffer sent
    			 	 manager.ready = 0;
     
    			 	 if(retVal <0 ){
    			 		 // Client is disconnected
    			 		 goto socket_close;
    			 	 }
     
     
    			 }
    			 else if(!manager.selector){ //buffer_1 is full and ready to be sent.
     
    			 	 acqBuff_1.startIndex = manager.masterIndex;
    			 	 retVal = lwip_write(new_socket, &acqBuff_1, (4*(acqBuff_1.size) + 8));
     
    			 	 acqBuff_1.size = acqBuff_1.size - (retVal-8)/4;
    			 	 memset(acqBuff_1.data, -2, sizeof(acqBuff_1.data));
     
    			 	 manager.ready = 0;
    			 	 manager.masterIndex += (retVal-8)/4;
     
    			 	 if(retVal <0 ){
    			 		 // Client is disconnected
    			 		 goto socket_close;
    			 	 }
     
    			 }
    			 }
     
    			 osDelay(100);
    		 }// End of client connected loop
     
    		 socket_close:
    		 lwip_close(new_socket);
     
    	 }
     
     }
     
     /* USER CODE END 5 */
    }

    Graduate II
    September 4, 2022

    Socket API in lwIP is like the old BSD-style socket API. Netconn API provides similar functionality, but is simpler and more efficient.

    Super User
    August 30, 2022

    if your lwip_accept() call returns <= 0 (no connection) then your main loop here never yields to lower priority tasks (like ethernetif_set_link).

    DPatr.2Author
    Explorer
    August 30, 2022

    That is good point, I dont understand how lwip_accept() handles multiple thread in the background but it seems like it does.

    Anyway, I found the issue to be total heap size

    in FreeRTOSConfig.h

    I modify

    #define configTOTAL_HEAP_SIZE ((size_t)16360) 

    to

    #define configTOTAL_HEAP_SIZE ((size_t)30720) 

    and all threads are now running !