Search This Blog

Nov 9, 2012

Porting FreeRTOS to SiM3U167 Cortex M3



Porting FreeRTOS to SiM3U167 Cortex M3
     RTOS is just an application which can execute difference function base on different trigger conditions, something like system ticket, interrupt, and message queue.etc. And also need protect some share resource would be accessed by difference function, or we call it task at one time.
      For Arm Cortex M3, there two popular RTOS, one it uC/OSII, the other one is FreeRtos. We pickup FreeRTOS as our target since it free and open source.  The poring procedure is pretty easy, let start it.

1.       Get Latest FreeRtos 7.3.0 source code.

Go to http://www.freertos.org/, and download it to your PC, extract it. We can see directory structure like below.
\FreeRTOS
\FreeRTOS-Plus
\readme.txt
Just go through the directory, there are a lot of difference platform support codes. We need Cortex M3 and GCC. So here are the resources we need.
\FreeRTOS\Source\*.*
\FreeRTOS\Source\include\*.*
\FreeRTOS\Source\portable\GCC\ARM\CM3\*.*
\FreeRTOS\Source\portable\MemMang\heap_4.c
And one head file needed, FreeRTOSConfig.h
I just choose \FreeRTOS\Demo\CORTEX_LM3S811_GCC\ FreeRTOSConfig.h, and copy it into \FreeRTOS\Source\include\

2.       Prepare our RTOS directory.

a)      Created a directory “FreeRTOSV7.3.0”.
b)      Copy a Blinky example code as code base and copy startup file in it.Exclude original startup file from project.
c)       Copy FreeRTOS directory into this directory.
d)      The directory structure now looks like this
\FreeRTOS\Source\*.*
\FreeRTOS\Source\include\*.*
\FreeRTOS\Source\portable\GCC\ARM\CM3\*.*
\FreeRTOS\Source\portable\MemMang\heap_4.c
\src\*.*
\src\generated\*.*

3.       Precistion32 environment setting and interrupt handler functions modification.

Include paths looks like this:
"${workspace_loc:/sim3u1xx_FreeRtos/src}"
"${workspace_loc:/sim3u1xx_FreeRtos/src/generated}"
"${workspace_loc:/sim3u1xx_FreeRtos/FreeRTOS/Source/include}"
"${workspace_loc:/sim3u1xx_FreeRtos/FreeRTOS/Source/portable/GCC/ARM_CM3}"
"${SI32_PATH}/si32Hal/sim3u1xx"
"${SI32_PATH}/si32Hal/SI32_Modules"
"${SI32_PATH}/si32Hal/CPU"
Open start up file src\startup_sim3u1xx_p32.c, changed three handler functions. In vector table “void (* const g_pfnVectors[])(void)”,
a)       Change SVCall handler to “vPortSVCHandler”
b)       Change PendSV handler to “xPortPendSVHandler”
c)        Change SysTick handler to “xPortSysTickHandler”

4.        Added task test code in main.c

void task1(void * parameters)
{
       uint32_t count = 0;
       const portCHAR *pcPassMessage = "PASS";
       while(1)
       {
              if(SI32_PBSTD_A_read_pin(SI32_PBSTD_2, 8)==0)
              {
                     printf("Task1 running %d\n",count++);
                     xQueueSend( xLEDQueue, &pcPassMessage, portMAX_DELAY );
              }
       }
}

void task2(void * parameters)
{
       uint32_t count = 0;
       while(1)
       {
              printf("Task2 running %d\n",count++);
              vTaskDelay( 1000 );
       }
}

void task3(void * parameters)
{
       uint32_t count = 0;
       portCHAR *pcMessage;
       while(1)
       {
              /* Wait for a message to arrive. */
              xQueueReceive( xLEDQueue, &pcMessage, portMAX_DELAY );
              SI32_PBSTD_A_toggle_pins(SI32_PBSTD_2,0xc00);
              printf("Task3 running %d  %s\n",count++,pcMessage);
       }
}

int main()
{

   while(SI32_PBSTD_A_read_pin(SI32_PBSTD_2, 8) == 0);
   // Enter the default operating mode for this application (gModes.c)
   gModes_enter_my_default_mode();

   // Print a starting message
   printf("hello world\n");
       /* Create the queue used to pass message to vPrintTask. */
   xLEDQueue = xQueueCreate( 3, sizeof( portCHAR * ) );

   xTaskCreate( task1, "task1", 200, NULL, 1, NULL );
   xTaskCreate( task2, "task2", 200, NULL, 2, NULL );
   xTaskCreate( task3, "task3", 200, NULL, 2, NULL );

       /* Start the scheduler running the tasks and co-routines just created. */
   vTaskStartScheduler();

   while(1);
   // Loop forever...
}

5.       Run the code,

We can task output from serial view window.
hello world
Task2 running 0
Task2 running 1
If we press SW2(PB2.8), we can see task1 and task3 active and output message
Task1 running 0
Task3 running 0  PASS
Task1 running 1
Task3 running 1  PASS

6.       Source code

We can get source code from https://github.com/MarkDing/sim3u1xx_FreeRtos