Re: Hardware Abstraction Layer - Rev 0.01



>
> 2)  There are only two types of I/O, analog and digital.
> Digital values are either TRUE or FALSE.  A "bit" data
> type is typedef'ed for digital data:
>
> typedef enum { FALSE = 0, TRUE = 1 } bit;
>
> (C++ defines a "bool" type, but I'm not sure it is
> supported in C.  If it is, it would be better than
> creating a custom type.)  "bit" values occupy at
> least one byte - no packing is done at the HAL level.
> This prevents problems when two threads try to modify
> different bits in the same byte.

I recommend using "char" for boolean's.

A C++ bool will be 1 byte but an enum as you
have above will be 4 bytes.  But the type char is completely
unambigous. Defining your own version of TRUE, FALSE and bool
is something I see too many programs do.  The problem is that there is no
way too know your definition won't conflict with someone elses that
is included by some header file perhaps very indirectly. Even if you 
successfully
compile you can never be certain that some future version of a header file
you don't even care about will redefine it. I always just use 0 and 1 
directly in my
code and have given up trying to alias these to FALSE and TRUE.


>
> Analog values are represented as "doubles".  Most of the
> code that manipulates these values will be running in a
> thread that already uses floating point, so there will
> be no performance hit for saving/restoring the FP state.
> Drivers that use a faster thread (for example software
> step/direction) could convert from float to int in the
> slow thread, and run the fast thread entirely with
> fixed point.  (But they don't have to, the decision is
> made by the driver implementer.)
>
>
> Data Structures:
>
> HAL Runtime Data:
>
>   EMC Side Data:
>
>     /* structure containing all EMC side variables for an abstracted 
> motion axis */
>     typedef struct
>     {
>       double   PosFb;               /* input:   position feedback, in 
> counts */
>       double   VelCmd;              /* output:  velocity command, in 
> counts/second */
>       bit      Home;                /* input:   true means home switch 
> tripped*/
>       bit      LoLim;               /* input:   true means low limit 
> switch tripped */
>       bit      HiLim;               /* input:   true means high limit 
> switch tripped */
>       bit      Fault;               /* input:   true means amp has 
> faulted */
>       bit      Clamp;               /* output:  true means axis should 
> be clamped */ 

Does this mean clamp velocity, voltage, or position? Either way would we 
need some max value to clamp it to?

>
>       bit      Enable;              /* output:  true means amp should 
> be enabled */
>     /* Anything else? */
>     } HAL_AXIS;
>
>     There would be one of these for each axis.  There would also be 
> structures for
>     the spindle(s), and variables or structures for other I/O such as 
> coolant,
>     lube, toolchangers, etc.
>
>   HW Side Data:
>
>     /* structure containing all HW side variables for a printer port */
>     /* defined in the printerport driver and present only when that 
> driver is loaded */
>     typedef struct
>     {
>       bit     Pin1;                 /* output:  true drives pin 1 hi */
>       bit     Pin14;                /* output:  true drives pin 14 hi */
>       bit     Pin16;                /* output:  true drives pin 16 hi */
>       bit     Pin17;                /* output:  true drives pin 17 hi */
>       bit     Pin2;                 /* output:  true drives pin 2 hi */
>       bit     Pin3;                 /* output:  true drives pin 3 hi */
>       bit     Pin4;                 /* output:  true drives pin 4 hi */
>       bit     Pin5;                 /* output:  true drives pin 5 hi */
>       bit     Pin6;                 /* output:  true drives pin 6 hi */
>       bit     Pin7;                 /* output:  true drives pin 7 hi */
>       bit     Pin8;                 /* output:  true drives pin 8 hi */
>       bit     Pin9;                 /* output:  true drives pin 9 hi */
>       bit     Pin10;                /* input:   true when pin 10 is hi */
>       bit     Pin11;                /* input:   true when pin 11 is hi */
>       bit     Pin12;                /* input:   true when pin 12 is hi */
>       bit     Pin13;                /* input:   true when pin 13 is hi */
>       bit     Pin15;                /* input:   true when pin 15 is hi */
>     } DRV_PPBITS;
>
>     There would be a data structure for each driver loaded.  The 
> structure would
>     vary depending on the I/O mix provided by the driver.
>
> HAL Init Data:
>
>   Link Data:
>
>     /* structures used to establish a link between an EMC side 
> variable and a HW side variable */
>     typedef struct
>     {
>       double *src;         /* pointer to data source */
>       double *dst;         /* pointer to data destination */
>     } HAL_LINK_DBL;
>
>     typedef struct
>     {
>       bit   *src;          /* pointer to data source */
>       bit   *dst;          /* pointer to data destination */
>       bit    invert;       /* true means an inverting link */
>     } HAL_LINK_bit;
>
>     /* arrays of links, filled in from ini file */
>
>     HAL_LINK_DBL      hal_output_links_dbl[MAX_LINKS_DBL];
>     HAL_LINK_BIT      hal_output_links_bit[MAX_LINKS_BIT];
>     HAL_LINK_DBL      hal_input_links_dbl[MAX_LINKS_DBL];
>     HAL_LINK_BIT      hal_input_links_bit[MAX_LINKS_BIT];
>
>   Driver Function pointers:
>
>     An array of pointers to each driver's runtime code
>
>
> Sqeuence of operation:
>
> 1)  Hardware interrupt occurs (either system timer, or hardware device)
> 2)  Run through both output link arrays, copying data from EMC side to 
> HW side.
> 3)  Run through driver function pointer array, calling driver runtime 
> code.
> 4)  Driver runtime code copies output data from HW side structs to the 
> actual hardware.
> 5)  Driver runtime code copies input data from the actual hardware to 
> the HW side structs.
> 6)  Driver runtime code returns.
> 7)  Run through both input link arrays, copying data from HW side to 
> EMC side.
> 8)  End of HAL code, begin executing servo loop code (emcmot).
>
> MAJOR ISSUES:
>
> The runtime stuff is pretty simple, in fact I coded it in less than an 
> hour.
> Init is the hard part.  The drivers must export the names and locations
> of their runtime data in a way that allows the ini file to specify links.
> Links might look like this in the ini file: 

The INI file program almost definitely has to be read in a user space app.
This means either each each HAL implementation comes with two components
a real time driver and a corresponding  non realtime app that reads and 
parses the INI file and sends data appropriate for that HAL down to 
realtime app via shared memory or fifo.
Or we always copy the entire INI file down  and have each HAL parse the 
INI data now loaded into memory. My preference would probably be for the 
first option since the less
code that runs in realtime where debugging is harder and mistakes are 
more likely to halt your system the better.


>
>
> [INLINKS]
> axis[0].pos_fb   =  stg[1].chan[2].encoder
> axis[0].hi_limit =  parallelport[0].Pin11
> axis[0].lo_limit =  parallelport[0].Pin11
> axis[0].home     = !stg[1].digio[20]
>
> [OUTLINKS]
> stg[1].chan[2].dac   =  axis[0].vel_cmd
> parallelport[0].Pin3 =  axis[0].enable
>
> Note in the INLINKS section that both the high limit and
> low limit are linked to the same input, and the home input
> is low true, which generates an inverting link.
>
> There is also no reason why a link has to go from the HW
> side to the EMC side, or vice-versa.  A link from one EMC
> variable to another would be perfectly legal, as would a link
> from one HW side variable to another.
>
> In fact, a PLC could be loaded just like a driver.  It would
> export a number of bits that would be coils and contacts
> in it's ladder logic.  Links would connect the coils and
> contacts to EMC side and/or HW side variables as needed.
>
> I'm learning more about the ini file and the functions that
> manipulate it, but I'm not ready to propose a detailed
> mechanism to get from the list of links above to a
> completely filled in set of link arrays.  I just wanted to
> post this to get other people looking at it.  Please
> review and let me know what you think.
>
> John Kasunich
>


-- 


--------------------------------------------------
Will Shackleford
NIST
100 Bureau Dr. Stop #8230
Gaithersburg, MD 20899
(301) 975-4286
Please do not send me Microsoft formatted documents.
They frequently contain viruses and discourage fair
competition and open standards.
I will ignore any email that contains them unless 
 absolutely necessary.
-------------------------------------------------








Date Index | Thread Index | Back to archive index | Back to Mailing List Page

Problems or questions? Contact