Http auto refresh page crashes RTOS when adding more tasks

Hello! I’m using FreeRTOS v. 10.2.1 with an unknown version of LWIP with the STM32F767 microcontroller. I’m actually running the LWIP Web server example that comes in the STM32Cube_FW_F7_V1.16.0 package with a lot of added features. When I have 10 threads the system runs fine.
But now I added an 11th thread and have increased the Heap space 4x. So heap space is not a problem. When I start the code, all the threads seem to be running fine. But when I load a webpage that does an auto-refresh, the whole microcontroller seems to hang. The page loads once only (no auto refresh) . I’m not sure if this is a freeRTOS problem or LWIP problem. I posted here since it happens when I load an 11th thread. With 10, it runs fine. For some reason the micro is stuck in the HTTP task on the netconn_accept line. The RTOS seems to never switch to another task. Any ideas? Thanks a lot.
Here is my FreeRTOSConfig.h file:

#define configUSE_PREEMPTION			1
#define configUSE_IDLE_HOOK			0
#define configUSE_TICK_HOOK			0
#define configCPU_CLOCK_HZ			( SystemCoreClock )
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES			(  7 )
#define configMINIMAL_STACK_SIZE		( ( uint16_t ) 128 )
#if defined(__GNUC__)
 #define configTOTAL_HEAP_SIZE			( ( size_t ) ( 100 * 1024 ) )
#else
 #define configTOTAL_HEAP_SIZE			( ( size_t ) ( 20 * 1024 ) )
#endif
#define configMAX_TASK_NAME_LEN			( 16 )
#define configUSE_TRACE_FACILITY		1
#define configUSE_16_BIT_TICKS			0
#define configIDLE_SHOULD_YIELD			1
#define configUSE_MUTEXES			1
#define configQUEUE_REGISTRY_SIZE		8
#define configCHECK_FOR_STACK_OVERFLOW	        0
#define configUSE_RECURSIVE_MUTEXES		1
#define configUSE_MALLOC_FAILED_HOOK	        0
#define configUSE_APPLICATION_TASK_TAG	        0
#define configUSE_COUNTING_SEMAPHORES	        1
#define configGENERATE_RUN_TIME_STATS	        0
#define configUSE_STATS_FORMATTING_FUNCTIONS    1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 		        0
#define configMAX_CO_ROUTINE_PRIORITIES        ( 2 )

/* Software timer definitions. */
#define configUSE_TIMERS			0
#define configTIMER_TASK_PRIORITY		( 2 )
#define configTIMER_QUEUE_LENGTH		15
#define configTIMER_TASK_STACK_DEPTH	        ( configMINIMAL_STACK_SIZE * 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet		1
#define INCLUDE_uxTaskPriorityGet		1
#define INCLUDE_vTaskDelete			1
#define INCLUDE_vTaskCleanUpResources	        0
#define INCLUDE_vTaskSuspend			0
#define INCLUDE_vTaskDelayUntil			1
#define INCLUDE_vTaskDelay			1
#define INCLUDE_xTaskGetSchedulerState          1

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
	/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
	#define configPRIO_BITS       		__NVIC_PRIO_BITS
#else
	#define configPRIO_BITS       		4        /* 15 priority levels */
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			0xf

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
	
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }	
	
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler

Have you read through the notes here https://www.freertos.org/FAQHelp.html regarding having stack overflow checking on, configASSERT() defined, setting interrupt priorities, etc?

Hello!
No I had not had checked the FAQ. I’ve now:

  • increased the stack space 2x of the Ethernet task
  • Fixed some priority assignments to be above the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY setting
  • Checked the configASSERT parameter. It was set already to call the taskDISABLE_INTERRUPTS. But I changed it to call the Error_Handle routine which just lights up a DEBUG led. It never gets called. BUT… I did notice an interesting behavior: If I set the line to just:
    #define configASSERT( x )
    then the autorefresh web page still only loads once, and the HTTP task still gets stuck BUT the other tasks seem to still run. I’m not sure why this works this way since when I had it go to Error_Handler, the LED never lit up.

So other than the quirky behavior I described above, I still have not been able to fix the problem. The system still habgs on the second reload of the the auto-refresh web page.

Thanks!

Ok. Somehow now the configASSERT is now failing.
it fails on this line in heap_4.c:
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
and indeed pxLink–>xBlockSize is 0, therefore it fails the assertion.
Basically it means that the memory that was being freed did not have a BlockLink_t structure immediately before it.
Any ideas on possible causes for this? Where was this BlockLink_t structure suuposed to be created?

Thanks

That means likely that the block of memory didn’t come from the same memory allocation system, or that you overran some buffer and clobbered the memory.