Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

dsP30F4013 starving tasd problems

Posted by leviatan1 on June 23, 2014

Hello, i managed to compile my code for my dsp30f project as follows:

main.c

xQueueHandle Queue_I2C_DataHander=0x0000;
xQueueHandle Queue_I2C_ACK=0x0000;

/******************Semaphores and Task Handles****************/

xSemaphoreHandle Mutex_I2C_Rx =0;
xSemaphoreHandle Mutex_I2C_Tx=0;
xSemaphoreHandle Mutex_I2C_Ctrl=0;
xTaskHandle I2C_HANDLE;

int main( void )
{
/* Create the standar Queues*/

Queue_I2C_DataHander = xQueueCreate(3, sizeof(unsigned short));
Queue_I2C_ACK = xQueueCreate(3, sizeof(unsigned short));

/* Create standard Semaphores and Mutexes*/

Mutex_I2C_Rx = xSemaphoreCreateMutex();
Mutex_I2C_Tx = xSemaphoreCreateMutex();
Mutex_I2C_Ctrl= xSemaphoreCreateMutex();

/* Create the standard tasks. */

xTaskCreate(prep_HARD,"Config Hardware",100,NULL,6,NULL);
xTaskCreate(data_I2C_HANDLE,"Handle I2C",100,NULL,4,&I2C_HANDLE);
xTaskCreate(rx_I2C,"Recepcion SPI",128,NULL,4,NULL);
xTaskCreate(tx_I2C,"Transmision SPI",128,NULL,4,NULL);


/* Finally start the scheduler. */

vTaskStartScheduler();

/* Will only reach here if there is insufficient heap available to start
the scheduler. */
return 0;
}

now i have another filte to define the tasks:

subfunctions.h

/*********************DEFINICIONES DE TAREAS*********************/
void prep_HARD(void *pvParameters)//Task configs Hardware
    {
	//Variables que usa la Funcion
	unsigned short usI2CCONValue;
    unsigned short usI2CBRGValue;//ACA VA el valor del Baud gen para 100KHz
for(;;)
	{
	//Funciones que configuran el hardware
	//OSC: ((10MHz/2)*8)/4 = FCY = 10 Mhz
	TRISFbits.TRISF6 = 0;        //Output RF6/SCK1
	TRISFbits.TRISF2 = 1;        //Input  RF2/SDI1
	TRISFbits.TRISF3 = 0;        //Output RF3/SDO1
	ADPCFGbits.PCFG2 = 1;          //Pin RB2 analgoni
	TRISBbits.TRISB2 = 0;        //Output RB2 (SDC_CS RB2)
	LATBbits.LATB2 = 1;
	usI2CBRGValue = 0x05A; //100Khz para 10 MHZ de FCY
	usI2CCONValue = I2C_ON &
                    I2C_IDLE_CON &
                    I2C_CLK_REL &
                    I2C_IPMI_DIS &
                    I2C_7BIT_ADD &
                    I2C_SLW_DIS &
                    I2C_SM_DIS &
                    I2C_GCALL_DIS &
                    I2C_STR_DIS &
                    I2C_ACK &
                    I2C_ACK_DIS &
                    I2C_RCV_DIS &
                    I2C_STOP_DIS &
                    I2C_RESTART_DIS &
                    I2C_START_DIS;
   	OpenI2C(usI2CCONValue,usI2CBRGValue);
	vTaskDelete (NULL);//vTaskDelete se activa en FREERTOSconfig.h
	} 
    }


void data_I2C_HANDLE(void *pvParameters)//Task HANDLE I2C DATA I/O
{
	//Variables que usa la Funcion INTERNAMENTE
	usAnalisis_data=0x00;

for(;;)
	{
	//Funcion que maneja entrada y salida del I2C

	xQueueReceive(Queue_I2C_DataHander,&usHan_data,100);
	if(usHan_data==0x00)
		{
		//vTaskSuspend(NULL);
		}
	xQueuePeek(Queue_I2C_DataHander,&usHan_data,100);
	if(usHan_data==0xAA)
		{
		usTx_data==0x00;
		xQueueReceive(Queue_I2C_DataHander,&usAnalisis_data,100);
		//mover motores, podria hacer una rutina que mueva motores
		//y llamarla con un "for" para la cantidad de pasos
		//ahora enviar dato para jeringas ACK 0xFX
		usTx_add=(SLAVE_ADD1&W_I2C);
		usTx_data=0xFF;//para este caso el analisis es F entonces
						//ACK= 0xFX + F = 0xFF


		}
	usRx_data=0xBB;			
	}
//El codigo siguiente es en caso que la tarea salga del for
//si esto pasa la tarea se borra
vTaskDelete(NULL); 
}




void rx_I2C(void *pvParameters)//Task receiving I2C data
{
	//Variables que usa la Funcion INTERNAMENTE A LA TAREA


for(;;)
	{
	//Esta tarea espera el mutex para poder usar la queue
	//Funcion que lee el buffer I2C


	if(xSemaphoreTake(Mutex_I2C_Ctrl, 50))
		{
		usRx_data=0xAA;
		xQueueSend(Queue_I2C_DataHander, &usRx_data,100);//Pone el dato en la queue
		xSemaphoreGive(Mutex_I2C_Ctrl);
		}
	vTaskDelay(200);	

	//vTaskResume(I2C_HANDLE);

	}
//El codigo siguiente es en caso que la tarea salga del for
//si esto pasa la tarea se borra
vTaskDelete(NULL); 
} 

void tx_I2C(void *pvParameters)//Task sending I2C data
{
//Variables que usa la Funcion INTERNAMENTE

for(;;)
	{
	//Funcion que escribe el buffer I2C
	if(xSemaphoreTake(Mutex_I2C_Ctrl, 50))
		{
		usRx_data=0xBB;
		xQueueSend(Queue_I2C_DataHander, &usRx_data,100);//Pone el dato en la queue
		xSemaphoreGive(Mutex_I2C_Ctrl);
		}
	vTaskDelay(200);
	/*IdleI2C();
    StartI2C();
	while(I2CCONbits.SEN);//se pone low cuando la secuencia start termina
	MasterWriteI2C(usTx_add);//slave address entre parentesis mas bit R/W
	IdleI2C();
    MasterWriteI2C(usTx_data);
    StopI2C();*/


	}
//El codigo siguiente es en caso que la tarea salga del for
//si esto pasa la tarea se borra
vTaskDelete(NULL); 
}

The higher task runs once and deletes itself this is ok. Now the other 3 task have the same priority

1-the "dataI2CHANDLE" Task is blockes waiting the queue this is ok. 2-the "rxI2C" task takes the semaphore and goes one iteration then give the semaphore and blocks. 3-the "rxI2C" task takes the semaphore after the previous task exceutes and gives the semaphore but it takes the semaphore again and again starving the other two tasks.

after that i get a loop inside the task.c arround this code:

static portTASK_FUNCTION( prvIdleTask, pvParameters )
{
/* Stop warnings. */
( void ) pvParameters;

for( ;; )
{
	/* See if any tasks have been deleted. */
	prvCheckTasksWaitingTermination();

and i keep here forever.... could you help me? thanks.


dsP30F4013 starving tasd problems

Posted by edwards3 on June 23, 2014

Because the tasks all have the same priority how it runs will depend on which task is created first. One possible scenario would be

dataI2CHANDLE blocks to wait for data.

rx_I2C takes the mutex then posts to the queue, causing a task switch

txI2C runs but cant get the mutex as rxI2C still has it

dataI2CHANDLE runs and removes the data from the queue, then peeks on the queue. The queue must be empty so there is another task switch

rxI2C runs again and gives back the semaphore so txI2C starts to run

tx_I2C takes the semaphore and writes to the queue, another task switch

QueueI2CDataHander runs again and the peek completes. There is still data in the queue and QueueI2CDataHander reads the queue again removing the data before blocking on a peek again

tx_I2C runs again giving the semaphore back before blocking for 200 ticks

rx_I2C runs again and blocks for 200 ticks too

Now all the tasks are blocked. QueueI2CDataHander is blocked for 100 ticks and the other two tasks for 200 ticks so the idle task will run for 100 ticks, after which QueueI2CDataHander will unblock because it times out. Even though the queue must be empty QueueI2CDataHander tries to process the non existing peeked data because it does not test the QueuePeek return value to see if any data was actually received. That is presumably an an error.

I guess this is not how you want the code to run. The structure is very confused, for example, why create a task that does not do anything other than initialize the hardware before it deletes itself rather than initialize the hardware from a simple function call in main() or in another task?


dsP30F4013 starving tasd problems

Posted by leviatan1 on June 23, 2014

these task are "dummy" because i want to check that all task get CPU time when the others are in delay, after that i will add the true code, but i need that i2c hander task get blocked from queue, and i need that the other 2 task just wait there reading or writing acordingly i need it.

But for now im testing that rx and tx task switch between them but it wont happen tx task will give the semaphore and take it again before rx task so rx task remains blocked and tx keeps running forever, i dont know if i should use task yield or change the priority. the problem is that this shouldnt happen. For what i understand when a task enter delay the next task should star because it was more time in the blocked state.


dsP30F4013 starving tasd problems

Posted by leviatan1 on June 24, 2014

i MUST ADD, I CHANGED MY FOR(;;) INTO WHILE(1) AND IT STARTED TO WORK MORE CONSISTENT. I DONT KNOW IF IT HAS SOMETHING TO DO, BUT IT IS HAPPENNING ALSO I USED SOME PRIORITY CHANGE FOR THE TASK AND IT SEEMS TO BEAHAVE MORE ACCORDINGLY TO WHAT I NEED. im sorry my CAPS ill update later with the code.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner