vTaskPrioritySet needs extra TaskHandle_t to function

Im using STM32F429I-DISC1 and Keil uVision v5

Ive written a simple example to demonstrate task priority setting using handles however the code only functions if I first delcare an unused TaskHandle_t (By functioning I mean the red LED blinks whilst the green LED stays static). When the unused TaskHandle_t is removed both LEDs blink (ie task priority is the same for both tasks)

/*

Simple blinky program converted to FreeRTOS
GnLed: PG13
RdLed: PG14

*/


#include "stm32f4xx_hal.h"              // Keil::Device:STM32Cube HAL:Common
#include "FreeRTOS.h"                   // ARM.FreeRTOS::RTOS:Core
#include "task.h"                       // ARM.FreeRTOS::RTOS:Core


#define gn_led GPIO_PIN_13
#define rd_led GPIO_PIN_14

void GPIO_Init(void);
void vGnLedControllerTask(void* pvParam);
void vRdLedControllerTask(void* pvParam);

TaskHandle_t test; //When this line is added code functions as expected
TaskHandle_t rd_Handle, gn_Handle;
	
int main()
{
	GPIO_Init(); 
	
	xTaskCreate(vGnLedControllerTask,
							"Green Led Controller",
							100,
							NULL,
							1,
							&gn_Handle
							);
							
	xTaskCreate(vRdLedControllerTask,
							"Red Led Controller",
							100,
							NULL,
							1,
							&rd_Handle
							);
							
	vTaskStartScheduler();
	while(1){};
}

void vGnLedControllerTask(void* pvParam)
{
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOG, gn_led);
		for(int i=0; i<1000000; i++){}
		vTaskPrioritySet(rd_Handle, 2);
	}
}

void vRdLedControllerTask(void* pvParam)
{
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOG, rd_led);
		for(int i=0; i<1000000; i++){}
	}
}


void GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	__HAL_RCC_GPIOG_CLK_ENABLE();
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_RESET);
	
	GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}

I’ve tried this here using your code, but with incrementing variables rather than toggling LEDs.
The code executes as expected.

The Red and Green tasks are started at the same priority so will time slice until the priority of the red task is raised, after which only the red task executes. The LEDs are only toggled once per loop, so when vTaskPrioritySet() is called each toggle (or variable increment in my case) has only happened once.

Also as expected, the behaviour is the same whether I have two or three task handles declared - and in most cases the compiler would remove references to the unused variable definition anyway so I’m not sure the compiled code would actually be any different with or without the third task handle declared.

If you find it makes a difference in your case then I would be suspicious of your project configuration. Adding the additional variable may change the alignment of the other variables, move them to a different memory location, etc. So options passed to the compiler or the linker scrip may be the cause.

My code:

//TaskHandle_t test; //When this line is added code functions as expected
TaskHandle_t rd_Handle, gn_Handle;
unsigned long green = 0, red = 0;

void vGnLedControllerTask(void* pvParam)
{
int i;
	while(1)
	{
		green++;
		for( i=0; i<1000000; i++){}
		vTaskPrioritySet(rd_Handle, 2);
	}
}

void vRdLedControllerTask(void* pvParam)
{
int i;
	
	while(1)
	{
		red++;
		for(i=0; i<1000000; i++){}
	}
}

int main()
{

	xTaskCreate(vGnLedControllerTask,
							"Green Led Controller",
							100,
							NULL,
							1,
							&gn_Handle
							);
							
	xTaskCreate(vRdLedControllerTask,
							"Red Led Controller",
							100,
							NULL,
							1,
							&rd_Handle
							);
							
	vTaskStartScheduler();
	while(1){};
}