17.04.2014 Views

Chapter 1 Sample Code Real-Time Programming Two Types of ...

Chapter 1 Sample Code Real-Time Programming Two Types of ...

Chapter 1 Sample Code Real-Time Programming Two Types of ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Two</strong> <strong>Types</strong> <strong>of</strong> <strong>Real</strong>-time System<br />

<strong>Chapter</strong> 1 <strong>Sample</strong> <strong>Code</strong><br />

1<br />

• Must finish operations by deadlines.<br />

– Hard real time: missing deadline causes failure.<br />

• Tasks have to be performed not only correctly but<br />

on time<br />

– S<strong>of</strong>t real time: missing deadline results in degraded<br />

performance.<br />

• Tasks are performed by the system as fast as<br />

possible<br />

• Most real-time systems have a combination <strong>of</strong><br />

SOFT and HARD requirements.<br />

• Most real-time systems are embedded<br />

3<br />

<strong>Real</strong>-<strong>Time</strong> <strong>Programming</strong><br />

Multi-task <strong>Programming</strong><br />

Single Task:<br />

Multi Task:<br />

Subroutine 1<br />

Task A<br />

Task C<br />

Main routine<br />

•••<br />

Task B<br />

Task D<br />

Subroutine n<br />

Subroutine<br />

No<br />

1<br />

2<br />

3<br />

Task<br />

No<br />

1<br />

2<br />

3<br />

(a) Sequential subroutine calls (cyclic executive)<br />

(b) Multi-tasking<br />

subroutine 3 finished<br />

calling subroutine 2<br />

task 1 suspended<br />

resume task 3<br />

time<br />

time<br />

2<br />

4


• A typical real-time multi-tasking program<br />

main( )<br />

{<br />

...<br />

subroutine1( ... );<br />

...<br />

subroutine2( ... );<br />

...<br />

subroutine3( ... );<br />

...<br />

}<br />

Cyclic Executive<br />

execute<br />

every<br />

10 ms<br />

execute<br />

whenever<br />

the CPU<br />

is available<br />

give up<br />

CPU time<br />

main( )<br />

{<br />

...<br />

create( task1, 10, ... );<br />

create( task2, 20, ... );<br />

create( task3, -1, ... );<br />

...<br />

} ....<br />

task2()<br />

{ ....<br />

if( ...) suspend( );<br />

...<br />

}<br />

Multi-tasking<br />

1.04 OS_Enter_Critical() and<br />

OS_Exit_Critical()<br />

#define OS_CRITICAL_METHOD 2<br />

#if OS_CRITICAL_METHOD == 1<br />

#define OS_ENTER_CRITICAL() asm CLI<br />

#define OS_EXIT_CRITICAL() asm STI<br />

#endif<br />

#if OS_CRITICAL_METHOD == 2<br />

#define OS_ENTER_CRITICAL() asm {PUSHF; CLI}<br />

#define OS_EXIT_CRITICAL() asm POPF<br />

#endif<br />

• Disabling interrupts affects interrupt latency, so be<br />

carefully<br />

5<br />

7<br />

Task Scheduling (which one can be serviced<br />

by CPU)<br />

• Round-robin and time-slicing<br />

– What is the difference?<br />

Task No<br />

1<br />

2<br />

3<br />

Task No<br />

1<br />

2<br />

3<br />

(a)<br />

(b)<br />

<strong>Time</strong><br />

<strong>Time</strong><br />

Round-robin<br />

<strong>Time</strong>-sliced<br />

(More fairness)<br />

a quantum<br />

6<br />

1.07 Example 1<br />

• Consist 13 tasks<br />

– <strong>Two</strong> internal tasks: the idle task and a task that determines CPU<br />

usage<br />

– Create 11 tasks: the TaskStart() task is created by main()<br />

– Other 10 tasks is create by TaskStart() task. This 10 tasks are based<br />

on the same code<br />

void main (void)<br />

{<br />

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); (1)<br />

OSInit(); (2)<br />

PC_DOSSaveReturn(); (3)<br />

PC_VectSet(uCOS, OSCtxSw); // INT 80H 200HZ (4)<br />

RandomSem = OSSemCreate(1); (5)<br />

OSTaskCreate(TaskStart, (6)<br />

(void *)0,<br />

(void *)&TaskStartStk[TASK_STK_SIZE-1],<br />

0);<br />

OSStart(); (7)<br />

}<br />

– OSInit () creates two tasks : an idle task, which executes when no<br />

other task is ready to run and a statistic task, which computes CPU<br />

usage<br />

8


Listing 1.3 Example #1, TaskStart()<br />

void TaskStart (void *data)<br />

{<br />

#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */<br />

OS_CPU_SR cpu_sr;<br />

#endif<br />

char s[100];<br />

INT16S key;<br />

pdata = pdata; (1) /* Prevent compiler warning */<br />

TaskStartDispInit(); (2) /* Initialize the display */<br />

OS_ENTER_CRITICAL(); (3)<br />

PC_VectSet(0x08, OSTickISR); (4)<br />

PC_SetTickRate(200); (5)<br />

OS_EXIT_CRITICAL(); (6)<br />

OSStatInit(); (7)<br />

TaskStartCreateTasks()<br />

(8) Create 10 identical tasks;<br />

for (;;) {<br />

TaskStartDisp();<br />

// Display the number <strong>of</strong> tasks created;<br />

if (key was pressed) {<br />

if (key pressed was the ESCAPE key) {<br />

PC_DOSReturn();<br />

}<br />

}<br />

Delay for 1 Second;<br />

}<br />

}<br />

Listing 1.4 Example #1 TaskStartCreateTasks()<br />

static void TaskStartCreateTasks (void)<br />

{<br />

INT8U i;<br />

for (i = 0; i < N_TASKS; i++) { /* Create N_TASKS identical tasks */<br />

TaskData[i] = '0' + i; /* Each task will display its own letter */<br />

OSTaskCreate(Task,<br />

(void *)&TaskData[i],<br />

&TaskStk[i][TASK_STK_SIZE - 1],<br />

i + 1);<br />

}<br />

}<br />

If you run code in an embedded application, you should always enable the ticker within the first task<br />

9<br />

11<br />

Example #1 Determining the PC’s speed<br />

void OSStatInit (void)<br />

{<br />

OS<strong>Time</strong>Dly(2); (1)<br />

OS_ENTER_CRITICAL();<br />

OSIdleCtr = 0L; (2)<br />

OS_EXIT_CRITICAL();<br />

OS<strong>Time</strong>Dly(OS_TICKS_PER_SEC); (3)<br />

OS_ENTER_CRITICAL();<br />

OSIdleCtrMax = OSIdleCtr; (4)<br />

OSStatRdy = TRUE; (5)<br />

OS_EXIT_CRITICAL();<br />

}<br />

• OSIdleCtrMax contains the largest value <strong>of</strong> the OSIdleCtl<br />

• Use OSStatTask() to compute the CPU utilization, which<br />

executes every second<br />

Listing 1.5 Example #1 Task that displays a number<br />

at random locations on the screen<br />

void Task (void *data)<br />

{<br />

UBYTE x;<br />

UBYTE y;<br />

UBYTE err;<br />

for (;;) {<br />

OSSemPend(RandomSem, 0, &err); (1)<br />

x = random(80); (2)<br />

y = random(16);<br />

OSSemPost(RandomSem); (3)<br />

PC_DispChar(x, y + 5, *(char *)data, DISP_FGND_LIGHT_GRAY); (4)<br />

OS<strong>Time</strong>Dly(1); (5)<br />

}<br />

}<br />

• TaskStart () creates all the 10 identical tasks, and no<br />

context switch occurs because TaskStart() has a priority <strong>of</strong><br />

0 (the highest priority)<br />

10<br />

12

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!