📄 chapter7.htm
字号:
<head>
<title>The Data Manual</title>
</head>
<body>
<h1>Chapter 7 The Data Manual</h1>
<p> We have seen the development of several important components all associated
with the M768HC16Y1 microcontroller. Some important items to remember. All
essential knowledge of a component is contained in the class definition or header file.
There is no need to see the class implementation file to use or understand the operation
of the component. In fact, the component, or class programmers, should feel free to alter
or improve the content of the class implementation files as they are moved from project
to project. There is a contract, however, between the class programmer and the
applications programmer: The operation of any component when viewed from an
external program will never change as the component is upgraded. As such, a Delay will
always be a Delay, it will always have the same class constructor prototype, and its
operation in the program will always be the same. Otherwise, the class programmer can
change the implementation code at will.
<p> The functions of the several components developed here have been gathered into
a series of data sheets. You will find that each component is completely described in its
data sheet along with the constructor arguments and a simple coding example that show
use of the component in a program.
<h2><a name="delay">Data Sheet DELAY</a></h2>
<h3>Device Name and description</h3>
<h3>Delay</h3> <p>-- Delay causes a delay by a specified number of output compare interrupts. A
semaphore is created by the calling program and this semaphore is attached to the delay
component. This semaphore is released when the delay has expired. This component is
used to delay execution of a program by an accurate time.
<h3>Super Classes</h3>
<p>Delay inherits the features of the error handler. The error handler inherits the features
of the class object.
<h3>Attributes</h3>
<pre><code>
None
</code></pre>
<h3>Methods</h3>
<pre><code>
void error_hand(void *, int, int) /* from Error_handler */
arguments /* see Error_handler */
void exercise( Object * ) /* from Object */
arguments /* See Object */
</pre></code>
<strong>Constructor</strong>
<pre><code>
struct delay *delay_(struct time*, /* Timer causing outputcompare interrupts */
Semaphore*, /* Semaphore to control program continution */
WORD); /* number of output compare interrupts to delay */
</pre></code>
<strong>Destructor</strong>
<pre><code>
void delay__(Delay *);
</code></pre>
<strong> Macro Methods</strong>
<pre><code>
None
</code></pre>
<h3>Header File</h3>
<pre><code>
#include "error.h"
#include "timer.h"
#include "semaphor.h"
#include "defines.h"
#define DELAY_CLASS \
ERROR_HANDLER \
unsigned int delay_time; \
struct time *Time;\
Semaphore *semaphore;
typedef struct delay
{
DELAY_CLASS
}Delay;
struct delay *delay_(struct time*, Semaphore*,unsigned int);
void delay__(struct delay *);
#endif
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p>
The delay destructor is executed automatically at the end of the delay and prior to the
release of the semaphore. This component alters the hook_method and the hook_object
attributes of the timer that is passed into the delay constructor, and these parameters are
both restored to a NULL value at the completion of the delay. The timer used here
should be dedicated completely to the delay operation.
<h3>Coding Examples</h3>
<pre><code>
/* delay the execution of a program by 2000 ms */
.
.
.
#include <timer.h>
#include <delay.h>
#include <semaphor.h>
.
.
.
main()
{
Semaphore *S1=semaphore_();
Timer *T1; /* 1 ms interrupt */
Timer_parameters tp;
Semaphore *S1=semaphore_();
.
.
.
/* set up the timer parameter structure and instantiate a timer */
tp.number=OC3; /* use output compare number 3 */
tp.tick=MS_PERIOD; /* 1 ms interrupts */
tp.action=0; /* no output action */
tp.OC1_connect=0; /* OC1 not connected to another OC */
tp.connect_data=0; /* therefore no connect data needed */
tp.interrupt=YES; /* need an interrupt here */
T1=timer_(&tp); /* instantiate the timer */
.
.
.
delay_(T1,S1,2000); /* 2000 ms delay */
wait_for_semaphore(S1);
timer__(T1); /* delete the timer */
semaphore__(S1); /* delete the semaphore */
.
.
.
</code></pre>
<h2><a name="error_handler">Data Sheet ERROR HANDLER</a></h2>
<h3>Device Name and description</h3>
<h3>Error Handler</h3>
<p>-- The error handler provides a uniform mechanism for handling errors
within components. This class is usually a super class for classes need error handling
capability. It is often used to detect errors that can occur when an object is being
instantiated.
<h3>Super Classes</h3>
<p>The error handler inherits the features of the class object.
<h3>Attributes</h3>
<pre><code>
None
</code></pre>
<h3>Methods</h3>
<pre><code>
void error_hand(void *, int, int) /* from Error_handler */
arguuments /* see Error_handler */
void exercise( Object * ) /* from Object */
arguments /* See Object */
</code></pre>
<strong> Constructor</strong>
<pre><code>
Error_handler *error_(void);
</code></pre>
<strong>Destructor</strong>
<pre><code>
void error__(Error_handler *);
</code></pre>
<strong> Macro Methods</strong>
<pre><code>
None
</code></pre>
<h3>Header File</h3>
<pre><code>
#ifndef ERROR_H
#define ERROR_H
#include "defines.h"
#include "object.h"
enum {TYPE_1,TYPE_2};
#define ERROR_HANDLER \
OBJECT \
void (*error_hand)(void*,int,Error_source);
typedef struct err
{
ERROR_HANDLER
} Error_handler;
#define error_handler(a,b,c) (*a->error_hand)(a,b,c)
Error_handler *error_(void);
void error__(Error_handler *);
#endif
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p>
The following enumeration is used to determine the error sources for the error handler.
<pre><code>
typedef enum BYTE
{
SEMAPHORE,
SERIAL,
TIMER,
DELAY,
PWM,
PWMI
}Error_source;
</code></pre>
<p>This enum is contained in the header file defines.h. It is placed there because these
values are subject to change, and it is better to place changable values outside of the class
definition file.
<p> The enum seen in the error header file
<pre><code>
enum {TYPE_1, TYPE_2};
</code></pre>
<p>
Identifies the type of error to the error handler. A type 1 error is a non recoverable error
that implies that the program is unable to continue operation and a type 2 error occurs
when there is an easily recoverable error that usually needs no additional code to repair
the situation. There is yet another error that can occur when the program encounters an
erronous parameter. With the third type of error, the return to the calling program will be
a value of 0. A test for a NULL pointer return will show this type of error. The type 1
error is an erro that cannot be easily corrected. An example of a type 1 error is that a
malloc() call returns a NULL value. In such a case, the system cannot be repaired by
local code and a special initialization will be executed. An error of type 2 is an error, but
it will be an error that can be fixed by the calling program. In this case, the error
occurrence is logged and the program is continued with the expectation that the error
will be corrected. An example of a type 2 error will occur when a serial port detects a
parity error or perhaps a framing error.
<h3>Coding Examples</h3>
<p>The coding example is taken from the constructor for the serial i/o class.
<pre><code>
Serial_io *serial_io_(...)
{
Error_handler *temp; /* the object from which inheritance
takes place */
Serial_io *this; /* this object */
.
.
.
temp=error_(); /* create error object */
this=(Serial_io*)malloc(sizeof(Serial_io)); /* make new object */
if(this==NULL) /* a malloc() error */
error_handler(this,TYPE_1,SERIAL);
memmove(this,temp,sizeof(Error_handler));/* move in inherited object */
error__(temp); /* get rid of the error object */
.
.
.
</code></pre>
<h2><a name="link">Data Sheet LINK</a></h2>
<h3>Device Name and description</h3>
<h3>Link</h3><p>--A link is a container that holds a single object. It is intended for use in some type
of linked list. The class link contains a pointer to the object and two pointers to the type
Link. One is the previous link andthe other is the next link. These two pointers provide
the capability of creation of single linked lists, double linked lists, binary trees, stacks
queues, etc.
<h3>Super Classes</h3>
<pre><code>
None
</code></pre>
<h3>Attributes</h3>
<pre><code>
struct object *current_object;
struct link *previous_link;
struct link *next_link;
</code></pre>
<h3>Methods</h3>
<pre><code>
None
</code></pre>
<strong>Constructor</strong>
<pre><code>
Link * link_(void *object);
</code></pre>
<strong>Destructor</strong>
<pre><code>
void link__( Link *);
</code></pre>
<strong>Macro Methods</strong>
<pre><code>
None
</code></pre>
<h3>Header File</h3>
<pre><code>
#ifndef LINK_H
#define LINK_H
#include "defines.h"
#include "object.h"
#define LINK_CLASS \
struct object *current_object; \
struct link *previous_link; \
struct link *next_link;
typedef struct link
{
LINK_CLASS
} Link;
Link * link_(void *object);
void link__( Link *);
#endif
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p>
A Link receives a pointer to an object and places this pointer along with pointers
designated previous_link and next_link into a structure. The previous_link and next_link
values are initialized to a NULL value.
<h3>Coding Examples</h3>
<pre><code>
#include <link.h>
#include <object.h>
.
.
.
Object *l1,*l2,*null; /* define some objects */
Link *lnk1,*lnk2,*lnknull; /* and links */
.
.
.
l1=object_(count_second_ticks);/* create two real objects */
l2=object_(count_half_second_ticks);
null=object_(NULL); /* and a null object */
.
.
.
lnk1=link_(l1); /* and put these objects */
lnk2=link_(l2); /* into links */
lnknull=link_(null);
.
.
.
</code></pre>
<h2><a name="link_list">Data Sheet LINK LIST</a></h2>
<h3>Device Name and description</h3>
<h3>Link List</h3>
<p>--A link list is a doubly linked list of objects. Each object is contained in a type
Link which contains a pointer to the object and pointers to the previous link and the next
link.
<h3>Super Classes</h3>
<pre><code>
None
</code></pre>
<h3>Attributes</h3>
<pre><code>
void *head;
</code></pre>
<h3>Methods</h3>
<pre><code>
void walk_list(Link_list *list); /* the list to be walked */
int add_link(Link_list *list, /* the list to receive */
Link *new_link); /* the new link */
int delete_link(Link_list *list, /* the list from which */
Link *old_link); /* old_link is to be deleted */
</code></pre>
<strong>Constructor</strong>
<pre><code>
Link_list *link_list_(void);
</code></pre>
<strong>Destructor</strong>
<pre><code>
void link_list__(Link_list *);
</code></pre>
<strong>Macro Methods</strong>
<pre><code>
None
</code></pre>
<h3>Header File</h3>
<pre><code>
#ifndef LINKLIST_H
#define LINKLIST_H
#include "defines.h"
#include "object.h"
#include "link.h"
#define LINK_LIST void *head;
typedef struct
{
LINK_LIST
} Link_list;
Link_list *link_list_(void);
void link_list__(Link_list *);
void walk_list(Link_list *list);
int add_link(Link_list *list,Link *new_link);
int delete_link(Link_list *list, Link *old_link);
#endif
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p> Each object contained in a link has a method called exercise(). The method
walk_list() executes the method exercise for each object in the list. Add link receive a
pointer to a new link as a parameter and a pointer to the list to which it is to be added.
The method add_link() places this new link at the head of the list. Links contained in the
list can be removed by delete_link(). This method has two parameters, the linked list
containing the link and a pointer to the link to be deleted. The location of the head of the
linked list is saved in the attribute head, but there is no tail saved. The end of the list is
designated by a "null" link. A null link is a link with all three of its attributes equal to
NULL. A null link must be placed on the list first before any other links are added.
<p> In the coding example shown below, the method walk_list() will be executed
from the Timer component. The Timer methods attach_method() and attach_object()
place the method walk list into the interrupt service routine of the timer t3 and the
argument of the method when it is executed is list1.
<h3>Coding Examples</h3>
<pre><code>
#include <object.h>
#include <link.h>
#include <linklist.h>
.
.
.
Object *l1,*l2,*null;
Link *lnk1,*lnk2,*lnknull;
Link_list *list1;
.
.
.
l1=object_(count_second_ticks); /* create the objects */
l2=object_(count_half_second_ticks);
null=object_(NULL);
.
.
.
list1=link_list_(); /* and the linked list */
.
.
.
lnknull=link_(null); /* create a null link */
lnk1=link_(l1); /* and the two real links */
lnk2=link_(l2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -