uCOS View
uCOS View
µC/OS-View
V1.10
User’s Manual
www.Micrium.com
µC/OS-View
1.00 Introduction
µC/OS-View is a combination of a Microsoft Windows application program and code that resides in your
target system (i.e. your product). The Windows application connects with your system via an RS-232C
serial port as shown in Figure 1-1. The Windows application allows you to ‘View’ the status of your tasks
which are managed by µC/OS-II.
2
µC/OS-View
µC/OS-View allows you to view the following information from a µC/OS-II based product:
• ‘Suspend’ the tick interrupt from decrementing delays and timeouts of tasks. However, you can
‘step’ on tick at a time by pressing the F8 key from the Windows application. The F6 key
cancels this mode, the F7 key enables this mode and the F8 key enables one tick to be
processed.
• Pass keystrokes to you application from the ‘Terminal’ window. In other words, you can now
send commands to your product from the Windows application. You determine the command
structure.
• Output ASCII strings from the target to the ‘Terminal’ window. These ASCII strings are target
specific and thus you can define those specific to your product.
3
µC/OS-View
• µC/OS-View now support the stepping feature of the viewer. In other words, pressing the F7
key on the viewer pauses the µC/OS-II ticker. Pressing the F8 key allows one tick to be
executed and pressing the F6 key resumes normal operation of the ticker. Note that
OSTimeTickHook() is still called at the tick rate in case your application has time critical
needs.
• µC/OS-View no longer needs to use OSTCBExtPtr, µC/OS-II’s OS_TCB extension pointer.
This allows you to extend an OS_TCB for your own use.
• µC/OS-II V2.61 now allows you to assign a name to a task and thus, this feature is no longer
part of µC/OS-View.
• There is no need for a µC/OS-View task anymore since stack usage statistics are now
determined by µC/OS-II’s statistic task. This means that µC/OS-View doesn’t ‘eat up’ a task
and stack space. Also, statistics (variables) allocated by µC/OS-View are no longer needed
since those have been placed in µC/OS-II’s OS_TCB.
4
µC/OS-View
1. Task List
2. System Variables
3. Terminal Window Systems Variables
4. CPU load vs Time
Display Area
(See section 2.02)
Task List
Display Area
(See section 2.01)
Terminal Window
(See section 2.03)
5
µC/OS-View
Prio Indicates the task priority of each task. Note that entries in the task list are always
sorted by task priority.
Id Is a unique ID for each task. In fact, this field contains the address of the OS_TCB of
the task.
Name Is the name of the task. Assigning a name to a task is a new feature that was added
to µC/OS-II V2.6x. The name is actually stored in the target system and sent to the
Windows application along with the other information about your tasks (see section
3.03 for details on how to set the task names). The number of characters you can
use for a task name depends on the µC/OS-II configuration constant
OS_TASK_NAME_SIZE found in OS_CFG.H.
Status This field indicates the status of each task. A task can have the following statuses:
DELAY A task is waiting for time to expire. The Timeout (described later) field
indicates how many ticks remains before the task is ready to run.
MBOX The task is waiting on a message mailbox. The Data field shows the
address (in Hexadecimal) of the Event Control Block associated with the
mailbox. The Timeout field indicates the amount of time (in ticks) that
the task is willing to wait for the mailbox to be posted. An empty timeout
indicates that the task will wait forever for the mailbox to be posted.
Q The task is waiting on a message queue. The Data field shows the
address (in Hexadecimal) of the Event Control Block associated with the
queue. The Timeout field indicates the amount of time (in ticks) that the
task is willing to wait for the queue to be posted. An empty timeout
indicates that the task will wait forever for the queue to be posted.
MUTEX The task is waiting on a mutex. The Data field shows the address (in
Hexadecimal) of the Event Control Block associated with the mutex. The
Timeout field indicates the amount of time (in ticks) that the task is willing
to wait for the mutex to be signaled (i.e. released). An empty timeout
indicates that the task will wait forever for the mutex.
FLAG The task is waiting on an event flag group. The Data field shows the
address (in Hexadecimal) of the event flag group. The Timeout field
indicates the amount of time (in ticks) that the task is willing to wait for
the desired flags to be set or cleared. An empty timeout indicates that
the task will wait forever for the desired flag(s).
6
µC/OS-View
Stack This field contains three pieces of information: the amount of stack space used (in
bytes), the total stack space available to the task (in bytes) and the base address of
the task’s stack. If the stack grows downwards (from high to low memory) then this
field contains the highest memory location of your stack. If the stack grows upwards
(from low to high memory) then this field contains the lowest memory location of your
stack. This field is useful to see just how much stack space is left for each task.
CPULoad This field indicates the amount of CPU time consumed by each task expressed as a
percentage. Of course, a higher number indicates that your task consumes a high
amount of the CPU’s time.
ContextSwitches Contains the total number of context switches to the task since your application
started.
OS_VERSION This field indicates the version of µC/OS-II running in your target system.
This field will not change at run-time.
CPU Indicates the type of CPU in your target system. This field will not
change at run-time.
#Ticks Contains the value of µC/OS-II’s global variable OSTime which indicates
the number of ticks since power up or, since you last called
OSTimeSet().
IntStack Indicates the base address of the interrupt stack if a separate stack area
is reserved for interrupts.
7
µC/OS-View
You can setup µC/OS-View to display either all your tasks at the same time or select to display up to 5
tasks on the graph. To change this option, simply click on the Setup menu item and then click on the
CPU View tab as shown in Figure 2-2.
As shown in Figure 2-3, if you click on the Task Selection’s Use Filter check box, you can actually specify
which of up to 5 tasks you can show on the graph. You simply select the tasks that you want to view by
name.
8
µC/OS-View
9
µC/OS-View
3.01 Restrictions
When you compile the target resident code with your µC/OS-II application, you need to abide by the
following restrictions:
10
µC/OS-View
L3-1(2) You should pass a NULL pointer as the pext argument if you are not using the TCB
extension.
L3-1(3) You must also specify that you want to enable stack checking for the task as well as clear the
stack upon task creation.
L3-1(4) You must call OSTaskNameSet() and pass this function the task priority as well as a name
you would like to give to the task. The name can contain spaces and some punctuation
marks. The size (number of characters) of the name MUST be less than
OS_TASK_NAME_SIZE-1.
INT8U err;
OSTaskCreateExt(YourTask, (1)
(void *)0,
&YourTaskStk[YOUR_TASK_STK_SIZE - 1],
your_task_prio,
your_task_prio,
&YourTaskStk[0],
YOUR_TASK_STK_SIZE,
(void *)0, (2)
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); (3)
OSTaskNameSet(prio, "Your Task Name!", &err); (4)
11
µC/OS-View
Figure 3-1 shows what happens when you select the Terminal Window and type at the keyboard.
(2) Display
(3)
Your
Target
(6) Display (5) (4)
(1)
Keyboard
F3-1(4) Your target gets a ‘notification’ that a character has arrived from µC/OS-View and performs
some action that YOU determine. In this case, I decided that receiving a ‘1’ meant that you
wanted to know what the current CPU usage is.
F3-1(5) The target then formats a reply string and send it to the terminal window.
F3-1(6) µC/OS-View sees that an ASCII string is received from the target and displays it on the
terminal window.
12
µC/OS-View
Figure 3-1 shows that I typed other characters. Specifically, typing a ‘2’ results in the target replying
back with the number of tasks created. Typing a ‘3’ resulted in displaying this simple menu. In fact, the
code I have only recognizes either a ‘1’ or a ‘2’ and, any other key displays the menu.
In order for the target to recognize the keys being sent from the terminal window, you need to install a
‘callback’ function by calling OSView_TerminalRxSetCallback(). In other words, when a character
is received, the µC/OS-View’s target resident code calls the function that you install. The code below
shows how that’s done:
OSView_TerminalRxSetCallback(TestTerminalCallback);
µC/OS-View will call your function and pass it the character received from the terminal window. You
need to know that the callback (TestTerminalCallback() in the case above) is called by an ISR and
thus, you should post the character received to a task (as shown above), and let the task process the
received character (as shown in the code below). Of course, the mailbox needs to be created before it’s
actually used by the callback. Also, YOUR callback function needs to be declared as shown above.
You can create your own commands for your target system. Specifically, you could have code that
initiates special tests on your hardware in response to certain keystrokes, you could create commands
that changes the operating mode of your target, you could create commands that displays the contents of
variables and memory locations and more.
13
µC/OS-View
pdata = pdata;
while (TRUE) {
key = (char)OSMboxPend(TestTerminalMbox, 0, &err);
TestTerminalMsgCtr++;
sprintf(s, "%05u", TestTerminalMsgCtr);
PC_DispStr(60, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);
switch (key) {
case '1':
sprintf(s, "\nCPU Usage = %3u%%\n", OSCPUUsage);
OSView_TxStr(s, 1);
break;
case '2':
sprintf(s, "\n#Tasks = %3u\n", OSTaskCtr);
OSView_TxStr(s, 1);
break;
default:
OSView_TxStr("\n\nMicrium, Inc.", 1);
OSView_TxStr("\n1: CPU Usage (%)", 1);
OSView_TxStr("\n2: #Tasks", 1);
OSView_TxStr("\n?: Help (This menu)\n", 1);
break;
}
}
}
14
µC/OS-View
You can download µC/OS-View ports from the Micriµm web site at www.Micrium.com. µC/OS-View ports
are found next to µC/OS-II ports.
As a minimum, a port should define the code for 18 functions as listed below. Most of these functions are
expected by OS_VIEW.C (i.e. the target independent code).
OSView_Exit()
OSView_GetCPUName()
OSView_GetIntStkBase()
OSView_GetIntStkSize()
OSView_InitTarget()
OSView_RxIntDis()
OSView_RxIntEn()
OSView_RxISR()
OSView_RxISRHandler()
OSView_RxTxISR()
OSView_RxTxISRHandler()
OSView_TickHook()
OSView_TimeGetCycles()
OSView_Tx1()
OSView_TxIntDis()
OSView_TxIntEn()
OSView_TxISR()
OSView_TxISRHandler()
15
µC/OS-View
OSView_Exit()
void OSView_Exit(void);
OSView_Exit() is called by your application when you want to stop running µC/OS-View. This function
is meant to perform some cleanup operations such as disabling Rx or Tx interrupts, releasing interrupt
vectors, and so on.
Arguments
None.
Returned Value
None
Notes/Warnings
None
Example
16
µC/OS-View
OSView_GetCPUName()
void OSView_GetCPUName(char *s);
OSView_GetCPUName() is called by the processor independent code to obtain the name of the CPU
that the viewer is connected to. This function is trivial to write since it only involves copying the name of
the processor into a string.
Arguments
s is a pointer to the name of the CPU. The name of the CPU should NOT exceed 29 characters
(30 if you include the NUL character).
Returned Value
None
Notes/Warnings
You should not be calling this function from your application because it is called by the processor
independent code.
Example
17
µC/OS-View
OSView_GetIntStkBase()
INT32U OSView_GetIntStkBase(void);
OSView_GetIntStkBase() is called by the processor independent code to obtain the base address of
the interrupt stack, if a separate interrupt stack is used. If the processor you are using doesn’t have an
interrupt stack or, you have not implemented that feature in software then this function should return 0.
Arguments
None
Returned Value
None
Notes/Warnings
You should not be calling this function from your application because it is called by the processor
independent code.
Example
OR
18
µC/OS-View
OSView_GetIntStkSize()
INT32U OSView_GetIntStkSize(void);
OSView_GetIntStkSize() is called by the processor independent code to obtain the size (in number
of bytes) of the interrupt stack, if a separate interrupt stack is used. If the processor you are using
doesn’t have an interrupt stack or, you have not implemented that feature in software then this function
should return 0.
Arguments
None
Returned Value
None
Notes/Warnings
You should not be calling this function from your application because it is called by the processor
independent code.
Example
OR
19
µC/OS-View
OSView_InitTarget()
void OSView_InitTarget(void);
Arguments
None
Returned Value
None
Notes/Warnings
You should not be calling this function from your application because it is called by the processor
independent code.
Example
20
µC/OS-View
OSView_RxIntDis()
void OSView_RxIntDis(void);
OSView_RxIntDis() is not currently called by the processor independent code but could be in a future
release. However, it can be used by the target specific code to disable interrupts from the UART
(Universal Asynchronous Receiver Transmitter) receiver. This function must ONLY disable receiver
interrupts.
Arguments
None
Returned Value
None
Notes/Warnings
This function should only disable interrupts from the receiver and not affect other interrupt sources. For
this, you may need to read the current interrupt disable mask register, alter the bit(s) needed to disable
the receiver interrupt and write the new value to the interrupt mask register.
Example
(80x86 port using COM1 on a PC)
OS_ENTER_CRITICAL();
stat = inp(OS_VIEW_8250_BASE + OS_VIEW_8250_IER) & ~BIT0;
outp(OS_VIEW_8250_BASE + OS_VIEW_8250_IER, stat);
if (stat == 0x00) {
mask = inp(OS_VIEW_8259_MASK_REG);
mask |= OS_VIEW_8259_COMM_INT_EN;
outp(OS_VIEW_8259_MASK_REG, mask);
}
OS_EXIT_CRITICAL();
}
21
µC/OS-View
OSView_RxIntEn()
void OSView_RxIntEn(void);
OSView_RxIntEn() is not currently called by the processor independent code but could be in a future
release. However, it can be used by the target specific code to enable interrupts from the UART
(Universal Asynchronous Receiver Transmitter) receiver. This function must ONLY enable receiver
interrupts.
Arguments
None
Returned Value
None
Notes/Warnings
This function should only enable interrupts from the receiver and not affect other interrupt sources. For
this, you may need to read the current interrupt disable mask register, alter the bit(s) needed to enable
the receiver interrupt and write the new value to the interrupt mask register.
Example
(80x86 port using COM1 on a PC)
OS_ENTER_CRITICAL();
stat = inp(OS_VIEW_8250_BASE + OS_VIEW_8250_IER) | BIT0;
outp(OS_VIEW_8250_BASE + OS_VIEW_8250_IER, stat);
cmd = inp(OS_VIEW_8259_MASK_REG) & ~OS_VIEW_8259_COMM_INT_EN;
outp(OS_VIEW_8259_MASK_REG, cmd);
OS_EXIT_CRITICAL();
}
22
µC/OS-View
OSView_RxISR()
void OSView_RxISR(void);
OSView_RxISR() is the interrupt service routine (ISR) that is invoked by the processor hardware when a
character is received by the UART (Universal Asynchronous Receiver Transmitter). If the UART issues a
combined interrupt for a received and transmitted character then your interrupt should vector to
OSView_RxTxISR() instead.
Arguments
None
Returned Value
None
Notes/Warnings
You don’t need to write the contents of this function if your UART issues a combined ISR for both Rx and
Tx characters. However, you MUST declare the function but leave the contents empty.
Example (Pseudo-code)
OSView_RxISR:
Save ALL CPU registers;
OSIntNesting++; /* Notify uC/OS-II of ISR entry */
if (OSIntNesting == 1) { /* Save SP in TCB if first nested ISR */
OSTCBCur->OSTCBStkPtr = SP;
}
OSView_RxISRHandler(); /* Call the C handler in OS_VIEWc.C */
OSIntExit(); /* Notify uC/OS-II of ISR completion */
Restore all the CPU registers;
Return from Interrupt;
23
µC/OS-View
OSView_RxISRHandler()
void OSView_RxISRHandler(void);
Arguments
None
Returned Value
None
Notes/Warnings
You don’t need to write the contents of this function if your UART issues a combined ISR for both Rx and
Tx characters. However, you MUST declare the function but leave the contents empty.
Example
24
µC/OS-View
OSView_RxTxISR()
void OSView_RxTxISR(void);
OSView_RxTxISR() is the interrupt service routine (ISR) that is invoked by the processor hardware
when either a character is received or transmitted by the UART (Universal Asynchronous Receiver
Transmitter). If the UART issues a separate interrupt for a received character and another one for a
transmitted character then, you should instead use OSView_RxISR() and OSViewTxISR(),
respectively.
Arguments
None
Returned Value
None
Notes/Warnings
You don’t need to write the contents of this function if your UART issues a separate ISR for for Rx and Tx
characters. However, you MUST declare the function but leave the contents empty.
Example (Pseudo-code)
OSView_RxTxISR:
Save ALL CPU registers;
OSIntNesting++; /* Notify uC/OS-II of ISR entry */
if (OSIntNesting == 1) { /* Save SP in TCB if first nested ISR */
OSTCBCur->OSTCBStkPtr = SP;
}
OSView_RxTxISRHandler(); /* Call the C handler in OS_VIEWc.C */
OSIntExit(); /* Notify uC/OS-II of ISR completion */
Restore all the CPU registers;
Return from Interrupt;
25
µC/OS-View
OSView_RxTxISRHandler()
void OSView_RxTxISRHandler(void);
Arguments
None
Returned Value
None
Notes/Warnings
You don’t need to write the contents of this function if your UART issues a combined ISR for both Rx and
Tx characters. However, you MUST declare the function but leave the contents empty.
Example
if (Rx interrupt) {
c = Read character from UART;
OSView_RxHandler(c); /* Pass to processor independent code */
Clear Rx interrupt;
}
if (Tx interrupt) {
OSView_TxHandler(); /* Call processor independent code */
Clear Tx interrupt;
}
}
26
µC/OS-View
OSView_TickHook()
void OSView_TickHook(void);
OSView_TickHook() MUST be called from the µC/OS-II function OSTimeTickHook(). Hopefully, you
would have access to the µC/OS-II port files and thus, you should simply add the call to the function
there.
Arguments
None
Returned Value
None
Notes/Warnings
None
Example
See OSView_TimeCyclesGet() (next function) for a description of the code presented in this example.
27
µC/OS-View
OSView_TimeGetCycles()
INT32U OSView_TimeGetCycles(void);
OSView_TimeGetCycles() is called by the processor independent code to read the current ‘absolute’
time which is generally provided by a real-time clock or a timer. Preferably, this clock would have a
resolution in the microsecond range, or better. A 32-bit counter is preferable. However, if you can’t get
this from your hardware, you can obtain sufficient resolution from a 16-bit counter as long as you can
keep track of overflows or sample the timer faster than its overflow rate.
Arguments
None
Returned Value
Notes/Warnings
You should not be calling this function from your application because it is called by the processor
independent code.
28
µC/OS-View
The drawing below shows a free running timer that counts up from 0 to 65535 and rolls over to 0. If
µC/OS-II’s tick rate is faster than the rollover rate then you could ‘sample’ this free-running timer by
hooking into µC/OS-II’s tick ISR as shown in the code below. OSView_CyclesCtr simply needs to
contain the sum of the Deltas. Because we use ‘unsigned’ arithmetic, a ‘small’ New value minus a
‘large’ Prev value results in the proper delta. Because OSView_CyclesCtr is actually updated in
OSView_TickHook(), OSView_TimeGetCycles() simply needs to return the value. You should be
able to do something similar with a 16-bit down counter.
µC/OS-II’s Tick
Prev
65535
New
Time
OSView_CyclesCtr
OS_ENTER_CRITICAL();
cycles = OSView_CyclesCtr;
OS_EXIT_CRITICAL();
Return (cycles);
}
29
µC/OS-View
OSView_Tx1()
void OSView_Tx1(INT8U data);
OSView_Tx1() is called by the processor independent code to send a single byte to the serial port.
Arguments
Returned Value
None
Notes/Warnings
You should not be calling this function from your application because it is called by the processor
independent code.
Example
30
µC/OS-View
OSView_TxIntDis()
void OSView_TxIntDis(void);
OSView_TxIntDis() is called by the processor specific and independent code to disable interrupts
from the UART (Universal Asynchronous Receiver Transmitter) transmitter.
Arguments
None
Returned Value
None
Notes/Warnings
This function should only disable interrupts from the transmitter and not affect other interrupt sources.
For this, you may need to read the current interrupt disable mask register, alter the bit(s) needed to
disable the transmitter interrupt and write the new value to the interrupt mask register.
Example
31
µC/OS-View
OSView_TxIntEn()
void OSView_TxIntEn(void);
OSView_TxIntEn() is called by the processor independent code to enable interrupts from the UART
(Universal Asynchronous Receiver Transmitter) receiver.
Arguments
None
Returned Value
None
Notes/Warnings
This function should only enable interrupts from the transmitter and not affect other interrupt sources. For
this, you may need to read the current interrupt disable mask register, alter the bit(s) needed to enable
the transmitter interrupt and write the new value to the interrupt mask register.
Example
32
µC/OS-View
OSView_TxISR()
void OSView_TxISR(void);
OSView_TxISR() is the interrupt service routine (ISR) that is invoked by the processor hardware when a
character has been transmitted by the UART (Universal Asynchronous Receiver Transmitter). If the
UART issues a combined interrupt for a received and transmitted character then your interrupt should
vector to OSView_RxTxISR() instead.
Arguments
None
Returned Value
None
Notes/Warnings
You don’t need to write the contents of this function if your UART issues a combined ISR for both Rx and
Tx characters. However, you MUST declare the function but leave the contents empty.
Example (Pseudo-code)
OSView_TxISR:
Save ALL CPU registers;
OSIntNesting++; /* Notify uC/OS-II of ISR entry */
if (OSIntNesting == 1) { /* Save SP in TCB if first nested ISR */
OSTCBCur->OSTCBStkPtr = SP;
}
OSView_TxISRHandler(); /* Call the C handler in OS_VIEWc.C */
OSIntExit(); /* Notify uC/OS-II of ISR completion */
Restore all the CPU registers;
Return from Interrupt;
33
µC/OS-View
OSView_TxISRHandler()
void OSView_TxISRHandler(void);
Arguments
None
Returned Value
None
Notes/Warnings
None
Example
34
µC/OS-View
OS_VIEW_BAUDRATE This constant defines the RS-232C communications baud rate between
the Windows application and your target system. The default baud rate
is 38400 and you should not change it unless your processor and serial
port is unable to support this speed. The serial port is configured for 8
bits, no parity and 1 stop bit.
OS_VIEW_RX_BUF_SIZE This #define determines the size of the buffer used to receive packets
from the Windows application. You should not have to change the
default value of 20.
OS_VIEW_TX_BUF_SIZE This #define determines the size of the buffer used to hold reply
packets going back to the Windows application. The size you need
depends on the number of tasks in your application. Each task requires
4 bytes. However, you should not set this #define to a value less than
64. The maximum is 255 which allows you to display the status of up to
63 tasks.
OS_VIEW_TX_STR_SIZE This #define determines the size of the buffer used to hold reply
packets going back to the ‘Terminal Window’. The size you need
depends on the maximum number of characters you will send to the
terminal window using OSView_TxStr(). You should not set this
#define to a value less than 64. The maximum is 255.
35
µC/OS-View
Code Space It’s difficult to determine the exact amount of code space needed because this is compiler
dependent. On an Intel 80x86 (Large Model) compiled using the Borland C/C++ V4.52
compiler, code space is about 4.5 Kbytes.
7 * sizeof(INT8U) +
OS_VIEW_RX_BUF_SIZE * sizeof(INT8U) +
OS_VIEW_TX_BUF_SIZE * sizeof(INT8U) +
OS_VIEW_TX_STR_SIZE * sizeof(INT8U) +
9 * sizeof(INT16U) +
2 * sizeof(void *)
On an Intel 80x86 (Large Model) compiled using the Borland C/C++ V4.52 compiler, data
space is shown in the table below:
36
µC/OS-View
References
µC/OS-II, The Real-Time Kernel, 2nd Edition
Jean J. Labrosse
R&D Technical Books, 2002
ISBN 1-5782-0103-9
Contacts
Micriµm, Inc.
949 Crestview Circle
Weston, FL 33327
USA
+1 954 217 2036
+1 954 217 2037 (FAX)
e-mail: Jean.Labrosse@Micrium.com
WEB: www.Micrium.com
JK Microsystems, Inc.
1403 Fifth Street, Suite D
Davis, CA 95616
USA
+1 530 297 6073
+1 530 297 6074 (FAX)
WEB: http://www.JKMicro.com
e-mail: jkmicro@jkmicro.com
37