Skip to main content
DPatr.2
Associate III
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

Bob S
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.2
DPatr.2Author
Associate III
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 */
}

Piranha
Principal III
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.

Bob S
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.2
DPatr.2Author
Associate III
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 !