...
PC.C
provides services to display ASCII (and special) characters on a PC’s VGA display. In normal mode (i.e., character mode), a PC’s display can hold up to 2000 characters organized as 25 rows (i.e., Y) by 80 columns (i.e., X) as shown in figure 20-1. Please disregard the aspect ratio of the figure. The actual aspect ratio of a monitor is generally 4 x 3. Video memory on a PC is memory mapped and, on a VGA monitor, video memory starts at absolute memory location 0x000B8000
(or using a segment:offset notation, B800:0000
).
Anchor | ||||
---|---|---|---|---|
|
Panel | ||||
---|---|---|---|---|
| ||||
Each displayable character requires two bytes to display. The first byte (lowest memory location) is the character that you want to display while the second byte (next memory location) is an attribute that determines the foreground/background color combination of the character. The foreground color is specified in the lower 4 bits of the attribute while the background color appears in bits 4 to 6. Finally, the most-significant bit determines whether the character will blink (when 1) or not (when 0). The character and attribute bytes are shown in figure 20-2.
The tables below show the possible colors that can be obtained from the PC’s VGA character mode.
...
Anchor | ||||
---|---|---|---|---|
|
Panel | ||||
---|---|---|---|---|
| ||||
The tables below show the possible colors that can be obtained from the PC’s VGA character mode.
Blink (B7)
Blink? | #define | Hex |
---|---|---|
No | 0x00 | |
Yes | DISP_BLINK | 0xB0 |
Background Color (B6 BS B4)
...
A lot happens in PC_DOSSaveReturn()
so you may need to look at the code in listing 18.1 to follow along.
Elapsed Time Measurement
The elapsed time measurement functions are used to determine how much time a function takes to execute. Time measurement is performed by using the PC’s 82C54 timer #2. You make time measurement by wrapping the code to measure by the two functions PC_ElapsedStart
and PC_ElapsedStop
. However, before you can use these two functions, you need to call the function PC_ElapsedInit
. PC_ElapsedInit
basically computes the overhead associated with the other two functions. This way, the execution time (in microseconds) returned by PC_ElapsedStop
consist exclusively of the code you are measuring. Note that none of these functions are reentrant and thus, you must be careful that you do not invoke them from multiple tasks at the same time. .
Miscellaneous
PC_GetDateTime
is a function that obtains the PC’s current date and time, and formats this information into an ASCII string. The format is:
"YYYY-MM-DD HH:MM:SS"
and you will need at least 21 characters (including the NUL character) to hold this string. You should note that there are 2 spaces between the date and the time which explains why you need 21 characters instead of 20. PC_GetDateTime
uses the Borland C/C++ library functions gettime
and getdate
which should have their equivalent on other DOS compilers.
PC_GetKey
is a function that checks to see if a key was pressed and if so, obtains that key, and returns it to the caller. PC_GetKey
uses the Borland C/C++ library functions kbhit
and getch
which again, have their equivalent on other DOS compilers.
PC_SetTickRate
allows you to change the tick rate for µC/OS-II by specifying the desired frequency. Under DOS, a tick occurs 18.20648 times per second or, every 54.925 mS. This is because the 82C54 chip used didn’t get its counter initialized and the default value of 65535 takes effect. Had the chip been initialized with a divide by 59659, the tick rate would have been a very nice 20.000 Hz! I decided to change the tick rate to something more ‘exciting’ and thus, decided to use about 200 Hz (actually 199.9966). The code found in OS_CPU_A.O
calls the DOS tick handler one time out of 11. This is done to ensure that some of the housekeeping needed in DOS is maintained. You would not need to do this if you were to set the tick rate to 20 Hz. Before returning to DOS, PC_SetTickRate
is called by specifying 18 as the desired frequency. PC_SetTickRate
will know that you actually mean 18.2 Hz and will correctly set the 82C54.
The last two functions in PC.C
are used to get and set an interrupt vector. PC_VectGet
and PC_VectSet
should be compiler independent as long as the compiler support the macros MK_FP
(make far pointer), FP_OFF
(get the offset portion of a far pointer) and, FP_SEG
(get the segment of a far pointer).
Interface Functions
This section provides a reference section for the PC services.
PC_DispChar()
PC_DispChar
allows you to display a single ASCII (or special) character anywhere on the display.
Arguments
x
and y
specifies the coordinates (col, row) where the character will appear. rows (i.e., lines) are numbered from 0
to DISP_MAX_Y –
1, and columns are numbered from 0
to DISP_MAX_X –
1 (see PC.C
).
c
is the character to display. You can specify any ASCII characters and special characters if c
has a value higher than 128. You can see what characters (i.e., symbols) will be displayed based on the value of c
by running the test code provided in this book as follows:
C:\SOFTWARE\BLOCKS\SAMPLE\TEST > TEST display
color
specifies the contents of the attribute byte and thus the color combination of the character to be displayed. You can add one DISP_FGND_???
(see PC.H
) and one DISP_BGND_???
(see PC.H
) to obtain the desired color combination.
Returned Value
NONE
Notes/Warnings
NONE
Example
PC_DispClrCol()
PC_DispClrCol
allows you to clear the contents of a column (all 25 characters).
Arguments
x
specifies which column will be cleared. Columns are numbered from 0
to DISP_MAX_X –
1 (see PC.C
).
color
specifies the contents of the attribute byte. Because the character used to clear a column is the space character (i.e., ‘ ‘), only the background color will appear. You can thus specify any of the DISP_BGND_???
colors.
Returned Value
NONE
Notes/Warnings
NONE
Example
PC_DispClrRow()
PC_DispClrRow
allows you to clear the contents of a row (all 80 characters).
Arguments
y
specifies which row (i.e., line) will be cleared. Rows are numbered from 0
to DISP_MAX_Y –
1 (see PC.C
).
color
specifies the contents of the attribute byte. Because the character used to clear a row is the space character (i.e., ‘ ‘), only the background color will appear. You can thus specify any of the DISP_BGND_???
colors.
Returned Value
NONE
Notes/Warnings
NONE
Example
PC_DispClrScr()
PC_DispClrScr
allows you to clear the entire display.
Arguments
color
specifies the contents of the attribute byte. Because the character used to clear the screen is the space character (i.e., ‘ ‘), only the background color will appear. You can thus specify any of the DISP_BGND_???
colors.
Returned Value
NONE
Notes/Warnings
You should use DISP_FGND_WHITE
instead of DISP_BGND_BLACK
because you don’t want to leave the attribute field with black on black.
Example
PC_DispStr()
PC_DispStr
allows you to display an ASCII string. In fact, you could display an array containing any of 255 characters as long as the array itself is NUL terminated.
Arguments
x
and y
specifies the coordinates (col, row) where the first character will appear. rows (i.e., lines) are numbered from 0
to DISP_MAX_Y –
1, and columns are numbered from 0
to DISP_MAX_X –
1 (see PC.C
).
s
is a pointer to the array of characters to display. The array MUST be NUL terminated. Note that you can display any characters from 0x01 to 0xFF.
color
specifies the contents of the attribute byte and thus the color combination of the characters to be displayed. You can add one DISP_FGND_???
(see PC.H
) and one DISP_BGND_???
(see PC.H
) to obtain the desired color combination.
Returned Value
NONE
Notes/Warnings
All the characters of the string or array will be displayed with the same color attributes.
Example #1
The code below displays the current value of a global variable called Temperature. The color used depends on whether the temperature is below 100 (white), below 200 (yellow) or if it exceeds 200 (blinking white on a red background).
Example #2
The code below displays a square b0x 10 characters wide by 7 characters high in the center of the screen.
PC_DOSReturn()
PC_DOSReturn
allows your application to return back to DOS. It is assumed that you have previously called PC_DOSSaveReturn
in order to save the processor’s important registers in order to properly return to DOS. See section 18.02 for a description on how to use this function.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST have called PC_DOSSaveReturn
prior to calling PC_DOSReturn
.
Example
PC_DOSSaveReturn()
PC_DOSSaveReturn
allows your application to save the processor’s important registers in order to properly return to DOS before you actually start multitasking with µC/OS-II. You would normally call this function from main
as shown in the example code provided below.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST call this function prior to setting µC/OS-II’s context switch vector (as shown below).
Example
PC_ElapsedInit()
PC_ElapsedInit
is invoked to compute the overhead associated with the PC_ElapsedStart
and PC_ElapsedStop
calls. This allows PC_ElapsedStop
to return return the execution time (in microseconds) of the code you are trying to measure.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST call this function prior to calling either PC_ElapsedStart()
and PC_ElapsedStop()
.
Example
PC_ElapsedStart()
PC_ElapsedStart
is used in conjunction with PC_ElapsedStop
to measure the execution time of some of your application code.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST call PC_ElapsedInit
before you use either PC_ElapsedStart()
and PC_ElapsedStop()
.
This function is non-reentrant and cannot be called by multiple tasks without proper protection mechanisms (i.e., semaphores, locking the scheduler, etc.).
The execution time of your code must be less than 54.93 milliseconds in order for the elapsed time measurement functions to work properly.
Example
PC_ElapsedStop()
PC_ElapsedStop
is used in conjunction with PC_ElapsedStart
to measure the execution time of some of your application code.
Arguments
NONE
Returned Value
The execution time of your code that was wrapped between PC_ElapsedStart()
and PC_ElapsedStop()
. The execution time is returned in microseconds.
Notes/Warnings
You MUST call PC_ElapsedInit()
before you use either PC_ElapsedStart()
and PC_ElapsedStop()
.
This function is non-reentrant and cannot be called by multiple tasks without proper protection mechanisms (i.e., semaphores, locking the scheduler, etc.).
The execution time of your code must be less than 54.93 milliseconds in order for the elapsed time measurement functions to work properly.
Example
See PC_ElapsedStart()
.
PC_GetDateTime()
void PC_GetDateTime(char *s)
PC_GetDateTime
is used to obtain the current date and time from the PC’s real-time clock chip and return this information in an ASCII string that can hold at least 21 characters.
Arguments
s
is a pointer to the storage area where the ASCII string will be deposited. The format of the ASCII string is:
"YYYY-MM-DD HH:MM:SS"
and requires 21 bytes of storage (note that there is 2 spaces between the date and the time.
Returned Value
NONE
Notes/Warnings
NONE
Example
PC_GetKey()
PC_GetKey
is used to see if a key was pressed at the PC’s keyboard and if so, obtain the value of the key pressed. You would normally invoke this function every so often (i.e., poll the keyboard) to see if a key was pressed. Note that the PC actually obtains key presses through an ISR and buffers key presses. Up to 10 keys are buffered by the PC.
Arguments
key
is a pointer to where the key value will be stored. If no key has been pressed, the value will contain 0x00.
Returned Value
TRUE is a key was pressed and FALSE otherwise.
Notes/Warnings
NONE
Example
PC_SetTickRate()
PC_SetTickRate
is used to change the PC’s tick rate from the standard 18.20648 Hz to something faster. A tick rate of 200 Hz is a multiple of 18.20648 Hz (the multiple is 11).
Arguments
freq
is the desired frequency of the ticker.
Returned Value
NONE
Notes/Warnings
You can only make the ticker faster than 18.20648 Hz.
The higher the frequency, the more overhead you will impose on the CPU.
Example
PC_VectGet()
PC_VectGet
is used to obtain the address of the interrupt handler specified by the interrupt vector number
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
void PC_DOSSaveReturn (void)
{
PC_ExitFlag = FALSE; (1)
OSTickDOSCtr = 1; (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)
}
} |
Panel | ||
---|---|---|
| ||
(1) (2) Then, (3) (4) (5) Next, (5) This brings the processor back in This time, however, PC_ExitFlag is TRUE and the code following the if statement is executed. (7) (8) (9) |
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
void PC_DOSReturn (void)
{
PC_ExitFlag = TRUE; (1)
longjmp(PC_JumpBuf, 1); (2)
} |
Panel |
---|
(1) (2) When you want to return to DOS, all you have to do is call |
Elapsed Time Measurement
The elapsed time measurement functions are used to determine how much time a function takes to execute. Time measurement is performed by using the PC’s 82C54 timer #2. You make time measurement by wrapping the code to measure by the two functions PC_ElapsedStart
and PC_ElapsedStop
. However, before you can use these two functions, you need to call the function PC_ElapsedInit
. PC_ElapsedInit
basically computes the overhead associated with the other two functions. This way, the execution time (in microseconds) returned by PC_ElapsedStop
consist exclusively of the code you are measuring. Note that none of these functions are reentrant and thus, you must be careful that you do not invoke them from multiple tasks at the same time. .
Miscellaneous
PC_GetDateTime
is a function that obtains the PC’s current date and time, and formats this information into an ASCII string. The format is:
"YYYY-MM-DD HH:MM:SS"
and you will need at least 21 characters (including the NUL character) to hold this string. You should note that there are 2 spaces between the date and the time which explains why you need 21 characters instead of 20. PC_GetDateTime
uses the Borland C/C++ library functions gettime
and getdate
which should have their equivalent on other DOS compilers.
PC_GetKey
is a function that checks to see if a key was pressed and if so, obtains that key, and returns it to the caller. PC_GetKey
uses the Borland C/C++ library functions kbhit
and getch
which again, have their equivalent on other DOS compilers.
PC_SetTickRate
allows you to change the tick rate for µC/OS-II by specifying the desired frequency. Under DOS, a tick occurs 18.20648 times per second or, every 54.925 mS. This is because the 82C54 chip used didn’t get its counter initialized and the default value of 65535 takes effect. Had the chip been initialized with a divide by 59659, the tick rate would have been a very nice 20.000 Hz! I decided to change the tick rate to something more ‘exciting’ and thus, decided to use about 200 Hz (actually 199.9966). The code found in OS_CPU_A.O
calls the DOS tick handler one time out of 11. This is done to ensure that some of the housekeeping needed in DOS is maintained. You would not need to do this if you were to set the tick rate to 20 Hz. Before returning to DOS, PC_SetTickRate
is called by specifying 18 as the desired frequency. PC_SetTickRate
will know that you actually mean 18.2 Hz and will correctly set the 82C54.
The last two functions in PC.C
are used to get and set an interrupt vector. PC_VectGet
and PC_VectSet
should be compiler independent as long as the compiler support the macros MK_FP
(make far pointer), FP_OFF
(get the offset portion of a far pointer) and, FP_SEG
(get the segment of a far pointer).
Interface Functions
This section provides a reference section for the PC services.
PC_DispChar()
Code Block | ||
---|---|---|
| ||
void PC_DispChar(INT8U x, INT8U y, INT8U c, INT8U color) |
PC_DispChar
allows you to display a single ASCII (or special) character anywhere on the display.
Arguments
x
and y
specifies the coordinates (col, row) where the character will appear. rows (i.e., lines) are numbered from 0
to DISP_MAX_Y –
1, and columns are numbered from 0
to DISP_MAX_X –
1 (see PC.C
).
c
is the character to display. You can specify any ASCII characters and special characters if c
has a value higher than 128. You can see what characters (i.e., symbols) will be displayed based on the value of c
by running the test code provided in this book as follows:
C:\SOFTWARE\BLOCKS\SAMPLE\TEST > TEST display
color
specifies the contents of the attribute byte and thus the color combination of the character to be displayed. You can add one DISP_FGND_???
(see PC.H
) and one DISP_BGND_???
(see PC.H
) to obtain the desired color combination.
Returned Value
NONE
Notes/Warnings
NONE
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
.
.
for (;;) {
.
PC_DispChar(0, 0, '$', DISP_FGND_WHITE);
.
.
}
} |
PC_DispClrCol()
Code Block | ||
---|---|---|
| ||
void PC_DispClrCol(INT8U x, INT8U color) |
PC_DispClrCol
allows you to clear the contents of a column (all 25 characters).
Arguments
x
specifies which column will be cleared. Columns are numbered from 0
to DISP_MAX_X –
1 (see PC.C
).
color
specifies the contents of the attribute byte. Because the character used to clear a column is the space character (i.e., ‘ ‘), only the background color will appear. You can thus specify any of the DISP_BGND_???
colors.
Returned Value
NONE
Notes/Warnings
NONE
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
.
.
for (;;) {
.
PC_DispClrCol(0, DISP_BGND_BLACK);
.
.
}
} |
PC_DispClrRow()
Code Block | ||
---|---|---|
| ||
void PC_DispClrRow(INT8U y, INT8U color) |
PC_DispClrRow
allows you to clear the contents of a row (all 80 characters).
Arguments
y
specifies which row (i.e., line) will be cleared. Rows are numbered from 0
to DISP_MAX_Y –
1 (see PC.C
).
color
specifies the contents of the attribute byte. Because the character used to clear a row is the space character (i.e., ‘ ‘), only the background color will appear. You can thus specify any of the DISP_BGND_???
colors.
Returned Value
NONE
Notes/Warnings
NONE
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
.
.
for (;;) {
.
PC_DispClrRow(10, DISP_BGND_BLACK);
.
.
}
} |
PC_DispClrScr()
Code Block | ||
---|---|---|
| ||
void PC_DispClrScr(INT8U color) |
PC_DispClrScr
allows you to clear the entire display.
Arguments
color
specifies the contents of the attribute byte. Because the character used to clear the screen is the space character (i.e., ‘ ‘), only the background color will appear. You can thus specify any of the DISP_BGND_???
colors.
Returned Value
NONE
Notes/Warnings
You should use DISP_FGND_WHITE
instead of DISP_BGND_BLACK
because you don’t want to leave the attribute field with black on black.
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
.
.
PC_DispClrScr(DISP_FGND_WHITE);
for (;;) {
.
.
.
}
} |
PC_DispStr()
Code Block | ||
---|---|---|
| ||
void PC_DispStr(INT8U x, INT8U y, INT8U *s, INT8U color) |
PC_DispStr
allows you to display an ASCII string. In fact, you could display an array containing any of 255 characters as long as the array itself is NUL terminated.
Arguments
x
and y
specifies the coordinates (col, row) where the first character will appear. rows (i.e., lines) are numbered from 0
to DISP_MAX_Y –
1, and columns are numbered from 0
to DISP_MAX_X –
1 (see PC.C
).
s
is a pointer to the array of characters to display. The array MUST be NUL terminated. Note that you can display any characters from 0x01 to 0xFF.
color
specifies the contents of the attribute byte and thus the color combination of the characters to be displayed. You can add one DISP_FGND_???
(see PC.H
) and one DISP_BGND_???
(see PC.H
) to obtain the desired color combination.
Returned Value
NONE
Notes/Warnings
All the characters of the string or array will be displayed with the same color attributes.
Example #1
The code below displays the current value of a global variable called Temperature. The color used depends on whether the temperature is below 100 (white), below 200 (yellow) or if it exceeds 200 (blinking white on a red background).
Code Block | ||
---|---|---|
| ||
FP32 Temperature;
void Task (void *pdata)
{
char s[20];
.
.
PC_DispStr(0, 0, "Temperature:",
DISP_FGND_YELLOW + DISP_BGND_BLUE);
for (;;) {
sprintf(s, "%6.1f", Temperature);
if (Temperature < 100.0) {
color = DISP_FGND_WHITE;
} else if (Temperature < 200.0) {
color = DISP_FGND_YELLOW;
} else {
color = DISP_FGND_WHITE + DISP_BGND_RED + DISP_BLINK;
PC_DispStr(13, 0, s, color);
.
.
}
} |
Example #2
The code below displays a square b0x 10 characters wide by 7 characters high in the center of the screen.
Code Block | ||
---|---|---|
| ||
INT8U B0x[7][11] = {
{0xDA, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xBF, 0x00},
{0xB3, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xB3, 0x00},
{0xB3, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xB3, 0x00},
{0xB3, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xB3, 0x00},
{0xB3, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xB3, 0x00},
{0xB3, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xB3, 0x00},
{0xC0, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xD9, 0x00}
};
void Task (void *pdata)
{
INT8U i;
.
.
for (i = 0; i < 7; i++) {
PC_DispStr(35, i + 9, B0x[i], DISP_FGND_WHITE);
}
for (;;) {
.
.
}
} |
PC_DOSReturn()
Code Block | ||
---|---|---|
| ||
void PC_DOSReturn(void) |
PC_DOSReturn
allows your application to return back to DOS. It is assumed that you have previously called PC_DOSSaveReturn
in order to save the processor’s important registers in order to properly return to DOS. See section 18.02 for a description on how to use this function.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST have called PC_DOSSaveReturn
prior to calling PC_DOSReturn
.
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
INT16U key;
.
.
for (;;) {
.
.
if (PC_GetKey(&key) == TRUE) {
if (key == 0x1B) {
PC_DOSReturn(); /* Return to DOS */
}
}
.
.
}
} |
PC_DOSSaveReturn()
Code Block | ||
---|---|---|
| ||
void PC_DOSSaveReturn(void) |
PC_DOSSaveReturn
allows your application to save the processor’s important registers in order to properly return to DOS before you actually start multitasking with µC/OS-II. You would normally call this function from main
as shown in the example code provided below.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST call this function prior to setting µC/OS-II’s context switch vector (as shown below).
Example
Code Block | ||
---|---|---|
| ||
void main (void)
{
OSInit(); /* Initialize uC/OS-II */
.
PC_DOSSaveReturn(); /* Save DOS's environment */
.
PC_VectSet(uCOS, OSCtxSw); /* uC/OS-II's context switch vector */
OSTaskCreate(...);
.
.
OSStart(); /* Start multitasking */
} |
PC_ElapsedInit()
Code Block | ||
---|---|---|
| ||
void PC_ElapsedInit(void) |
PC_ElapsedInit
is invoked to compute the overhead associated with the PC_ElapsedStart
and PC_ElapsedStop
calls. This allows PC_ElapsedStop
to return return the execution time (in microseconds) of the code you are trying to measure.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST call this function prior to calling either PC_ElapsedStart()
and PC_ElapsedStop()
.
Example
Code Block | ||
---|---|---|
| ||
void main (void)
{
OSInit(); /* Initialize uC/OS-II */
.
.
PC_ElapsedInit(); /* Compute overhead of elapse meas. */
.
.
OSStart(); /* Start multitasking */
} |
PC_ElapsedStart()
Code Block | ||
---|---|---|
| ||
void PC_ElapsedStart(void) |
PC_ElapsedStart
is used in conjunction with PC_ElapsedStop
to measure the execution time of some of your application code.
Arguments
NONE
Returned Value
NONE
Notes/Warnings
You MUST call PC_ElapsedInit
before you use either PC_ElapsedStart()
and PC_ElapsedStop()
.
This function is non-reentrant and cannot be called by multiple tasks without proper protection mechanisms (i.e., semaphores, locking the scheduler, etc.).
The execution time of your code must be less than 54.93 milliseconds in order for the elapsed time measurement functions to work properly.
Example
Code Block | ||
---|---|---|
| ||
void main (void)
{
OSInit(); /* Initialize uC/OS-II */
.
.
PC_ElapsedInit(); /* Compute overhead of elapse meas. */
.
.
OSStart(); /* Start multitasking */
}
void Task (void *pdata)
{
INT16U time_us;
.
.
for (;;) {
.
.
PC_ElapsedStart();
/* Code you want to measure the execution time */
time_us = PC_ElaspedStop();
.
.
}
} |
PC_ElapsedStop()
Code Block | ||
---|---|---|
| ||
INT16U PC_ElapsedStop(void) |
PC_ElapsedStop
is used in conjunction with PC_ElapsedStart
to measure the execution time of some of your application code.
Arguments
NONE
Returned Value
The execution time of your code that was wrapped between PC_ElapsedStart()
and PC_ElapsedStop()
. The execution time is returned in microseconds.
Notes/Warnings
You MUST call PC_ElapsedInit()
before you use either PC_ElapsedStart()
and PC_ElapsedStop()
.
This function is non-reentrant and cannot be called by multiple tasks without proper protection mechanisms (i.e., semaphores, locking the scheduler, etc.).
The execution time of your code must be less than 54.93 milliseconds in order for the elapsed time measurement functions to work properly.
Example
See PC_ElapsedStart()
.
PC_GetDateTime()
void PC_GetDateTime(char *s)
PC_GetDateTime
is used to obtain the current date and time from the PC’s real-time clock chip and return this information in an ASCII string that can hold at least 21 characters.
Arguments
s
is a pointer to the storage area where the ASCII string will be deposited. The format of the ASCII string is:
"YYYY-MM-DD HH:MM:SS"
and requires 21 bytes of storage (note that there is 2 spaces between the date and the time.
Returned Value
NONE
Notes/Warnings
NONE
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
char s[80];
.
.
for (;;) {
.
.
PC_GetDateTime(&s[0]);
PC_DispStr(0, 24, s, DISP_FGND_WHITE);
.
.
}
} |
PC_GetKey()
Code Block | ||
---|---|---|
| ||
BOOLEAN PC_GetDateTime(INT16S *key) |
PC_GetKey
is used to see if a key was pressed at the PC’s keyboard and if so, obtain the value of the key pressed. You would normally invoke this function every so often (i.e., poll the keyboard) to see if a key was pressed. Note that the PC actually obtains key presses through an ISR and buffers key presses. Up to 10 keys are buffered by the PC.
Arguments
key
is a pointer to where the key value will be stored. If no key has been pressed, the value will contain 0x00.
Returned Value
TRUE is a key was pressed and FALSE otherwise.
Notes/Warnings
NONE
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
INT16S key;
BOOLEAN avail;
.
.
for (;;) {
.
.
avail = PC_GetKey(&key);
if (avail == TRUE) {
/* Process key pressed */
}
.
.
}
} |
PC_SetTickRate()
Code Block | ||
---|---|---|
| ||
void PC_SetTickRate(INT16U freq) |
PC_SetTickRate
is used to change the PC’s tick rate from the standard 18.20648 Hz to something faster. A tick rate of 200 Hz is a multiple of 18.20648 Hz (the multiple is 11).
Arguments
freq
is the desired frequency of the ticker.
Returned Value
NONE
Notes/Warnings
You can only make the ticker faster than 18.20648 Hz.
The higher the frequency, the more overhead you will impose on the CPU.
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
.
.
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(400); /* Reprogram PC's tick rate to 400 Hz */
OS_EXIT_CRITICAL();
.
.
for (;;) {
.
.
}
} |
PC_VectGet()
Code Block | ||
---|---|---|
| ||
void *PC_VectGet(INT8U vect) |
PC_VectGet
is used to obtain the address of the interrupt handler specified by the interrupt vector number. An 80x86 processor supports up to 256 interrupt/exception handlers.
Arguments
vect
is the interrupt vector number, a number between 0 and 255.
Returned Value
The address of the current interrupt/exception handler for the specified interrupt vector number.
Notes/Warnings
Vector number 0 corresponds to the RESET handler.
It is assumed that the 80x86 code is compiled using the ‘large model’ option and thus all pointers returned are ‘far pointers’.
It is assumed that the 80x86 is running in ‘real mode’.
Example
Code Block | ||
---|---|---|
| ||
void Task (void *pdata)
{
void (*p_tick_isr)(void);
.
.
p_tick_isr = PC_VectGet(0x08); /* Get tick handler address */
.
.
for (;;) {
.
.
}
} |
PC_VectSet()
Code Block | ||
---|---|---|
| ||
void PC_VectSet(INT8U vect, void *(pisr)(void)) |
PC_VectSet
is used to set the contents of an interrupt vector table location. An 80x86 processor supports up to 256 interrupt/exception handlers.
Arguments
vect
is the interrupt vector number, a number between 0 and 255.
Returned Value
The pisr
is the address of the current interrupt/exception handler for the specified interrupt vector number.
Returned Value
NONE
Notes/Warnings
Vector number 0 corresponds to the RESET handlerYou should be careful when setting interrupt vectors. Some interrupt vectors are used by the operating system (DOS and/or µC/OS-II).
It is assumed that the 80x86 code is compiled using the ‘large model’ option and thus all pointers returned are ‘far pointers’.
It is assumed that the 80x86 is running in ‘real mode’.
Example
PC_VectSet()
PC_VectSet
is used to set the contents of an interrupt vector table location. An 80x86 processor supports up to 256 interrupt/exception handlers.
Arguments
vect
is the interrupt vector number, a number between 0 and 255.
pisr
is the address of the interrupt/exception handler.
Returned Value
NONE
Notes/Warnings
You should be careful when setting interrupt vectors. Some interrupt vectors are used by the operating system (DOS and/or µC/OS-II).
It is assumed that the 80x86 code is compiled using the ‘large model’ option and thus all pointers returned are ‘far pointers’.
If your interrupt handler works in conjunction with µC/OS-II, it must follow the rules imposed by µC/OS-II (see page 91 of “MicroC/OS-II, The Real-Time Kernel”, ISBN 0-87930-543-6).
...
model’ option and thus all pointers returned are ‘far pointers’.
If your interrupt handler works in conjunction with µC/OS-II, it must follow the rules imposed by µC/OS-II (see page 91 of “MicroC/OS-II, The Real-Time Kernel”, ISBN 0-87930-543-6).
Example
Code Block | ||
---|---|---|
| ||
void InterruptHandler (void)
{
}
void Task (void *pdata)
{
.
.
PC_VectSet(64, InterruptHandler);
.
.
for (;;) {
.
.
}
} |