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