Task format

I want to know whether the following task format is correct:

void FUN (void *param)
{
	// some operations here

	for(;;) // main loop
	{
		// some operations here

        vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10));

		if(condition_1)
		{
			// some operations here

			for(;;)  // subcycle
			{
				if(condition_2)
				{
					// some operations here

					vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10));
				}
				else
				{
					break;
				}
			}
			
			// some operations here
		}
	}
}

The problem I encountered is: if there is only one such task and no other tasks, the program can run normally. Once other tasks are added, the task will enter the vPortRaiseBASEPRI function at the first delay function and cannot be completed. After testing, I think it is a problem existing in this format. I hope someone can answer it

By the way, the chip is ATSAM4E16E

I think the problem is very likely somewhere else. The posted task code itself seems ok so far.
Do you check the return codes of xTaskCreate etc. and did you define configASSERT and also enable stack overflow checking for development/debugging to catch possible fatal errors or data corruption ?
Are there any interrupts / ISRs used where a wrong interrupt priority configuration can also cause nasty problems.

@hs2

There is a very strange phenomenon,I have set up three functions like this:

void Delay_test(void*p)
{
	for(;;)
	{
		vTaskDelay(10);
	}
}

void doble_loop_delay_test(void)
{
	int i = 1;
	for(;;)
	{
		can_send(CAN0, 0x0001, 7, 0x04030201, 0x08070605, 5);
		vTaskDelay(10);
		if(i <= 10)
		{
			for(;i <= 10;i++)
			{
				can_send(CAN0, 0x0001, 7, 0x04030201, 0x08070605, 8);
				vTaskDelay(10);
			}
		}
		i = 1;
	}
}

void t_speed_test(void* pm)
{
	t_param_t* param = pm;
	
	const TickType_t xDelayTime = pdMS_TO_TICKS(10);
	TickType_t xLastWakeTime = xTaskGetTickCount();
	
	Bool new_progress = true;
	
	int S/* = (*param).target_position - (*param).current_position*/;
	int Am/* = (*param).max_acc*/;
	int Vm/* = (*param).max_speed*/;
	
	if(param -> isNewPosition)
	{
		S = (param -> target_position) - (param -> current_position);
		Am = param -> max_acc;
		Vm = param -> max_speed;
		param -> isNewPosition = false;
		
		new_progress = true;
	}
	
	while(1)
	{
		if(new_progress)
		{
			float Smin = abs(Vm * Vm / Am);
			
		
			if (S < 0)
			{
				Am = -Am;
				Vm = -Vm;
				S = -S;
			}
			
			float t1, t2, t3;
			
			
			if (S > Smin)
			{
				t1 = (float)Vm / (float)Am;
				t3 = t1;
				t2 = (S - abs(Vm) * t1) / abs(Vm);
			}
			else
			{
				float Vm0 = sqrt(S) * sqrt(Am);
				t1 = Vm0 / abs(Am);
				t3 = t1;
				t2 = 0;
			}
			
			float x1 = 0.5 * Am * t1 * t1;
			float x2 = Am * t1 * t2;

			float s;
			
			
			for(int i = 10; i <= (int)((t1 + t2 + t3) * 1000); i += 10)
			{
				if (i / 1000.0 < t1)
				{
					s = 0.5 * Am * (i / 1000.0) * (i / 1000.0);
				}
				else if (i / 1000.0 >= t1 && i / 1000.0 < t1 + t2)
				{
					s = x1 + Am * t1 * (i / 1000.0 - t1);
				}
				else
				{
					s = x1 + x2 + Am * t1 * (i / 1000.0 - t1 - t2) - 0.5 * Am * (i / 1000.0 - t1 - t2) * (i / 1000.0 - t1 - t2);
				}
				
				can_send(CAN0, 0x0311, 6, (uint32_t)s, 0, 4);
				// Can_Send_IntData(CAN0 , 0x0311 ,(uint32_t)s , 0x00000000);
				 //vTaskDelay(10);
				vTaskDelayUntil(&xLastWakeTime, xDelayTime);
			}
			vTaskDelay(5);
 
		}
	}
}

And the parameters used are like this:

typedef struct
{
	int max_acc;
	int max_speed;
	
	Bool isNewPosition;
	
	uint32_t current_position;
	uint32_t target_position;
	uint32_t current_speed;
	uint32_t target_speed;
}t_param_t;

void can_send(Can *p_can, uint32_t ms_id, uint32_t mb_code, uint32_t datal, uint32_t datah, uint32_t digit)
{
	p_can -> CAN_MB[mb_code].CAN_MMR = CAN_MMR_PRIOR(0) | CAN_MMR_MOT_MB_TX;
	p_can -> CAN_MB[mb_code].CAN_MID = CAN_MID_MIDvA(ms_id);
	p_can -> CAN_MB[mb_code].CAN_MDL = datal;
	p_can -> CAN_MB[mb_code].CAN_MDH = datah;
	p_can -> CAN_MB[mb_code].CAN_MCR = CAN_MCR_MDLC(digit) | CAN_MCR_MTCR;
}

/************************************************************************/
//xSemaphoreHandle t_target_Mutex;
//xSemaphoreHandle t_current_Mutex;
//can_rxmb_data_t rx_data;
t_param_t t_param;

//S_Motion_Plane_In_t input_param;
/************************************************************************/

int main (void)
{
	WDT->WDT_MR = WDT_MR_WDDIS;
	/* Insert system clock initialization code here (sysclk_init()). */

	sysclk_init();
	board_init();
	ioport_init();
	delay_init(sysclk_get_cpu_hz());
	
	t_param.current_position = 0;
	t_param.target_position = 10000000;
	t_param.max_acc = 1000000;
	t_param.max_speed = 500000;
	t_param.isNewPosition = true;
	
	BaseType_t a = xTaskCreate((void*)Delay_test, "delay_test", 100, NULL, 3, NULL);
	
	//BaseType_t b = xTaskCreate((void*)doble_loop_delay_test,"dldt",100,NULL,5,NULL);
	BaseType_t b = xTaskCreate((void*)t_speed_test, "t_speed_test",500,&t_param,5,NULL);
	
	if(a && b)
	{
		vTaskStartScheduler();
	}
}

The specific situation is: when functions Delay_test and doble_loop_delay_test are executed simultaneously as tasks, the program runs normally , and if I only run the task of function t_speed_test, the program can also be used normally. When functions Delay_test and t_speed_test are executed simultaneously as tasks, the program is stuck in the function portFORCE_INLINE static void vPortRaiseBASEPRI( void ) when entering the delay function for the first time.I confirm that there are no other interrupts used during the execution of the function, and I will continue to try to trace the stack

Hmm … it still looks ok :thinking:
Just to be sure, t_param is a global variable, right ?
If you (hopefully) have a debugger attached and using the debug facilities like configASSERT mentioned before you should get an idea checking the backtrace / call stack from the point where (exactly) the app hangs.

Can you share the callstack when it is stuck?