180 likes | 371 Views
Chapter 1 Sample Code. Terminology Single user system Multi user system Single programming Multi programming Single task Multi tasks Multi thread Generally, embedded system is a single programming system Sequential programming Multitask programming Hard/soft real-time system.
E N D
Chapter 1 Sample Code • Terminology • Single user system • Multi user system • Single programming • Multi programming • Single task • Multi tasks • Multi thread • Generally, embedded system is a single programming system • Sequential programming • Multitask programming • Hard/soft real-time system
Real-Time Programming Single Task: Main routine Subroutine 1 Subroutine n Multi Task: Task A Task B Task C Task D
Two Types of Real-time System • Must finish operations by deadlines. • Hard real time: missing deadline causes failure. • Tasks have to be performed not only correctly but on time • Soft real time: missing deadline results in degraded performance. • Tasks are performed by the system as fast as possible • Most real-time systems have a combination of SOFT and HARD requirements. • Most real-time systems are embedded
subroutine 3 finished calling subroutine 2 Subroutine No 1 2 3 time (a) Sequential subroutine calls (cyclic executive) task 1 suspended resume task 3 Task No 1 2 3 time (b) Multi-tasking Multi-task Programming
A typical real-time multi-tasking program main( ) { ... create( task1, 10, ... ); create( task2, 20, ... ); create( task3, -1, ... ); ... } .... task2() { .... if( ...) suspend( ); ... } main( ) { ... subroutine1( ... ); ... subroutine2( ... ); ... subroutine3( ... ); ... } execute every 10 ms execute whenever the CPU is available give up CPU time Cyclic Executive Multi-tasking
Task Scheduling (which one can be serviced by CPU) • Round-robin and time-slicing • What is the difference? Round-robin Task No 1 2 3 Time (a) Task No 1 Time-sliced (More fairness) 2 3 a quantum Time (b)
1.02 Compiler-Independent Data Types • Not use C’s short, int, and long data types because they are inherently nonportable Listing 1.1 Portable data types • For a 32-bit processor, the uC/OS-II will declare the unsigned int to unsigned short typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned int INT16U; typedef signed int INT16S; typedef unsigned long INT32U; typedef signed long INT32S; typedef float FP32; typedef double FP64; #define BYTE INT8S #define UBYTE INT8U #define WORD INT16S #define UWORD INT16U #define LONG INT32S #define ULONG INT32U
1.03 Global Variables • A global variable must be allocated storage space in RAM and must be referenced by other modules using the C keyword extern. • The following teaches how to use only signle declaration in the header file • In all .H files that define global variables as follows #ifdef xxx_GLOBALS#define xxx_EXT#else#define xxx_EXT extern#endif
EX: uCOS_II.H contains the following declaration #ifdef OS_GLOBALS#define OS_EXT#else#define OS_EXT extern#endif OS_EXT INT32U OSIdleCtr OS_EXT INT32U OSIdleCtrRun; OS_EXT INT32U OSIdleCtrMax; uCOS_II.C contains the following declarations : #define OS_GLOBALS#include “includes.h” INT32U OSIdleCtr INT32U OSIdleCtrRun; INT32U OSIdleCtrMax; After compiler: extern INT32U OSIdleCtr extern INT32U OSIdleCtrRun; extern INT32U OSIdleCtrMax; When compiler any other .C file:
1.04 OS_Enter_Critical() and OS_Exit_Critical() #define OS_CRITICAL_METHOD 2 #if OS_CRITICAL_METHOD == 1 #define OS_ENTER_CRITICAL() asm CLI #define OS_EXIT_CRITICAL() asm STI #endif #if OS_CRITICAL_METHOD == 2 #define OS_ENTER_CRITICAL() asm {PUSHF; CLI} #define OS_EXIT_CRITICAL() asm POPF #endif • Disabling interrupts affects interrupt latency, so be carefully
1.05 PC-Based Services • 1.05.01 Character-based Display • The display functions perform direct writes to video RAM for performance reasons • On a VGA monitor, video memory starts at absolute memory location 0xB8000 (B800:0000) • 25*80 = 2000 characters, each character requires two bytes. The first byte is displayed character, the second byte is display attribute 7 6 4 3 0 Foreground color Blinks bit Background color PC_DispClrScr() To clear the screen PC_DispClrLine() To clear a single row (or line) PC_DispChar() To display a single ASCII character anywhere on the screen PC_DispStr() To display an ASCII string anywhere on the screen
1.05.02 Elapsed Time Measurement • Time measurement is performed by using the PC’s 82C54 timer number 2 • PC_ElapsedStart(): begin to measure the function • PC_ElapsedStop(): return the measure result • PC_ElapsedInit(): comput the overhead of this two functions INT16U time; PC_ElapsedInit(); . . PC_ElapsedStart(); PC_DispChar(40, 24, ‘A’, DISP_FGND_WHITE); time = PC_ElapsedStop();
1.05.03 Miscellaneous • PC_DOSSaveReturn(): save the DOS environment • PC_DOSReturn(): return to the DOS • PC_GetDateTime: obtain the PC’s current date and time with the format MM-DD-YY HH:MM:SS • PC_SetTickRate(): use to change the tick rate • Under DOS, a tick occurs 18.20648 times per second (use the 8054 default value 65535) • If the 8254 value is set to 5965, the tick rate would have been a very nice 200 Hz. In the uCOS-II, it use this value to do the tick clock • The DOS tick handler requires to call in every 11 time out
1.07 Example 1 • Consist 13 tasks • Two internal tasks: the idle task and a task ther determines CPU usage • Create 11 tasks: the TaskStart() task is created by main() • Other 10 tasks is create by TaskStart() task. This 10 tasks are based on the same code • OSInit () creates two tasks : an idle task, which executes when no other task is ready to run and a statistic task, which computes CPU usage void main (void) { PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); (1) OSInit(); (2) PC_DOSSaveReturn(); (3) PC_VectSet(uCOS, OSCtxSw); // INT 80H 200HZ (4) RandomSem = OSSemCreate(1); (5) OSTaskCreate(TaskStart, (6) (void *)0, (void *)&TaskStartStk[TASK_STK_SIZE-1], 0); OSStart(); (7) }
void PC_DOSSaveReturn (void) { PC_ExitFlag = FALSE; (1) OSTickDOSCtr = 8; (2) PC_TickISR = PC_VectGet(VECT_TICK); (3) OS_ENTER_CRITICAL(); PC_VectSet(VECT_DOS_CHAIN, PC_TickISR); (4) OS_EXIT_CRITICAL(); setjmp(PC_JumpBuf); (5) if (PC_ExitFlag == TRUE) { OS_ENTER_CRITICAL(); PC_SetTickRate(18); (6) PC_VectSet(VECT_TICK, PC_TickISR); (7) OS_EXIT_CRITICAL(); PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); (8) exit(0); (9) } } Listing 1.6 Saving the DOS Environment Listing 1.7 Setting up to return to DOS void PC_DOSReturn (void) { PC_ExitFlag = TRUE; (1) longjmp(PC_JumpBuf, 1); //jump to the after of setjmp() location (2) }
void TaskStart (void *data) { Prevent compiler warning by assigning ‘data’ to itself; Display banner identifying this as EXAMPLE #1; (1) OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR); (2) PC_SetTickRate(200); (3) OS_EXIT_CRITICAL(); Initialize the statistic task by calling ‘OSStatInit()’; (4) Create 10 identical tasks; (5) for (;;) { Display the number of tasks created; Display the % of CPU used; Display the number of task switches in 1 second; Display uC/OS-II’s version number if (key was pressed) { if (key pressed was the ESCAPE key) { PC_DOSReturn(); } } Delay for 1 Second; } } Listing 1.8 Task that creates the other tasks If you run code in an embedded application, you should always enable the ticker within the first task
Listing 1.9 Determining the PC’s speed void OSStatInit (void) { OSTimeDly(2); (1) OS_ENTER_CRITICAL(); OSIdleCtr = 0L; (2) OS_EXIT_CRITICAL(); OSTimeDly(OS_TICKS_PER_SEC); (3) OS_ENTER_CRITICAL(); OSIdleCtrMax = OSIdleCtr; (4) OSStatRdy = TRUE; (5) OS_EXIT_CRITICAL(); } • OSIdleCtrMax contains the largest value of the OSIdleCtl • Use OSStatTask() to compute the CPU utilization, which executes every second
Listing 1.10 Task that displays a number at random locations on the screen void Task (void *data) { UBYTE x; UBYTE y; UBYTE err; for (;;) { OSSemPend(RandomSem, 0, &err); (1) x = random(80); (2) y = random(16); OSSemPost(RandomSem); (3) PC_DispChar(x, y + 5, *(char *)data, DISP_FGND_LIGHT_GRAY); (4) OSTimeDly(1); (5) } } • TaskStart () creates all the 10 identical tasks, and no context switch occurs because TaskStart() has a priority of 0 (the highest priority)