cancel
Showing results for 
Search instead for 
Did you mean: 

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?

DPatr.2
Associate III
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.

5 REPLIES 5
Bob S
Principal

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.2
Associate III

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 */
}

Bob S
Principal

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.2
Associate III

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 !

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