FreeRTOS porting on LPC2148

mohanraoksm wrote on Tuesday, December 02, 2014:

BaseType_t taskReturn;
QueueHandle_t xQueue;

void my_task(void *variable1)
{
long i;
while(1)
{
IOSET0 |= 0xC00000;
xQueueReceive(xQueue,&i,1000);
vTaskDelay(100); //keeps task in sleep mode for 100ms
}
}

void my_task1(void *variable1)
{
long j;
while(1)
{
IOCLR0 |= 0xC00000;
xQueueSend(xQueue,&j,1000);
vTaskDelay(100); //keeps task in sleep mode for 100ms
}
}

int main()
{

IODIR0 |= 0xC00000;
//number of items in the queue = 10
// each size is int
xQueue = xQueueCreate( 1024, sizeof( uint32_t ) );

if (xQueue != NULL)
{

	//Create Tasks here
	//Task name is my_task
	// const char * is used for task list creation
	//prority = 1
	//pointer passed, variable1 = NULL
	taskReturn = xTaskCreate(my_task, (const char *) "my_task", 1024, NULL, 1, NULL);
	taskReturn = xTaskCreate(my_task1, (const char *) "my_task1", 1024, NULL, 1, NULL);
}

//scheduler to be started once the queue and tasks are defined
vTaskStartScheduler();

return 0;

}

I have the above code written for LPC2148 microcontroller. When i try to compile and run the code, it doesn’t give any error. but the code goes to DATA ABORT condition. The Data abort occurs when it tries to execute vTaskStartScheduler() function.

When i see the port.c, i see the following code:

BaseType_t xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. */
prvSetupTimerInterrupt();

/* Start the first task.  This is done from portISR.c as ARM mode must be
used. */
vPortStartFirstTask();

/* Should not get here! */
return 0;

}

In the above code, we have vPortStartFirstTask(); which is not defined anywhere. also, i see the following declaration in port.c

extern __asm void vPortStartFirstTask( void );

The above declaration shows a warning “expected identifier or ‘(’” when i place the cursor.

I am unable to understand how asm file gets intergated to c code here and where from vPortStartFirstTask(); is coming. Please, guide me here.

This is my first project with FreeRTOS and i am trying to find a way out of here.

rtel wrote on Tuesday, December 02, 2014:

You don’t say which compiler you are using, but from the syntax I am guessing (I love guessing) it is Keil? In which case you would need to also include an assembly file in your project - which is called portASM.s. As your code is compiling and running, up to a point anyway, I presume you are already building the required asm file.

Are you sure it is crashing in the function you state, rather than completing that function, starting a task, then crashing in the task. You can step through the code to determine that, and if you step through the code you will also see the definition of vPortStartFirstTask().

If it is crashing in vPortStartFirstTask() then the most likely cause is the processor is in the wrong state when main() is called. It needs to be in Supervisor state. This used to be an FAQ when ARM7 was the most common architecture, but is rarely mentioned now.

Regards.

mohanraoksm wrote on Friday, December 05, 2014:

You guessed it right. I am using Keil compiler.

  1. portASM is already included.
  2. The ARM controller is in Supervisor mode.

It is definitely crashing in vPortStartFirstTask(). But the processor is in supervisor state at this time also. I have atatched snapshots when,

  1. Main execution started
  2. Before vPortStartFirstTask() function
  3. After vPortStartFirstTask() function

Please, let me know if want any other information regarding this. I am struck with this because vPortStartFirstTask() is akernel function and i dont have any control on this.

mohanraoksm wrote on Friday, December 05, 2014:

Query2

mohanraoksm wrote on Friday, December 05, 2014:

Query3

mohanraoksm wrote on Friday, December 05, 2014:

One more observation is that when i tried to step-in to that vPortStartFirstTask() function, it executed, and went to first task, but when run it directly, it goes to abort mode.

rtel wrote on Friday, December 05, 2014:

In the last screen shot the value in the program counter shows it is
about to call a __semihosting_library_function( 0x2444 ), but the C code
shows it is about to call vPortStartFirstTask().

Are you sure you are debugging the program you think you are?

Have you tried stepping through the assembly code for vPortStartFirstTask()?

Regards.

rtel wrote on Friday, December 05, 2014:

I would also recommend turning semi hosting off.

mohanraoksm wrote on Friday, December 05, 2014:

i am sure that i am debugging the desired program. I have included all the files and started compiling. Mostly, might not have missed it.

I stepped thorugh the assembly and when i step with debugger connected the execution goes to asm. attached snapshot

mohanraoksm wrote on Friday, December 05, 2014:

After, I step-in further, it goes to first task

mohanraoksm wrote on Friday, December 05, 2014:

But the only problem is if i run directly, the code goes to abort mode.

rtel wrote on Friday, December 05, 2014:

I have included
all the files and started compiling.

Sometimes people build the files but don’t actually download them to the
microcontroller.

In this case it looks like the first task is starting, so the crash is
happening after that, not in vPortStartFirstTask().

If you put a break point on the call to vTaskDelay(), so the program
stops before calling it, does it get to the break point?

mohanraoksm wrote on Friday, December 05, 2014:

Yes, you are right. Wow!!! my first FreeRTOS task execution happened without me noticing:)

Here now the problem is the execution goes to first task. But i debug further and execute the loop several times after 6-7 loops the data abort occurs.
Might be queue is overflown here? How to overcome this?

Also, my execution never goes to second queue. How to go to my second task from here?

rtel wrote on Friday, December 05, 2014:

I would recommend starting with a simpler system.

First have just one task that does this:

volatile uint32_t ulTask1 = 0, ulTask2 = 0;

void vTask1( void *pvParameters )
{
for( ;; )
{
ulTask1++;
taskYIELD();
}
}

to check a task can yield to itself, ulTask1 should increment very quickly.

then add a second task at the same priority:

void vTask2( void *pvParameters )
{
for( ;; )
{
ulTask2++;
taskYIELD();
}
}

to check both ulTask1 and ulTask2 increment.

Then you can add in blocking code, etc. to check that is working too.

Regards.

mohanraoksm wrote on Friday, December 05, 2014:

I did that… I added new code as mentioned by you…

BaseType_t taskReturn;
QueueHandle_t xQueue;
volatile uint32_t ulTask1 = 0, ulTask2 = 0;

void vTask1( void *pvParameters )
{
for( ;; )
{
ulTask1++;
taskYIELD();
}
}

void vTask2( void *pvParameters )
{
for( ;; )
{
ulTask2++;
taskYIELD();
}
}

void my_task(void *variable1)
{
long i;
while(1)
{
IOSET0 |= 0xC00000;
xQueueReceive(xQueue,&i,1000);
vTaskDelay(100); //keeps task in sleep mode for 100ms
}
}

void my_task1(void *variable1)
{
long j;
while(1)
{
IOCLR0 |= 0xC00000;
xQueueSend(xQueue,&j,1000);
vTaskDelay(100); //keeps task in sleep mode for 100ms
}
}

int main()
{

IODIR0 |= 0xC00000;
//number of items in the queue = 10
// each size is int
xQueue = xQueueCreate( 1024, sizeof( uint32_t ) );

if (xQueue != NULL)
{

	//Create Tasks here
	//Task name is my_task
	// const char * is used for task list creation
	//prority = 1
	//pointer passed, variable1 = NULL
	taskReturn = xTaskCreate(vTask1, (const char *) "my_task", 1024, NULL, 1, NULL);
	taskReturn = xTaskCreate(vTask2, (const char *) "my_task1", 1024, NULL, 1, NULL);
}

// vTaskResume(my_task);

//scheduler to be started once the queue and tasks are defined
vTaskStartScheduler();

return 0;

}

Now it goes to vTask2 directly and after few loops in the task it again goes to Data abort mode…

rtel wrote on Friday, December 05, 2014:

In which case perhaps it aborts when the tick interrupt fires for the
first time.

mohanraoksm wrote on Friday, December 05, 2014:

I have attached the snapshot of the program when it goes to abort mode