# FreeRtos taskCRITICAL example not working as expected

**URL:** <https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377>\
**Category:** Kernel\
**Tags:** tutorial\
**Created:** [September 11, 2024, 6:37am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377 "2024-09-11T06:37:27Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ZoroIchimonji](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/zoroichimonji/32/4914_2.png) [@ZoroIchimonji](https://forums.freertos.org/u/ZoroIchimonji)\
**Post date:** [September 11, 2024, 6:37am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/1 "2024-09-11T06:37:27Z")

</div>

Hi everyone,

I am working with freertos10\_xilinx and trying to solve a challenge presented (Digikey freertos challenge, video 7 on youtube)

In short, I need to create N Producer tasks that store their task number 3 times, in common global buffer and M Consumer tasks that print whatever there is in the global buffer.

Following is the code I am using

```auto
//To implement problem from DigiKey Introduction to RTOS Part 7.
//https://www.youtube.com/watch?v=95yUbClyf3E&list=PLEBQazB0HUyQ4hAPU1cJED6t3DU0h34bz&index=7
/* Task 1,2,3,4:
 * Send task number to a queue
 * Task 5,6:
 * Receive data from the same queue and print it
 */

/ ******************************************Application specific includes****************************************** /
#include "RtosUtil.h"
#include "app.h"

/ ******************************************'Main' specific****************************************** /
//Task Related
#define TASK_STACK_SIZE	(1024)
#define BUFFER_SIZE (100)
#define NUM_OF_PROD_TASKS	(5)
#define NUM_OF_CONS_TASKS	(2)

//Semaphore Related
SemaphoreHandle_t SemCount;

//Queue Related
QueueHandle_t queue1;
QueueHandle_t queue2;

//Task Related
TaskHandle_t TaskProdHandle[NUM_OF_PROD_TASKS];
TaskHandle_t TaskConsHandle[NUM_OF_CONS_TASKS];

static void TaskProd(void *);
static void TaskCons();

//UART related
char* rcvstr=NULL;
char UartByte;
char dumbuf[BUFFER_SIZE];
uint32_t head=0,tail=0;

unsigned int i_ind;

/* Task 1,2,3,4:
 * Send task number to a queue
 */
static void TaskProd(void *pvParameters){

	//Use to load global buffer and control UART
	taskENTER_CRITICAL();
	for(int i=0;i<3;i++){
		dumbuf[head]=*(uint32_t *)pvParameters;
		head=(head+1) % BUFFER_SIZE;
	}
	xil_printf("Received in TaskProd :%d\r\n",*(uint8_t *)pvParameters);
	taskEXIT_CRITICAL();

	xSemaphoreGive(SemCount);
//	vTaskDelete(TaskProdHandle[*(uint32_t *)pvParameters]);

}

/* Task 5,6:
 * Receive data from the same queue and print it
 */
static void TaskCons(){

	while(1){
		xSemaphoreTake(SemCount,0);

		//Use to load global buffer and control UART
		taskENTER_CRITICAL();
		xil_printf("Task number %d\r\n",dumbuf[tail]);
		tail=(tail+1) % BUFFER_SIZE;
		taskEXIT_CRITICAL();

		//Add delay for the task
		vTaskDelay(1000/portTICK_RATE_MS);
	}
}

int main(){

	xil_printf("Application started\r\n");

	AllInit();

	//Create Semaphores
	SemCount=xSemaphoreCreateCounting(NUM_OF_PROD_TASKS,0);
	if(SemCount!=NULL){
		xil_printf("Counting Semaphore Created\r\n");
	}

	//Create Queues to send parameters among tasks
	queue1=xQueueCreate(MAX_QUEUE_LEN,
						sizeof(int));
	queue2=xQueueCreate(MAX_QUEUE_LEN,
						sizeof(int));

	if(queue1==NULL && queue2==NULL)
		xil_printf("Queues NOT created\r\n");

	//Create Producer tasks
	for(i_ind=0;i_ind<NUM_OF_PROD_TASKS;i_ind++){
		sprintf(dumbuf,"Producer Task %d\r\n",i_ind);
		//Create Task to send the task number.
		xTaskCreate(TaskProd,
					dumbuf,
					TASK_STACK_SIZE,
					(void *)&i_ind,
					1,
					&TaskProdHandle[i_ind]);

// xSemaphoreTake(SemCount, 0);

	}

	//Create Consumer tasks
	for(i_ind=0;i_ind<NUM_OF_CONS_TASKS;i_ind++){
		sprintf(dumbuf,"Consumer Task %d\r\n",i_ind);
		//Create task to send task number
		xTaskCreate(TaskCons,
					dumbuf,
					TASK_STACK_SIZE,
					NULL,
					1,
					&TaskConsHandle[i_ind]);
	}

	//Start scheduler
	vTaskStartScheduler();

	return 0;
}

```

This is the output I am getting.

```auto
Application started
XGpio_CfgInitialize successful
Counting Semaphore Created
Received in TaskProd :2
Received in TaskProd :2
Received in TaskProd :2
Received in TaskProd :2
Received in TaskProd :2
Task number 2
Task number 2

```

I don’t see what I am doing wrong. Can someone guide me here?

Thanks in advance,

-ZoroIchimonji

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [September 11, 2024, 6:59am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/2 "2024-09-11T06:59:09Z")

</div>

> [@ZoroIchimonji](#):
>
> ```auto
> static void TaskProd(void *pvParameters){
> 
> //Use to load global buffer and control UART
> taskENTER_CRITICAL();
> for(int i=0;i<3;i++){
> dumbuf[head]=*(uint32_t *)pvParameters;
> head=(head+1) % BUFFER_SIZE;
> }
> xil_printf("Received in TaskProd :%d\r\n",*(uint8_t *)pvParameters);
> taskEXIT_CRITICAL();
> 
> xSemaphoreGive(SemCount);
> //	vTaskDelete(TaskProdHandle[*(uint32_t *)pvParameters]);
> 
> }
> 
> ```

A task cannot exit - it must call `vTaskDelete( NULL );` to delete itself.

---

<div class="post-metadata">

**Author:** ![ZoroIchimonji](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/zoroichimonji/32/4914_2.png) [@ZoroIchimonji](https://forums.freertos.org/u/ZoroIchimonji)\
**Post date:** [September 13, 2024, 5:00am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/3 "2024-09-13T05:00:15Z")

</div>

Hi @aggarg ,

Yes just corrected that and also made some more changes.

```auto
//To implement problem from DigiKey Introduction to RTOS Part 7.
//https://www.youtube.com/watch?v=95yUbClyf3E&list=PLEBQazB0HUyQ4hAPU1cJED6t3DU0h34bz&index=7
/* Task 1,2,3,4:
 * Send task number to a queue
 * Task 5,6:
 * Receive data from the same queue and print it
 */

/ ******************************************Application specific includes****************************************** /
#include "RtosUtil.h"
#include "app.h"

/ ******************************************'Main' specific****************************************** /
//Task Related
#define TASK_STACK_SIZE	(1024)
#define BUFFER_SIZE (100)
#define NUM_OF_PROD_TASKS	(5)
#define NUM_OF_CONS_TASKS	(2)

//Semaphore Related
SemaphoreHandle_t SemCount;

//Queue Related
QueueHandle_t queue1;
QueueHandle_t queue2;

//Task Related
TaskHandle_t TaskProdHandle[NUM_OF_PROD_TASKS];
TaskHandle_t TaskConsHandle[NUM_OF_CONS_TASKS];

static void TaskProd(void *);
static void TaskCons();

//UART related
char* rcvstr=NULL;
char UartByte;
char dumbuf[BUFFER_SIZE];
char ProdTaskDat[BUFFER_SIZE];

uint32_t head=0,tail=0;

//unsigned int i_ind;

/* Task 1,2,3,4:
 * Send task number to a queue
 */
static void TaskProd(void *pvParameters){

	//Use to load global buffer and control UART
	taskENTER_CRITICAL();
	xil_printf("Received in TaskProd :%d\r\n",*(uint8_t *)pvParameters);
	taskEXIT_CRITICAL();

	for(int i=0;i<3;i++){
		xSemaphoreGive(SemCount);

		taskENTER_CRITICAL();
		dumbuf[head]=*(uint8_t *)pvParameters;
		head=(head+1) % BUFFER_SIZE;
		taskEXIT_CRITICAL();
	}

	vTaskDelete(TaskProdHandle[*(uint8_t *)pvParameters]);
	TaskProdHandle[*(uint8_t *)pvParameters]=NULL;

}

/* Task 5,6:
 * Receive data from the same queue and print it
 */
static void TaskCons(){

	while(1){
		xSemaphoreTake(SemCount,portMAX_DELAY);

		//Use to load global buffer and control UART
		taskENTER_CRITICAL();
		xil_printf("Task number %d\r\n",dumbuf[tail]);
		tail=(tail+1) % BUFFER_SIZE;
		taskEXIT_CRITICAL();

		//Add delay for the task
		vTaskDelay(100/portTICK_RATE_MS);
	}
}

int main(){

	xil_printf("Application started\r\n");

	AllInit();

	//Create Semaphores
	SemCount=xSemaphoreCreateCounting(NUM_OF_PROD_TASKS*3,0);
	if(SemCount!=NULL){
		xil_printf("Counting Semaphore Created\r\n");
	}

	//Create Queues to send parameters among tasks
	queue1=xQueueCreate(MAX_QUEUE_LEN,
						sizeof(int));
	queue2=xQueueCreate(MAX_QUEUE_LEN,
						sizeof(int));

	if(queue1==NULL && queue2==NULL)
		xil_printf("Queues NOT created\r\n");

	//Create Producer tasks
	for(int i_ind=0;i_ind<NUM_OF_PROD_TASKS;i_ind++){
		ProdTaskDat[i_ind]=i_ind;
		sprintf(dumbuf,"Producer Task %d\r\n",i_ind);
		//Create Task to send the task number.
		xTaskCreate(TaskProd,
					dumbuf,
					TASK_STACK_SIZE,
					(void *)&ProdTaskDat[i_ind],
					1,
					&TaskProdHandle[i_ind]);

// xSemaphoreTake(SemCount, 0);

	}

	//Create Consumer tasks
	for(int i_ind=0;i_ind<NUM_OF_CONS_TASKS;i_ind++){
		sprintf(dumbuf,"Consumer Task %d\r\n",i_ind);
		//Create task to send task number
		xTaskCreate(TaskCons,
					dumbuf,
					TASK_STACK_SIZE,
					NULL,
					1,
					&TaskConsHandle[i_ind]);
	}

	//Start scheduler
	vTaskStartScheduler();

	return 0;
}

```

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [September 13, 2024, 5:08am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/4 "2024-09-13T05:08:57Z")

</div>

Thank you for sharing changes. Does it solve your problem?

---

<div class="post-metadata">

**Author:** ![hs2](https://avatars.discourse-cdn.com/v4/letter/h/a4c791/32.png) [@hs2](https://forums.freertos.org/u/hs2)\
**Post date:** [September 13, 2024, 6:52am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/5 "2024-09-13T06:52:50Z")

</div>

Note that a task can delete itself by just using `vTaskDelete(NULL);` and I’d recommend that this should be the very last statement in the task code even though the effective deletion is deferred to the idle task.

---

<div class="post-metadata">

**Author:** ![RAc](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rac/32/1389_2.png) [@RAc](https://forums.freertos.org/u/RAc)\
**Post date:** [September 13, 2024, 3:33pm UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/6 "2024-09-13T15:33:07Z")

</div>

also make sure to check the return value of each FreeRTOS API call, in particular xTaskCreate().

---

<div class="post-metadata">

**Author:** ![ZoroIchimonji](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/zoroichimonji/32/4914_2.png) [@ZoroIchimonji](https://forums.freertos.org/u/ZoroIchimonji)\
**Post date:** [September 14, 2024, 4:27am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/7 "2024-09-14T04:27:38Z")

</div>

Yes

To be specific, the problem was I think that tasks were suspended. Because of two reasons.

1. I was **improperly type casting the Handle to _vTaskDelete()_ resulting in some error**. **Proper type casting and assigning the Handle value to NULL after, solved the problem.**
2. As per problem statement, I needed to hand different value in the **pvParameters** in the **xTaskCreate()**. Because I am sharing the address of a global variable/variable out of scope, and because all tasks start after a call to **vTaskStartScheduler()**, they were printing same number.

Hi @hs2  
Ok! I tried to search for if it does that. Probably got unlucky there.

Hi @RAc  
Yep! Will do that from next time.

Thank you everyone!

---

<div class="post-metadata">

**Author:** ![hs2](https://avatars.discourse-cdn.com/v4/letter/h/a4c791/32.png) [@hs2](https://forums.freertos.org/u/hs2)\
**Post date:** [September 14, 2024, 6:40am UTC](https://forums.freertos.org/t/freertos-taskcritical-example-not-working-as-expected/21377/9 "2024-09-14T06:40:51Z")

</div>

See the API doc here:

> **[vTaskDelete - FreeRTOS™](https://www.freertos.org/Documentation/02-Kernel/04-API-references/01-Task-creation/03-vTaskDelete)**
>
> TBD

Parameters:

- _xTask_ The handle of the task to be deleted. Passing NULL will cause the calling task to be deleted.
