For Zilog Z180 Microprocessors: Integrated C Development System
For Zilog Z180 Microprocessors: Integrated C Development System
Version 6.x
Application Frameworks
019-0081 020330-B
Copyright
2002 Z-World, Inc. All rights reserved.
Z-World, Inc. reserves the right to make changes and improvements to its
products without providing notice.
Trademarks
Notice to Users
When a system failure may cause serious consequences, protecting life and
property against such consequences with a backup system or safety device
is essential. The buyer agrees that protection against consequences
resulting from system failure is the buyers responsibility.
This device is not approved for life-support or medical systems.
Company Address
Z-World, Inc.
(530) 757-3737
(530) 753-5141
http://www.z w orld.c om
[email protected]
TABLE OF CONTENTS
About This Manual
vii
Chapter 1: Introduction
11
13
Chapter 3: Costatements
21
Application Frameworks
37
41
51
55
63
iv s Table of Contents
Dynamic C 32 v. 6.x
75
83
87
Index
95
Application Frameworks
Table of Contents s v
vi s Table of Contents
Dynamic C 32 v. 6.x
Application Frameworks
Assumptions
Assumptions are made regarding the user's knowledge and experience in
the following areas.
Understanding of the basics of operating a software program and
editing files under Windows on a PC.
Knowledge of the basics of C programming. Dynamic C is not the
same as standard C.
Acronyms
Table 1 lists the acronyms that may be used in this manual.
Table 1. Acronyms
Acronym
Meaning
EPROM
EEPROM
LCD
LED
Light-Emitting Diode
NMI
Nonmaskable Interrupt
PIO
PRT
RAM
RTC
Real-Time Clock
SIB
SRAM
UART
Dynamic C 32 v. 6.x
Icons
Table 2 displays and defines icons that may be used in this manual.
Table 2. Icons
Icon
$
(
Meaning
Icon
Refer to or see
Note
Please contact
7LS
Tip
Caution
FD
Meaning
High Voltage
Factory Default
Conventions
Table 3 lists and defines typographic conventions that may be used in this
manual.
Table 3. Typographical Conventions
Example
Description
while
// IN-01
Italics
Edit
...
[ ]
< >
a | b | c
Application Frameworks
Dynamic C 32 v. 6.x
CHAPTER 1: INTRODUCTION
Application Frameworks
Introduction s 11
12 s Introduction
Dynamic C 32 v. 6.x
CHAPTER 2:
REAL-TIME PROGRAMMING
Interrupt Latency
Multitasking
Application Frameworks
Real-Time Programming s 13
Interrupt Latency
Interrupt latency is usually defined as the worst-case delay between an
interrupt request and the start of the interrupt service. Typical values for
this delay are about 100 microseconds.
Low interrupt latency is necessary when speed is important, or when it is
important that an interrupt not be missed, such as a periodic timer interrupt.
Causes
A delay between an interrupt request and the start of the interrupt service
can occur for several reasons.
1. The current instruction must finish executing. This is never more than
14 clock periods on the Z180.
2. The return address must be pushed on the stack. This is about 10 more
clock periods.
3. Atomic store and read operations associated with shared and
protected variables result in interrupts being disabled for about
10 microseconds on a 9-MHz processor. (Atomic structure assignments, of course, can cause longer delays.)
The above-mentioned delays are relatively minor since they are simply the
overhead from processing interrupts. More serious delays occur when
interrupts are disabled when an interrupt is requested. Interrupts can be
disabled, for example, during critical sections of code. Interrupt processing itself disables interrupts until the interrupt service routine reenables
them or exits.
If software turns off interrupts for 25 microseconds and an interrupt
request happens just as the interrupts are disabled, the interrupt service will
be delayed for an additional 25 microseconds.
14 s Real-Time Programming
Dynamic C 32 v. 6.x
A running program will fail if the interrupt latency is too great. For
example, if the serial port is receiving characters every 173 microseconds
(57,600 baud), then an interrupt latency of 2173s = 347 microseconds
will cause a lost character because the serial port can only hold two
characters before it loses one.
Interrupt routines are usually most efficient when written in assembly
language, but interrupt routines can be written in Dynamic C at the
expense of a minimum overhead of about 25 microseconds on a 9-MHz
processor, which is the time necessary to save the registers. If the service
routine leaves interrupts off for its duration, then it is necessary to add
another 30 microseconds to the latency calculation, to allow for the return
from interrupt, plus the amount of time it takes to execute the routine. The
advantage of assembly-language routines is that they need only to save the
registers that they use, while the C interrupt routine assumes that everything possible must be saved. Assembly language also has more direct
access to the machine registers.
Nested Interrupts
With sufficient care, it is possible to reenable interrupts inside an interrupt
routine. This lessens the interrupt latency because interrupts do not stay
disabled for the duration of the interrupt handler.
In general, the cause of a type X interrupt should be removed before
interrupts are reenabled for the type X interrupt. When this is done, one
interrupt routine can interrupt another interrupt routine. For example, a
serial port interrupt routine on the Z180 can reenable interrupts in general
while disabling the serial port interrupt specifically. The serial port
interrupt can then be reenabled upon returning from the interrupt routine.
However, such a practice can create difficulties, particularly if a nested
interrupt lasts for a long time. There is no way to get back to the original
interrupt service until the nested interrupt is complete, at which point some
data may be lost.
A logical solution in this situation is to establish a software flag that
prevents a lengthy task from interrupting a service routine. Were this idea
taken to extremes, there would eventually be an operating system where
every interrupt is logged by the operating system and then dispatched in a
priority order. Z-World provides two real-time kernels to help the user
solve these problems.
Application Frameworks
Real-Time Programming s 15
Multitasking
A task is an ordered list of operations to perform. In a multitasking
environment, more than one task (each representing a sequence of operations) can appear to execute in parallel. In reality, a single processor can
only execute one instruction at a time, so the parallel tasks execute almost
in parallel.
If an application has multiple tasks to perform, multitasking software can
usually take advantage of natural delays in each task to increase the overall
performance of the system. Each task can do some of its work while the
other tasks are waiting for an event, or for something to do.
Although multitasking may actually decrease processor throughput
slightly, it is an important concept. A controller is often connected to more
than one external device. A multitasking approach makes it possible to
write a program controlling multiple devices without having to think about
all the devices at the same time. In other words, multitasking is an easier
way to think about the system.
There are two types of multitasking available for developing applications
in Dynamic C: preemptive and cooperative.
Cooperative Multitasking
In a cooperative multitasking environment, each task voluntarily gives up
control so other tasks can execute. A kernel is not required in this case
because the tasks cooperate among themselves. If periodic task scheduling
or time delays are not required, a cooperative multitasking environment
does not require a timer interrupt.
The following advantages are offered by cooperative multitasking.
Much easier communication between tasks.
Greater predictability of mutual task interaction.
Much simplified programming.
Dynamic C has a language extension called the costatement to support
cooperative multitasking. In essence, a costatement is a cooperative task.
Preemptive Multitasking
Preemption means tasks are interrupted and control is taken away involuntarily (by an interrupt). We say a task is preempted by another task,
perhaps of a higher priority. A task has no control of when preemption
may take place, when preemption is enabled, but a task can turn off
preemption altogether (by disabling interrupts).
16 s Real-Time Programming
Dynamic C 32 v. 6.x
Application Frameworks
Real-Time Programming s 17
// atomic variables
Dynamic C 32 v. 6.x
Application Frameworks
Real-Time Programming s 19
20 s Real-Time Programming
Dynamic C 32 v. 6.x
CHAPTER 3: COSTATEMENTS
Costatements allow cooperative multitasking within an application.
Costatements are blocks of code that can suspend their own execution at
various times for various reasons, allowing other costatements or other
program code to execute. Costatements operate concurrently.
There are several advantages such as the following to using costatements.:
Costatement functions
Application Frameworks
Costatements s 21
Task 1
Task 2
Task n
If there are other tasks to be run, this control problem can be solved better
by creating a larger loop that processes a number of tasks. Now, each task
can relinquish control when it is waiting, thereby allowing other tasks to
proceed. Each task then does its work in the idle time of the other tasks.
This situation is like that of a worker who goes from station to station
performing jobs according to an instruction book at each station. By
traveling from station to station, the worker can execute long sequences of
jobs without having to waste time at any station waiting for the next event.
22 s Costatements
Dynamic C 32 v. 6.x
This is similar to a cook who has 5 to 10 ovens and many cook pots to
prepare many different meals at the same time.
if( state==1 ){
if( buttonpushed() ){
state=2;
turnondevice1();
timer1 = time;
}else if( state==2 ){
if( (time-timer1) >= 60L){
state=3;
turnondevice2();
timer2=time;
}
}else if( state==3 ){
if( (time-timer2) >= 60L){
state=1;
turnoffdevice1();
turnoffdevice2();
}
}
(other tasks or state machines)
Application Frameworks
// task 1
// task 2
// task n
Costatements s 23
This solution is elegant and simple. Note that the costatement (the one that
is written out) looks much like the original description of the problem. All
the branching, nesting and variables within the task are hidden in the
implementation of the costatement and its waitfor statements.
Summary
The Dynamic C costatement provides a formalized way of generating code
that advances until it encounters a point in the logic where it is necessary
to create a delay or wait for an event. Waiting is accomplished by jumping
out of the costatement to allow the larger loop to continue execution.
Whenever a costatement is defined, the compiler creates an associated
CoData data structure at the same time. The address of the current starting
point in the costatement and the time at which the currently running delay
(if any) began are saved in the data structure.
A costatement can be thought of as a local computer with its own instruction counter. One or more statements are executed in the costatement on
each pass of the execution thread.
Costatements are cooperative concurrent tasks because they can suspend
their own operation. There are several ways they do this.
They can waitfor events, conditions, or the passage of time.
They can yield temporarily to other costatements.
They can abort their own operation.
Costatements can also resume their own execution from the point at which
they suspended their operation. In general, each costatement in a set of
costatements is in a state of partial completion. Some are suspended, some
are executing. With the passage of time, all costatements should suspend
and then resume.
All costatements in the program, except those that use pointers as their
names are initialized whenever the function chain _GLOBAL_INIT is
called.
!
$
24 s Costatements
Dynamic C 32 v. 6.x
Costatement Functions
Syntax
The general format of a costatement appears below.
costate [ name [state] ] {
[ statement | yield; | abort; | waitfor( expression ); ] . . .
}
State
The term state can be one of the following.
always_on. The costatement is always active. (Unnamed
costatements are always on.)
init_on. The costatement is initially on and will automatically
execute the first time it is encountered in the execution thread.
The costatement becomes inactive after it completes (or aborts).
If state is absent, the costatement is initially off. The software must
trigger the costatement for the costatement to execute. Then it will execute
once and become inactive again. Unnamed costatements are always_on.
Application Frameworks
Costatements s 25
The CSState field contains two flags, STOPPED and INIT. The functions
CoBegin, CoReset, CoPause and CoResume set these two flags. The
functions isCoDone and isCoRunning report these flags. Table 3-1
summarizes the meanings of the STOPPED and INIT flags.
Table 3-1. Explanation of STOPPED and INIT Flags in CSState
Meaning
STOPPED
INIT
Yes
Yes
Yes
No
No
Yes
No
No
The function isCoDone returns true (1) if both the STOPPED and INIT
flags are set.
The function isCoRunning returns true (1) if the STOPPED flag is not set.
26 s Costatements
Dynamic C 32 v. 6.x
The CSState field applies only if the costatement has a name. The
CSState flag has no meaning for unnamed costatements.
Last Location
The two fields lastlocADDR and lastlocCBR represent the 24-bit
address of the location at which to resume execution of the costatement. If
lastlocADDR is zero (as it is when initialized), the costatement executes
from the beginning, subject to the CSState flag. If lastlocADDR is
nonzero, the costatement resumes at the 24-bit address represented by
lastlocADDR and lastlocCBR.
These fields are zeroed when (1) the CoData structure is initialized by a
call to _GLOBAL_INIT, CoBegin or CoReset, (2) the costatement is
executed to completion, or (3) the costatement is aborted.
Check Sum
The ChkSum field is a one-byte check sum of the address. (It is the
exclusive-or result of the bytes in lastlocADDR and lastlocCBR.) If
ChkSum is not consistent with the address, the program will generate a runtime error and reset. The check sum is maintained automatically. It is
initialized by _GLOBAL_INIT, CoBegin and CoReset.
First Time
The firsttime field is a flag that is used by waitfor statements. It is set
to 1 before the waitfor expression is evaluated the first time. This aids in
calculating elapsed time for the functions DelayMS, DelaySec, and
DelayTicks.
Content
The content field (a union) is used by the costatement delay routines to
store a delay count.
Check Sum 2
The ChkSum2 field is currently unused.
At a yield statement, the processor (1) stores the address of the following
statement in lastlocADDR and lastlocCBR as the resume address, and
(2) exits the costatement. Consequently, when the costatement is executed
again, it continues from the statement that follows the yield statement.
abort
Costatements s 27
waitfor
waitfor statement.
costate{
...
waitfor( MyDelay(1000) );
...
}
Note that the call to MyDelay has only one parameter. The CoData
pointer, required in the function definition, is not to be included in the call.
The compiler automatically passes the address of the CoData structure as
the first argument if a firsttime function is called from within a
costatement.
28 s Costatements
Dynamic C 32 v. 6.x
These delay functions depend on the virtual driver. Initialize the virtual
driver with a call to VdInit before they can be used.
yield
Application Frameworks
Costatements s 29
abort
The abort statement, in effect, causes the execution to jump to the very
end of the costatement, where it exits. The costatement will then terminate. If the costatement is always on, the next time the program reaches it,
it will restart from the top. If the costatement is not always on, it becomes
inactive and will not execute again until turned on by some other software.
(Unnamed costatements are always on.)
Other Functions
void CoBegin ( CoData *cd )
CoBegin initializes a CoData structure. The INIT flag is set, but the
STOPPED flag is clear.
both set.
Costatement Topics
Timing Issues
Costatements in most instances are grouped as periodically executed tasks.
A costatement can be part of a real-time task, which executes every n
milliseconds, as shown in Figure 3-2.
30 s Costatements
Dynamic C 32 v. 6.x
If all goes well, the first costatement will be executed at the periodic rate.
The second costatement will, however, be delayed by the first costatement.
The third will be delayed by the second, and so on. The frequency of the
routine and the time it takes to execute comprise its granularity.
If the routine executes every 25 milliseconds and the entire group of
costatements executes in 5 to 10 milliseconds, then the granularity is 30 to
35 milliseconds. Thus the delay between the occurrence of a waitfor
event and the statement following the waitfor can be as much as the
granularity, 30 to 35 milliseconds. The routine may also be interrupted by
higher priority tasks or interrupt routines, increasing the variation in delay.
The consequences of such variations in the time between steps depends on
the programs objective. Suppose that the typical delay between an event
and the controllers response to the event is 25 milliseconds, but under
unusual circumstances the delay may reach 50 milliseconds. An occasional slow response may have no consequences whatsoever. If a delay is
added between the steps of a process where the time scale is measured in
seconds, then the result may be a very slight reduction in throughput.
Consider the delay between sensing a defective product on a moving belt
and activating the reject solenoid that pushes the object into the reject bin.
If such a critical delay cannot exceed 40 milliseconds, then a system will
sometimes fail if its worst-case delay is 50milliseconds.
waitfor Accuracy Limitations
Costatements s 31
A particular application may not need very precise delay timing. Suppose
the application requires a 60-second delay with only 100 milliseconds of
delay accuracy; that is, an actual delay of 60.1 seconds is considered
acceptable. Then, if the processor guarantees to check the delay every
50milliseconds, the delay would be at most 60.05 seconds, and the
accuracy requirement is satisfied.
Setting the start field does not actually cause the costatement to execute. This simply means that the costatement is
active and is ready to execute. The calling programs
execution thread must pass through the costatement.
However, this code works when only one task can request the costatement
at a time. If several tasks request the execution of a costatement at the
same time, the costatement will certainly executeonce, maybe twice. In
general, each of the multiple requesters is not guaranteed a separate
execution of the costatement.
Request the execution of a costatement in the following cases.
The requester and requestee are in different tasks, where one
preempts the other, so direct calls are out of the question.
Multiple costatements must start simultaneously, something that
cannot be done with a direct call.
One task needs to start another, but no further synchronization is
needed between the tasks.
32 s Costatements
Dynamic C 32 v. 6.x
Nesting Costatements
If a costatement needs to run another costatement as a subtask, where the
original task cannot proceed until the subtask has completed, a direct call
using a waitfor is probably the best way to accomplish the desired end.
This is done by placing the subordinate costatement in a C function that
returns 0 on each pass of the execution thread except the last pass, when
completion occurs, at which time it returns 1.
// Upper level call within a costatement
costate...{
waitfor( function(args) );
}
// function outline
int function( args ){
...
costate...{
flag=0;
body of costatement
flag=1;
}
return flag;
In this case, the subroutine is called repeatedly each time the execution
thread passes through the waitfor. The subroutine returns zero each
time, until the execution of the costatement is completed, when it returns a
one, satisfying the waitfor in the upper-level costatement. This approach
has the additional advantage of providing local variables and arguments
that are passed. A disadvantage is that the arguments must be passed
repeatedly.
OR
if( bad condition ) CoReset(&xxx);
Application Frameworks
Costatements s 33
// terminate sendstring
// terminate cursorpos
// terminate printmenu
...
34 s Costatements
Dynamic C 32 v. 6.x
if( !x ){
// x not set and we cant wait
errorflag = 1; // any longer!
abort;
}
It is important that x not change between the test in the waitfor and the
test following the waitfor. There would be no risk of change if x reflects
a condition that is updated, for example, at the top of a costatement loop,
and remains stable through out the loop. If x is subject to change, then a
different scheme, such as the following, could be used.
costate xxx always_on {
...
waitfor((flag = DelayMs(200L)) || x);
if( flag ){
// x not set and we cant wait
errorflag = 1; // any longer!
abort;
}
}
Application Frameworks
Costatements s 35
Furthermore, the DelayMs routine does not start its time delay until it is
actually called. An expression such as
waitfor( test && DelayMs(50L) );
has the (perhaps unexpected) result of waiting until test is true and then
waiting 50 milliseconds more. Because of short-circuit evaluation rules,
DelayMs will not be evaluated if test is false.
If the order of the terms is reversed,
waitfor( DelayMs(50L) && test );
it waits for test, but not less than 50 milliseconds. It is possible to avoid
short-circuit evaluation problems by using the bitwise AND and OR
operators (| and &).
36 s Costatements
Dynamic C 32 v. 6.x
CHAPTER 4:
Global initialization
Application Frameworks
yes
32nd
pass?
no
defined?
Call user-defined
FASTCALL function if
user-specified number of
ticks have occurred.
exit
RTK or SRTK
defined?
no
exit
Dynamic C 32 v. 6.x
Calling Sequence
To enable or disable the various services of the virtual driver, include
#define parameters before calling the virtual driver initialization function
(VdInit). The examples below illustrate how to do this.
// # RTK tasks. For RTK only, no default
#define NTASKS nn
// max # of virtual watchdog timers, default 10
#define N_WATCHDOG nn
// load and run RTK or SRTK, default off
#define RUNKERNEL state
// 1 true, 0 off
// load fastcall, but dont run it
#define VD_FASTCALL state
// 1 load, 0 dont load
// initialize the virtual driver. default off
VdInit();
// Init fastcall to be called every nn (0-255) clock
// interrupts. Its off (nn=0) by default. Must be
// called after VdInit().
vd_initquickloop( nn );
that must have response times on the order of a few milliseconds, or that
need to be invoked as continuations of interrupt routines. The function
DelayTicks has a waitfor granularity of less than a millisecond.
Application Frameworks
Hitting the watchdog resets its count to the count value with which it
was created. To release the virtual watchdog wd use the function
VdReleaseWd( int wd );
Global Initialization
When the virtual driver is initialized with VdInit, the driver calls
_GLOBAL_INIT, which executes all the _GLOBAL_INIT function chain
segments in the program and libraries. This results in the initialization of
the entire program. The _GLOBAL_INIT segment must appear after the
variable declarations and before the executable statements.
The initialization statements placed in a _GLOBAL_INIT segment can be
complex C, assembly code with loops, branches, and function calls, or
they can be simple assignmentswhatever is required by the code. The
_GLOBAL_INIT segment can take action to precondition all or part of the
hardware, as well as to preset variable data.
Dynamic C treats a variable initialized with the syntax
type name = value;
e.g.,
int i = 0;
Dynamic C 32 v. 6.x
CHAPTER 5:
REAL-TIME KERNELS
Kernel functions
Application Frameworks
Real-Time Kernels s 41
The real-time kernel (RTK) and the simplified real-time kernel (SRTK) are
included with Dynamic Cs function libraries. The RTK and SRTK allow
a program to be divided into tasks by priority. These tasks can be treated
as separate programs running independently of one another. The execution
of the tasks is interleaved in time. There are two main advantages to this.
1 More urgent tasks (higher priority) are performed in preference to less
urgent tasks.
2 It is easier to write and organize a program when separate tasks or
sequences of events can be handled as if they were isolated from one
another.
The RTK allows many levels of priorities, but the SRTK has only the three
levels listed in Table 5-1.
Table 5-1. Simplified Real-Time Kernel Priorities
Name
srtk_hightask
srtk_lowtask
-none-
Frequency
Every 25 ms
Every 100 ms
Priority
High
Low
Background, lowest
The background task is code that executes when no other task is executing.
The virtual drivers FASTCALL service can be used with either kernel to
implement a very high priority task.
Each RTK or SRTK task can contain multiple execution threads by using
costatements.
#define RUNKERNEL 1
42 s Real-Time Kernels
Dynamic C 32 v. 6.x
main(){
HCOUNT = LCOUNT = 0;
VdInit();
// Need virtual driver
init_srtkernel();
// Initialize the SRTK
while(1){ ... } // stay alive while SRTK works
}
// This high priority task executes every 25 ms
srtk_hightask(){ HCOUNT++;
}
// This low priority task executes every 100 ms
srtk_lowtask(){
LCOUNT++;
costate{
// print every 1/2 second
waitfor(DelayMs(500));
printf(%d %d\n, HCOUNT, LCOUNT);
}
costate{
// When HCOUNT gets too big, reset
waitfor( HCOUNT >= 32000 );
HCOUNT = 0;
LCOUNT = 0;
}
}
In this example, costatements create two execution threads within the lowpriority task. The SRTK was designed with costatements in mind,
although some preemption is available. Background tasks can be placed in
(or called from) the while loop in main. Background tasks will be
preempted by any other task.
In above example, the background task would consume at least 90%
percent of the CPUeven if it does nothing but idlebecause the two
higher priority tasks do so little computation.
Real-Time Kernels s 43
The following example shows how a program might look with and without
the virtual driver.
#define NTASKS 4
#define RUNKERNEL 1
#use RTK.LIB
// the four task prototypes
int heater(), pump(), sensor(), backgnd();
// array of 4 task pointers
int (*Ftask[4])() = { heater,
//
pump,
//
sensor,
//
backgnd };//
task
task
task
task
0
1
2
3
backgnd();
The program can request that a task be invoked at a particular time (48-bit
time in ticks) or after a certain delay (32-bit count in ticks) or that the task
be invoked every nn ticks (nn being a 16-bit number). A task that is
running can also request that its own execution be suspended for up to m
ticks (16-bit number). Any task or interrupt routine can also request that
another task be run at the first opportunity.
The RTK multitasking capability may be used as a tool to separate control
loops into independent functions or modules. In this case, each task is
specified to run every nn ticks by calling the run_every function once as
part of the program initialization.
44 s Real-Time Kernels
Dynamic C 32 v. 6.x
For example, the following scheme could be used for a task to turn on a
valve each time the liquid level in a tank is low.
main(){
...
run_every(4,100);
...
}
task4(){
if( level() <= LOW ) openvalve();
if( level() >= HIGH ) closevalve();
return;
}
If ticks occur 50 times per second, then the state of the valve will be
sampled every two seconds. A very small amount of execution time will
be expended on this task.
If the nature of the task is such that there are several sequences of code
separated by dead time awaiting an external event or waiting for a fixed
time to elapse, then the suspend function could be invoked. In the above
example, suppose that, in order to open the valve, a motor must start, run
for approximately three seconds until a contact is closed, indicating that
the valve is fully open, and then the motor must be turned off. Assume
that the task of closing the valve is similar, and that ticks occur 50 times
per second. The following code could be used.
task4(){
if( level()<=LOW && valveclosed() ){
motor( OPEN );
while( valveclosed() ) suspend( 5 );
motor( OFF );
}else if( level()>=HIGH && !valveclosed() ){
motor( CLOSE );
while( !valveclosed() ) suspend( 5 );
suspend( 10 );
motor( OFF );
}
}
The first call to suspend stops the program from executing for the
number of ticks in the argument, five ticks, or 0.1 second. The first while
loop causes the program to suspend repeatedly for 0.1 second until the
valve is no longer closed. (The suspend time allows the time precision for
detecting the event to be specified.) The second while loop causes the
program to suspend repeatedly for 0.1 second until the valve closes.
The additional suspend(10) after the motor closes ensures that the motor
continues to run for ten ticks (0.2 seconds) to close the valve tightly.
Application Frameworks
Real-Time Kernels s 45
The above routine could also be made into an endless loop. In that case it
would be invoked one time by a call such as
request(task4);
Kernel Functions
The following routines control the activity of the RTK.
void run_at( int tasknum, void* time )
Requests the kernel to run the task specified by tasknum when the
time is greater than or equal to the time specified by the pointer time.
The time pointer points to a 48-bit number (stored least significant byte
first), which is the number of ticks since init_kernel was called.
int comp48( void* time1, void* time2 )
Compares two 48-bit time values. The function returns
1 for time1 < time2,
0 for time1 == time2, and
+1 for time1 > time2.
void gettimer( void* time )
Returns the current 48-bit time to the 6-byte area to which time points.
void run_after( int tasknum, long delay )
Requests the kernel to run the task specified by tasknum after delay
ticks have occurred.
void run_every( int tasknum, int period )
Requests the kernel to run the task specified by tasknum every
period ticks. The first request comes after period ticks. This is
exact and no ticks will be gained or lost in the period.
void request( unsigned int tasknum )
Requests the kernel to run the task specified by tasknum immediately.
If a request for the task is pending, this call has no further effect. The
specified task will be run on a future tick when priorities allow.
void run_cancel( int tasknum )
Cancels any pending requests for the task specified by tasknum..
void suspend( unsigned int ticks )
This routine must be called only from within a given task. It allows the
task to suspend itself for the specified number of ticks, after which it
will continue to be requested automatically. Execution resumes at the
statement following the call to suspend.
46 s Real-Time Kernels
Dynamic C 32 v. 6.x
This example checks for the event every 20 ticks until the event takes
place, at which point execution continues. The suspension can be up to
65,535 ticks.
Pointers to auto variables or arguments within the task or its subroutines can point to the wrong location after a suspend. Avoid this
problem by using auto variables or arguments only in routines that do
not suspend, directly, or indirectly through a subroutine. Be very
careful about pointers to auto variables, or use only static variables.
Application Frameworks
Real-Time Kernels s 47
RTK Internals
The following pseudocode shows the major RTK routines.
BEGIN run_timer
Step timer48
(48-bit timer)
BEGIN task loop
IF task has non-zero suspend count
Decrement count and set task request when
count becomes zero.
ENDIF
CASE operation mode
run_at:
Set task request flag.
run_after: Set task request flag.
run_every: Set task request flag.
ENDCASE
END task loop
call rkernel() to invoke next task
END run_timer
BEGIN rkernel
IF blocked, return, with block entry, to kernel
BEGIN task loop, high priority first
IF task is running, return from kernel
IF task is requested
Set task running and resume execution of task.
Return or suspend.
Clear request flag.
ENDIF
END task loop
Execution never gets here. Background task will
run instead.
END rkernel
48 s Real-Time Kernels
Dynamic C 32 v. 6.x
Application Frameworks
Real-Time Kernels s 49
50 s Real-Time Kernels
Dynamic C 32 v. 6.x
CHAPTER 6:
Software failures
Hardware failures
Protected variables
Application Frameworks
Even if a program is written and compiled correctly, the program may still
crash because of conditions that are beyond the control of the programmer
and the compiler. For example, blackouts, brownouts and power spikes
can put the controller in an unpredictable state. Therefore, crash detection
and recovery is an important issue for all embedded applications.
Z-World is aware of this issue, and has derived methods and support
routines to facilitate the development of robust embedded systems. As a
rule, the logic associated with the detection and handling of errors can be
expected to be a substantial portion of a programs overall code. Z-World
provides various ways to detect failures.
Software Failures
Certain software-related failures can be actively verified. For example, if
the program is compiled with the debugging options activated, the
compiler inserts code to do the following.
1. Check for stack integrity.
2. Check for pointer store validity.
3. Check for array bound overflowing.
If such exceptions occur, the debugging code generated by compiler calls
the routine exception, which in turn calls the function to which
ERROR_EXIT points. To handle such exceptions correctly, make sure that
ERROR_EXIT contains the address of a correct exception handler.
Hardware Failures
Hardware-related failures are difficult to verify with software because the
software runs on the failing hardware! The only verifiable hardware
failure is power failure. Special hardware on the controller detects low
voltage before the power goes out completely. This causes a nonmaskable
interrupt (NMI), and the processor executes the NMI handler. There is
usually not much time between the NMI and complete power failure.
Dynamic C 32 v. 6.x
This code only works if there is battery-backed RAM that stores CurSec.
It could be modified to use flash EPROM or EEPROM.
Application Frameworks
Dynamic C 32 v. 6.x
CHAPTER 7:
Application Frameworks
The five-key system uses the LCD and the keypad on Z-Worlds PK2100
and PK2200 series controllers. Figure 7-1 shows the standard assignment
of the keys on the keypad..
menu
item
setup
F1
F2
field
help
run
up
down
init
F3
F4
del
add
The LCD has two lines of 20 characters in the standard version. Other
versions are available. An underline cursor may be positioned under any
character.
The five-key system uses the costatement programming paradigm and runs
under the simplified real-time kernel. There also is an old five-key system
library (5KEY.LIB) that requires the real-time kernel. The 5KEY.LIB
library is described in Appendix B.
The five-key system provides a simple scheme for changing operating
parameters. It is possible to cycle through a number of menus by pressing
the MENU key. For each menu, a number of items may be selected by
pressing the ITEM key. Each item may have one or more fields, each of
which is selected by pressing the FIELD key.
When the desired parameter is selected, adjust the parameter by pressing
the UP or DOWN keys. These keys cycle forward or backward through a
list of acceptable values. It is not possible to select a wrong value.
In addition to the five keys, the HELP key provides help in context for
each specific menu item. The keys F1, F2, F3, F4, del, and add can each
be programmed for a specific task.
Operator Features
The five-key system allows an operator to do the following tasks.
Ask for helpusing the HELP keyon any five-key menu or parameter.
Dynamic C 32 v. 6.x
Programmer Features
A programmer may extend the five-key system in these ways.
Write code to use the F1, F2, F3, F4, add and del keys.
Dynamic C 32 v. 6.x
Result
(setup + run)
menu + up
Five-Key Functions
void fk_monitorkeypad()
Monitors the keypad for keys pressed. This function should be called
as an SRTK or RTK high-priority task. It sets global variable fk_tkey
to values from 1 to 12 depending on the key pressed. The value is 0 if
no key is pressed.
The function also monitors for the 2-key reset combination. If a reset
combination is detected, the function will not return but will force a
watchdog time-out. There is no buffer. Key presses should be processed within 100 milliseconds or they will be lost.
int fk_helpmsg( char **hptr )
Displays a series of help messages when the HELP key is pressed. The
current display is saved and each message string is displayed for
1.8seconds, then the previous display is restored. The input should be
an array of strings declared like this.
char *hptr[]={Str 1,Str 2",...,StrN,};
The last string must be null. The function returns nonzero if help is
off, and zero if help is on.
Application Frameworks
Dynamic C 32 v. 6.x
Application Frameworks
Dynamic C 32 v. 6.x
CHAPTER 8:
RS-232 COMMUNICATION
Serial communication
Application Frameworks
RS-232 Communication s 63
Serial Communication
Z-World supports RS-232 communication (with function libraries) for the
following ports.
Z180 Ports 0 and 1.
SIO Ports 0 and 1 on the BL1100.
SCC (Z80C30) Ports A and B on the BL1300.
The XP8700 expansion card.
The functional support for serial communications consists of the following.
Initialization of the serial ports.
Reading data from the receive circular buffer.
Writing data to the transmit circular buffer.
The RS-232 packages have the following features.
Circular send and receive buffers serviced with serial interrupts.
Echo option.
CTS/RTS control
XMODEM protocol for downloading and uploading data
Modem option
Echo Option
If the echo option is selected when a serial port is initialized, any character
received is automatically echoed (transmitted back). This feature is ideal for
systems with a dumb terminal and for checking transmitted characters.
With or without echo, the serial drivers automatically parse out the BACKSPACE character (ASCII 0x08). A separate function call after initialization of
the serial port can put the serial drivers in BINARY mode, that is, all data are
placed in the serial receive buffer.
64 s RS-232 Communication
Dynamic C 32 v. 6.x
CTS/RTS Control
If the CTS/RTS option is selected, the support software will pull the RTS
line high when the receive buffer has reached 80% of its capacity. Thus,
the transmitting device (if its CTS is enabled) will stop transmitting. The
software pulls the RTS line again when the received buffer has gone below
20% of its capacity.
If the device with which the controller is communicating does not support
CTS and RTS, the CTS and RTS lines on the controller side can be tied
together to make communication possible.
Modem Communication
Modems allows RS-232 communication across long distances using
telephone lines. If the modem option is selected, character streams that are
read from the receive buffer are automatically parsed for modem commands. If a modem command is found, appropriate actions are taken.
Normally the communication package would be in COMMAND mode
while waiting for valid modem command or messages. Once a link is
established, communication goes into DATA mode (that is, regular RS-232
communication). In DATA mode, the modem is still monitored for a
NO_CARRIER message.
The software assumes that modem commands (for which it scans) are
terminated with CR (carriage return, or ASCII 0x0D). Therefore, the
modem option is easiest to use when the protocol also has CR as the
terminating character. Otherwise, the software has to check for both
terminating characters. The message-terminating character cannot be any
of the ASCII characters used in the modem commands, nor can it be a linefeed character (0x0A).
The software supports communication with a Hayes Smart Modem or
other compatible modem. The CTS, RTS and DTR lines of the modem are
not used. If the modem used is not truly Hayes Smart Modem compatible,
tie the CTS, RTS and DTR lines on the modem side together. The CTS
and RTS lines on the controller side also have to be tied together.
Application Frameworks
RS-232 Communication s 65
A NULL connection is also required for the TX and RD lines since both
the controllers serial port and the modem are data communication
equipment (DCE). A commercial NULL modem would have its CTS and
RTS lines tied together on both sides.
Figure 8-1 shows the correct modem to controller serial connections. The
ISA COM ports 1 and 2 can be connected directly to a modem since they
are already data terminal equipment (DTE).
Modem
Side
RX
TX
GND
RTS
CTS
DTR
Controller
Side
RX
TX
GND
RTS
CTS
The function names for these ports incorporate the following keys.
Port
Z180 Port 0
Z180 Port 1
SCC Port A
SCC Port B
XP8700
Key
z0
z1
sca
scb
uart
Port
Key
SIO Port 0
s0
SIO Port 1
s1
ISA COM 1 com1
ISA COM 2 com2
For example, the initialization routine for Z180 Port 0 is called Dinit_z0
and is described here. The same function for SIO Port 0 is named
Dinit_s0. The equivalent function for the XP8700 expansion card is
Dinit_uart. The equivalent function call for SCC Port B is Dinit_scb.
The equivalent function call for ISA Port 2 is Dinit_com2. Each function
described (for z0) in this section has eight other functions that use the
other keys in their names.
66 s RS-232 Communication
Dynamic C 32 v. 6.x
Interrupt Handling
Normally the serial interrupt service routine is declared with this compiler
directive.
#INT_VEC SER0_VEC routine_name
However, if the same serial port is used for Dynamic C programming and
for communication, the program has to be downloaded first through
DynamicC before the address of the serial interrupt service routine is
loaded into the interrupt vector table. Put simply, the service routine must
be loaded at run time. The function
void reload_vec( int vector, int(*function)() );
will load the address of the service routine function into the specified
location in the interrupt vector table. Do not use the #INT_VEC directive
in this case. It is not possible to do any further debugging through
Dynamic C once the service routine has taken over.
For communication with a serial device other than the Dynamic C programming port on the PC, the program has to make sure that the hardware
is properly configured before sending any serial messages. For example,
when using the Z180s Port 0 for serial communication with a modem, the
keypad (PK2100 or PK2200 only) may be used to trigger the initialization
of the serial port. Without such a trigger, the modem might not communicate with the support software properly because the initialization routine
also send commands to the modem to initialize it.
When executable programs are generated for the EPROM or for download
to RAM, there will be no need for communication with Dynamic C. The
compile-time directive (#INT_VEC) can then be used freely.
RS-232 Software
int Dinit_z0( void*
int
byte
byte
rbuf,
rsize,
mode,
modem,
void*
int
byte
byte
tbuf,
tsize,
baud,
echo )
RS-232 Communication s 67
Reads a character from the receive buffer into character ch. The
function returns
0 buffer is empty.
1 byte has been successfully extracted from buffer.
int Dwrite_z01ch( char ch )
Places a character in the transmit buffer. If not already transmitting, the
function initiates transmission. It returns
0 transmit buffer did not have space for ch.
1 write was successful.
int Dread_z0( char* buffer, char terminate )
Checks the receive buffer for a message terminated with the character
68 s RS-232 Communication
Dynamic C 32 v. 6.x
ismodem = 0;
isecho = 1;
tbuf[384];
rbuf[200];
//
//
//
//
//
//
//
//
//
carriage return
9600 baud, divided by 1200
1 stop bit
no parity
8 data bits
no modem is connected
data received are echoed
circ. transmit buffer
circ. receive buffer
main(){
char buf[20];
// messages
Dinit_z0(rbuf,tbuf,200,384,mode,baud,ismodem,isecho);
Dz0send_prompt(); // send a prompt
while(1){
// wait for a message terminated with CR
while( Dread_z0(buf,CR)==0 );
// here you could do whatever you want with the message
// in this example, the message is sent back
Dz0send_prompt();
Dwrite_z0(buf,strlen(buf)); // send message back
// then, some more ...
Dz0send_prompt();
Dwrite_z0(it works!,9);
// write another
Dz0send_prompt();
}
}
Application Frameworks
RS-232 Communication s 69
Dynamic C 32 v. 6.x
address
pages
dest
\nOK
\nCONNECT
\nRING
\nNO CARRIER
\nERROR
\nCONNECT 1200
\nNO DIALTONE
\nBUSY
\nNO ANSWER
\nCONNECT 2400
\n
//
//
//
//
//
//
//
//
//
//
//
okay respond
connect at 300 baud
ring detected
no carrier
command error
connect at 1200 baud
no dial tone
line busy
no answer
connect at 2400 baud
just a line feed
Application Frameworks
RS-232 Communication s 71
void Drestart_z0modem()
Restarts the modem (during start of program or abnormal operation).
void Dz0modem_chk( char* buffer )
Checks the buffer for valid modem commands. The function takes
the appropriate response to the modem command if it finds a valid
modem command.
The function returns
0 Valid modem command.
1 Invalid modem command.
void Dz0_circ_int()
This is an interrupt service routine for Z180 Port 0.
void Ddelay_1sec()
Creates a 1-second delay (approximately). If RUNKERNEL is defined,
suspend(50) is used to generate the delay.
void Ddelay_100ms()
Creates a 100-millisecond delay (approximately).
void reload_vec( int vector, int(*function)() )
Load the address of an interrupt service routine (ISR) into the vector
table. This function is useful during program development when either
of the Z180 Port 0 (Z0) or the PLCBus XP8700 UART #3 is used as
the Dynamic C programming port. It is also useful as a safeguard
against the BIOS rewriting the Z0 or /INT1 (PLCBus UARTs) vector
when the controller is powered up or reset into programming mode, as
occurs when using the Program Loader Utility (PLU) to update the
controllers application either via port Z0 or PLCBus UART #3.
If the application uses the Z0 or PLCBus UART serial ports it should
call reload_vec once each for the used Z0 or PLCBus ISRs early in
its normal initialization to ensure that the respective vectors point to its
ISRs. For other serial ports use the compile-time interrupt directive
#INT_VEC to load the ISR address into the interrupt vector table when
generating the executable code for EPROM or for download to RAM.
vector is the offset for the specific interrupt.
function is a pointer to the interrupt service routine.
72 s RS-232 Communication
Dynamic C 32 v. 6.x
Libraries
Table 8-1 lists the Dynamic C libraries that support serial communication.
Table 8-1. Dynamic C Libraries Supporting Serial Communication
Z0232.LIB
Z180 Port 0
Z1232.LIB
Z180 Port 1
S0232.LIB
SIO Port 0
S1232.LIB
SIO Port 1
SCC232.LIB
XP87XX.LIB
COM232.LIB
MODEM232.LIB
Application Frameworks
RS-232 Communication s 73
Sample Programs
Table 8-2 lists sample programs that illustrate serial communication.
Table 8-2. Dynamic C Serial Communication Sample Programs
RS232.C
XP87XX.C
Z1232.C
SCC232.C
DOWNLOAD.C
The programs in Table 8-3 use the serial port as a diagnostic port. Except
for Z1REM.C and SCCREM.C, these programs are also the master programs
that can talk to a slave running SREMOTE.C or CSREMOTE.C via the
RS-485 half-duplex linkage.
Table 8-3. Dynamic C Sample Programs
Z0REM.C
Z1REM.C
S0REM.C
SCCREM.C
UARTREM.C
CZ0REM.C
CUARTREM.C
COM232.C
COM1REM.C
COM2REM.C
74 s RS-232 Communication
Dynamic C 32 v. 6.x
CHAPTER 9:
MASTER-SLAVE NETWORKING
Z-World supports master-slave networks using 2-wire and 4-wire RS-485
networks. The master and slave controllers communicate using a protocol
based on the ninth bit. Chapter 9 discusses these topics.
Communication protocol
Hardware connections
Software support
Application Frameworks
Master-Slave Networking s 75
Z-world has library functions for master-slave two-wire half-duplex RS485 9-bit binary communication. This protocol is supported only on Z180
Port 1, which is configured for RS-485 communication on most Z-World
controllers. Boards that provide access to Z180 Port 1 can be the master or
the slave. There should only be one master, which will then have a board
address of 0. The slaves must have their own distinct identification
numbers from 1255.
The functional support for the master-slave serial communication consists
of the following steps.
1. Initialization of Z180 Port 1 for RS-485 communication.
2. Master sends inquiry and waits for response from a slave.
3. Slaves monitor for their address during the ninth bit of a transmission.
The targeted slave replies to the master.
Communication Protocol
The binary command message protocol adopted is similar to that used for
the Opto-22 binary protocol. A master message is composed as shown
here.
[slave id] [len] [ ] [ ]...[ ] [CRC hi][CRC lo]
Hardware Connection
Figure 9-1 shows the connections for a two-wire RS-485 network. Any
Z-Worlds controller can be a master or a slave. There should only be one
master, but there can be up to 255 slaves.
485 Rx+
485 Tx+
485 Rx
485 Tx
PK2100,
BL1100,
and others
485+
485
BL1200
BL1600,
PK2200,
BL1400,
and others
Dynamic C 32 v. 6.x
Software Support
void op_init_z1( char baud, char* rbuf,
byte address )
Initializes Z180 Port 1 for RS-485 ninth-bit protocol binary communication. The data format defaults to 8 bits, no parity, 1 stop bit.
baud
rbuf
address the network address of the board: 0 for the master board,
int check_opto_command()
Checks for a valid and completed command or reply in the receive
buffer. The function returns with
0 if there is no completed command or message available.
1 if there is a completed command or reply available.
2 if the completed command or reply has a bad CRC check.
int sendOp22( byte dest, char* message,
byte len, int
delays )
The master sends a message to the slave and waits for a reply. The
function puts the message in the following format.
[slave id] [len] [ ] [ ]...[ ] [CRC hi][CRC lo]
Master-Slave Networking s 77
reply
count
Miscellaneous Functions
void misticware( char* tbuf, char count )
This is the gateway for RS-485 ninth-bit protocol for binary communication. The receive and the transmit buffers must already be set up.
Interrupt-driven transmission must be intitialized.
tbuf
count
void optodelay()
This function produces a delay of ~50 milliseconds. The delay is
implemented with a suspend(2) if the RTK is being used. Otherwise, it is a software countdown delay.
int rbuf_there()
Monitors the receive buffer for a completed command or reply. The
function returns
1 if a completed command or reply is available.
0 if a completed command or reply is not available.
void op_send_z1( char* tbuf, byte count )
This function is called by misticware to initiate transmission of data.
void op_rec_z1()
This function is called by misticware to reset and to ready the
receiver for data reception.
void op_kill_z1()
Disables Z180 Port 1. The RS-485 driver is also disabled.
78 s Master-Slave Networking
Dynamic C 32 v. 6.x
void z1_op_int()
This is an interrupt service routine for the Z180 Port 1 used in masterslave networking.
Sample Program
// MASTER.C (running in slave controller)
// The master sends a string of messages to the slave.
// Slave replies. The master prints the reply at STDIO.
char rbuf[255];
// receive buffer
char reply[40];
// reply buffer
char msg[40];
// message buffer
main(){
int i,j,ercode;
VdInit();
// initialize 19200 baud, receive and master
op_init_z1(16,rbuf,0);
j = 1;
while(1){
// wait 10000 counts before polling
for(i = 0; i< 10000; i++) runwatch();
sprintf(msg,Message # %d, j++);
// send message to slave 1 and wait for reply
ercode = TalkToSlave(1,msg,strlen(msg),3,reply);
if( ercode == 1){
// if reply is valid
printf(%s\n, reply);
}else{
// if bad reply or link failure
printf(Link Failure or Bad Link\n);
}
}
Application Frameworks
Master-Slave Networking s 79
Note that sendOp22 just sets up the message for transfer using the ninthbit protocol. It does not poll for the completion of the transfer. All
transfers of messages are done in the background interrupt routine.
80 s Master-Slave Networking
Dynamic C 32 v. 6.x
MODEM232.LIB
Sample Programs
Table 9-2 lists the sample programs that illustrate master-slave communication.
Table 9-2. Dynamic C Sample Programs for
Master-Slave Communication
RS485.C
SREMOTE.C
CSREMOTE.C
Application Frameworks
Master-Slave Networking s 81
82 s Master-Slave Networking
Dynamic C 32 v. 6.x
APPENDIX A:
Application Frameworks
EXECUTION SPEED
Execution Speed s 83
9.216
2.7
1.8
24
16
12
142.5
95
72
47.5
21
14
10.5
123
82
60.5
41
609
406
304.5
203
117
78
19.5
39
Floating-point multiply
171
114
85.5
57
Floating-point divide
12.288
18.432
1.4
0.9
429
286
214.5
143
Sine or cosine
4650
3100
2325
1550
Square root
1275
850
637.5
425
Table A-2 lists the execution times of various logical and counting
operations for a 9.216-MHz clock.
Table A-2. Execution Times of Logical Operations
Operation
Execution Time
2.6 s
if(k)
for(k=0;k<100;k++){}
12.8 s
22 s
7 s
switch(n){...}
costate{}
costatement entry + exit overhead
costate{waitfor(0)}
costatement waiting
84 s Execution Speed
5.8 s
32 s
19 s
Dynamic C 32 v. 6.x
Table A-3 lists the execution times of other operations. These times are
approximate times, assuming a typical environment. Hand coding in
assembly language or other special care can result in substantially increased performance.
Table A-3. Execution Times of Other Operations
Operation
Execution Time
100 s
Application Frameworks
Execution Speed s 85
86 s Execution Speed
Dynamic C 32 v. 6.x
APPENDIX B:
Application Frameworks
Code-Driven Approach
In the code-driven approach, the programmer creates menus for updating
parameters. A real-time-kernel task calls all the menus repeatedly. Each
menu handles its own list of items.
The following examples shows a conceptual code-driven menu system.
main(){
initialization
background();
}
indirect background(){
request(TASK1);
while(1);
}
indirect task1(){
// the code-driven menu
server
while(1){
menu1();
optional menu 1 housekeeping
menu2();
...
menuN();
}
}
// continued
Dynamic C 32 v. 6.x
int menu1(){
int k;
while(1){
k = _5key_parameter1();
optional housekeeping for parameter 1
if( k == MENU ) return; // menu key pressed?
k = _5key_parameter2();
optional housekeeping for parameter 2
if( k == MENU ) return; // menu key pressed?
k = _5key_parameter3()
optional housekeeping for parameter 3
if( k == MENU ) return; // menu key pressed?
}
}
int menu2(){
code here
}
int menuN(){
code here
}
Linked-List Approach
The following code shows the linked-list approach. The library function
_5key_menu is called from a real-time-kernel task. This function uses the
linked lists that were created during initialization with calls to
_5key_setmenu. The linked-list method handles parameters easily, but
there is no way to do housekeeping for specific parameters or menus.
main( ){
// initialization routines...
_5key_setmenu( menu1, parameter1 );
_5key_setmenu( menu1, parameter2 );
_5key_setmenu( menu1, parameter3 );
_5key_setmenu( menu2, parameter4 );
_5key_setmenu( menu2, parameter5 );
_5key_setmenu( menu2, parameter6 );
_5key_setmenu( menu3, parameter7 );
_5key_setmenu( menu3, parameter8 );
_5key_setmenu( menu3, parameter9 );
background();
}
indirect background(){
request(TASK1);
while(1);
}
indirect task1(){
_5key_menu(); // endless 5key service
}
Application Frameworks
1
0
1
0
0x10
0x00
(char**)0
(int(*)())0
Tb is the temperature,
of boiler 3. Use UP, ,
DOWN and FIELD keys,
to modify};
Code-Driven Approach
The function call to change the variable Tb would be
_5key_float( Tb, &Tb, 300.00, 100.00,
Tb_help, sizeof(Tb_help),
MODIFY, 10 );
The following declarations are needed for a string time that displays and
allows changes to the real-time clock.
char time[9];
char *time_help[] = { time display and set,
the real-time clock };
Dynamic C 32 v. 6.x
Linked-List Approach
The two variables previously mentioned, Tb and time, would be added to
the linked list with the following calls.
_5key_setmenu( Menu1, Tb , _5key_Fdata, &Tb,
300.00, 100.00,
Tb_help, sizeof(Tb_help),
RTCLK|MODIFY, 10, NO_DISPLAY );
_5key_setmenu( Menu1, time, _5key_Tdata, time,
0.0, 0.0,
time_help, sizeof(time_help),
RTCLK|MODIFY, 10, NO_DISPLAY );
Periodic Display
When there is no keypad and no display activity for 1000 ticks
(25 seconds), the five-key system will display the time, date, up to 10
messages and up to 10 linked-list parameters. The time and date are
always enabled. String messages can be set up with the following call.
_5key_setmsg( message_no, the message );
Application Frameworks
Linked-list parameters can also be displayed. They are set through the
_5key_setmenu calls. The previously mentioned boiler temperature, Tb,
can be displayed periodically with this call.
_5key_setmenu( Menu1, Tb , _5key_Fdata, &Tb,
300.00, 100.00,
Tb_help, sizeof(Tb_help),
MODIFY, 10, DISPLAY );
Software Alarms
Four variables, _ALARM1, _ALARM2, _ALARM3, and _ALARM4, are monitored by the five-key system. When any of these software alarms becomes
nonzero, the five-key system resets it to zero, and calls a specified function. It handles the functions keys the same way, and except for alarms,
the triggers are generated in software. The alarm service is particularly
useful when an alarm condition has to transfer control of the display and
keypad to a predefined function. Alarm handlers might be loaded as
follows.
_5key_setalarm( alarm1,alarm2,alarm3,NO_FUNCTION );
to an application.
Some of the functions (for example, _5key_float) return an integer
representing one of the keys MENU, ITEM, UP, DOWN, ADD or DELETE. These integers are also defined as symbolic constants in
5KEY.LIB. These functions return such a value to indicate that the
particular key has been pressed. They return 1 when no key has been
pressed or the value is being monitored.
When data are monitored, they are presumed to be changed somewhere
else in the program. The PK2100 display reflects the change when
monitored data changes.
92 s Old 5-Key System
Dynamic C 32 v. 6.x
Miscellaneous Functions
lcd_server
_5keysettime
_5keysetdate
_5keygettime
_5keygetdate
_5key_init_menu
Application Frameworks
Dynamic C 32 v. 6.x
INDEX
Symbols
A
abort ............ 24, 25, 27, 30, 33, 35
ADD key ............................. 56, 57
alarm functions ......................... 88
always_on ..................... 25, 27, 35
assembly language .................... 15
B
background task
SRTK .................................... 42
battery-backed RAM .......... 53, 54
baud rate ....................... 12, 67, 77
BINARY mode ......................... 65
BIOS ......................................... 53
buffer
receive ................. 68, 69, 77, 78
initialization ...................... 67
reading .............................. 68
transmit ........................... 69, 78
initialization ...................... 67
writing ......................... 68, 69
Application Frameworks
Index s 95
D
DATA mode .............................. 65
Ddelay_100ms .......................... 72
deciphering modem commands 71
DEL key .................................... 57
delay
modem communications ....... 72
delay functions .......................... 29
delay_1sec ................................ 72
DelayMs ........... 27, 28, 36, 38, 43
DelaySec ....................... 27, 38, 43
DelayTicks .............. 27, 38, 39, 43
DELETE key ............................ 56
DEMO_RT.C ............................ 49
Dget_modem_command ........... 71
96 s Index
Dinit_com2 ...............................
Dinit_sca ...................................
Dinit_scb ...................................
Dinit_uart ..................................
Dinit_z0 ....................................
disabling interrupts ...................
DMA channels ......................
Z180 Serial Channels 0 and 1
disabling the RS-485 driver ......
Dkill_z0 ....................................
DMA channels
disabling interrupts ...............
DOWN key ...............................
downloading
data .......................................
programs ...............................
Dread_sca .................................
Dread_z0 ...................................
Dread_z01ch .............................
Dreset_z0rbuf ...........................
Dreset_z0tbuf ............................
Drestart_z0modem ....................
Dscasend_prompt .....................
Dwrite_sca ................................
Dwrite_z0 .................................
Dwrite_z01ch ...........................
Dxmodem_z0down ...................
Dxmodem_z0up .......................
Dynamic C
Function Reference ...............
programming port .................
Dz0_circ_int .............................
Dz0modem_chk ........................
Dz0send_prompt .......................
66
70
66
66
66
73
73
73
78
69
73
56
70
72
70
68
68
69
69
72
70
70
69
68
70
70
89
72
72
72
69
E
echo option ............................... 67
EEPROM ............................ 53, 72
error exits .................................. 33
use of setjmp and longjmp .... 34
ERROR_EXIT .......................... 52
exception ................................... 52
Dynamic C 32 v. 6.x
execution speed
other operations .................... 85
expression evaluation
and costatements ................... 35
F
F1, F2, F3, F4 ..................... 56, 57
failure detection and recovery .. 54
hardware failures .................. 52
hardware watchdog ............... 52
power failure ......................... 52
protected variables ................ 54
reset ....................................... 53
software failures ................... 52
super reset ............................. 53
fastcall ..................... 17, 38, 39, 42
FIELD key ................................ 56
firsttime ............................... 27, 28
flag ........................................ 28
functions ............................... 28
calling ............................... 28
definition of ...................... 28
Five-Key system ..... 55, 56, 63, 75
DOWN key ........................... 56
extending .............................. 57
FIELD key ............................ 56
HELP key ....................... 56, 57
ITEM key .............................. 56
linked-list driven ................... 91
MENU key ............................ 56
operation ............................... 56
UP key .................................. 56
FK.LIB ...................................... 88
fk_helpmsg ............................... 59
fk_item_alpha ........................... 60
fk_item_enum ........................... 61
fk_item_int ............................... 60
fk_item_setdate ......................... 60
fk_item_settime ........................ 60
fk_item_uint ............................. 60
fk_monitorkeypad ............... 57, 59
FKSAMP.C ............................... 59
flash EPROM ............................ 53
Application Frameworks
G
getcrc ........................................
gettimer .....................................
global initialization ...................
initializing CoData ................
granularity .................................
costatement ...........................
73
46
40
24
39
31
H
hardware watchdog ................... 52
Hayes Smart Modem .... 65, 70, 71
HELP key ..................... 56, 57, 91
I
identifying shared variables ...... 18
init_kernel ................................. 46
init_on ....................................... 25
init_srtkernel ............................. 42
initialization
receive buffer ........................ 67
transmit buffer ...................... 67
Z180 Port 1 ........................... 77
initiation
serial transmission .... 68, 69, 78
input
RS-232 .................................. 68
INT1 ................................... 72, 73
INT2 ......................................... 73
interrupt-driven transmission .... 78
interrupts ............................. 14, 18
#INT_VEC ........................... 67
disabling ............................... 73
latency ................................... 15
causes ................................ 14
nested .................................... 15
routines ................................. 15
SER0_VEC ........................... 67
serial ...................................... 67
service functions ................... 72
service routines ............... 72, 79
vector table ........................... 72
ISA
COM ports ............................ 66
Index s 97
isCoDone ..................................
isCoRunning .............................
ITEM key ..................................
IX register .................................
30
30
56
47
K
kernel
real-time . 17, 39, 42, 43, 48, 70,
72, 78, 88
keyboard
see Five-Key system 55, 56, 63,
75
lastlocADDR ............................ 27
lastlocCBR ................................ 27
latency ....................................... 14
LCD
see Five-Key system 55, 56, 63,
75
longjmp ..................................... 34
98 s Index
Dynamic C 32 v. 6.x
optodelay .................................. 78
output
RS-232 ............................ 68, 69
RS-485 ............................ 76, 77
P
parity ......................................... 67
phy_adr ..................................... 71
PLCBus ..................................... 72
PLU
Program Loader Utility ......... 72
preemption .................... 16, 17, 18
with fastcall ........................... 39
preemptive multitasking 16, 17, 18
printf ......................................... 49
problems with C expression
evaluation .......................... 35
Program Loader Utility
PLU ....................................... 72
programmable reload timer (PRT)
43, 73
programming ............................ 56
protected variables .............. 14, 15
crash recovery ....................... 54
protocol
command
master-slave ...................... 76
R
RAM
battery-backed ................ 53, 54
rbuf_there .................................. 78
read-only memory ..................... 72
real-time kernel (RTK) 17, 38, 39,
42, 43, 48, 70, 72, 78, 88
and the old Five-Key system 88
and virtual driver .................. 43
array of RTK task pointers .... 43
sample programs ................... 49
real-time programming ............. 13
Application Frameworks
Index s 99
sample programs
communication ..................... 69
Five-Key system ................... 59
master-slaves ............. 79, 80, 81
real-time kernel (RTK) ......... 49
SCC ............................... 64, 66, 70
sendOp22 .................................. 77
SER0_VEC ............................... 67
serial communication ... 64, 67, 76,
77, 78, 81
master-slave .................... 77, 78
serial transmission
initiating .......................... 68, 69
terminating ............................ 69
setjmp ....................................... 34
shared variables ............ 14, 15, 18
identifying ............................. 18
multitasking .................... 17, 18
simplified real-time kernel (SRTK)
17, 39, 42, 43, 57, 88
sample program .................... 42
SIO ...................................... 64, 66
slave response format ......... 76, 78
Smart Modem
Hayes .............................. 65, 70
software support
RS-232 .................................. 67
SRTK (simplified real-time kernel)
17
SRTK.LIB ................................. 42
srtk_hightask ............................. 42
srtk_lowtask .............................. 42
stack corruption checking ... 47, 48
state machine ............................ 23
example ................................. 22
stop bits ..................................... 67
string messages
in the Five-Key system ......... 91
super reset ................................. 53
suspend 17, 45, 46, 47, 48, 49, 70,
72, 78
syntax
costatement ........................... 25
100 s Index
U
UART .......................................
UP key ......................................
uplc_init
initialize CoData structures ...
uploading data ...........................
useix ..........................................
72
56
24
70
47
V
VD_FASTCALL ...................... 39
vd_initquickloop ....................... 39
vd_quick_loop .......................... 39
VdGetFreeWd ........................... 40
VdInit ............................ 38, 39, 40
and waitfor delay functions .. 29
initialize CoData structures ... 24
VdReleaseWd ........................... 40
VDRIVER.LIB ......................... 38
VdWdogHit .............................. 40
virtual driver ................. 37, 43, 53
and real-time kernel .............. 39
fastcall ................................... 39
global initialization ............... 40
virtual watchdog ........... 38, 40, 53
Dynamic C 32 v. 6.x
Z0 .............................................. 72
z0binaryreset ............................. 68
z0binaryset ................................ 68
z1_op_int .................................. 79
Z180 .................................... 64, 66
Port 0 .................. 67, 68, 69, 72
Port 1 .............................. 78, 79
initialization ...................... 77
Serial Channels 0 and 1
disabling interrupts ........... 73
xdata ......................................... 71
XMODEM
commands ............................. 70
protocol ..................... 64, 65, 70
XP8700 ............................... 66, 72
Application Frameworks
Index s 101
102 s Index
Dynamic C 32 v. 6.x
Z-World, Inc.
(530) 757-3737
(530) 753-5141
http://www.z w orld.c om
[email protected]
Printed in U.S.A.