One thing missing from LinuxCNC is the ability to transfer structured,
buffered data between userspace and realtime.

This branch factors out the shared memory code used by hal's streamer
and sampler components into a C API so that components other than
streamer/sampler can receive or send data in a way that is compatible
with the existing components.  Unlike streamer/sampler, it is possible
(as long as userspace keeps up) to transfer more than one record per
thread invocation.

This means that hypothetically, hostmot2's serial code could be
rewritten so that it repeatedly reads bytes from a halstreamer shared
memory block into the transmit FIFO in the FPGA, and likewise reads from
the receive FIFO into a halsampler shared memory block to read back to
userspace---even if more than one u8/u16/u32 is transferred every servo
cycle.

(it could also be used between two realtime components or two
free-running components, but I suspect the RT<->free-running interface
to be the most interesting possibility)

I don't plan to merge this unless there's a user of it, such as a
UART-type component.  The branch is based off 2.7, but probably would be
merged to master if at all.

Its worth noting that without the 222 lines of documentation, the change
is a slight net deletion of code.

Jeff
---
The following changes since commit 13992eb9c54cbf3a42bec5932767a59bfcdd548d:

  configure: align the --disable-userspace-pci help correctly (2015-07-11 
11:57:14 -0600)

are available in the git repository at:

  git://git.linuxcnc.org/git/linuxcnc.git origin/jepler/hal-streams

for you to fetch changes up to 1eeb4914111cd88c46ed714179050bd63b73f630:

  hal: document the new C API (2015-07-11 20:42:43 -0500)

----------------------------------------------------------------
Jeff Epler (2):
      hal: factor out streamer/sampler
      hal: document the new C API

 docs/man/man3/rtapi_stream.3rtapi | 222 +++++++++++++++++++++++++++++++
 src/hal/components/sampler.c      | 226 +++++++-------------------------
 src/hal/components/sampler_usr.c  | 110 ++++------------
 src/hal/components/streamer.c     | 232 ++++++++-------------------------
 src/hal/components/streamer.h     |  23 ----
 src/hal/components/streamer_usr.c |  95 ++++----------
 src/hal/hal.h                     |  55 ++++++++
 src/hal/hal_lib.c                 | 268 ++++++++++++++++++++++++++++++++++++++
 src/hal/hal_priv.h                |  14 ++
 src/rtapi/uspace_rtapi_app.cc     |   1 -
 10 files changed, 704 insertions(+), 542 deletions(-)
 create mode 100644 docs/man/man3/rtapi_stream.3rtapi


hal_stream(3hal)                      HAL                     hal_stream(3hal)



NAME
       hal_stream - non-blocking realtime streams


SYNOPSIS
   #include <hal.h>

   int  hal_stream_create(hal_stream_t  *stream,  int  comp_id,  int  key, int
       depth, const char *typestring);
   void hal_stream_destroy(hal_stream_t *stream);
   int hal_stream_attach(hal_stream_t *stream, int  comp_id,  int  key,  const
       char *typestring);
   int hal_stream_detach(hal_stream_t *stream);


   int hal_stream_element_count(hal_stream_t *stream);
   hal_type_t hal_stream_element_type(hal_stream_t *stream, int idx);
   int hal_stream_depth(hal_stream_t *stream);
   int hal_stream_maxdepth(hal_stream_t *stream);
   int hal_stream_num_underruns(hal_stream_t *stream);
   int hal_stream_num_overruns(hal_stream_t *stream);


   int   hal_stream_read(hal_stream_t  *stream,  union  hal_stream_data  *buf,
       unsigned *sampleno);
   bool hal_stream_readable(hal_stream_t *stream);


   int hal_stream_write(hal_stream_t *stream, union hal_stream_data *buf);
   bool hal_stream_writable(hal_stream_t *stream);


   #ifdef ULAPI
   void hal_stream_wait_writable(hal_stream_t *stream, sig_atomic_t *stop);
   void hal_stream_wait_readable(hal_stream_t *stream, sig_atomic_t *stop);
   #endif



DESCRIPTION
       A HAL stream provides a limited ability for two components to  communi‐
       cate  data  which  does not fit within the model of HAL pins.  A reader
       and a writer must agree on a key (32-bit integer identifier) and a data
       structure  specified  by  typestring will hal_stream_create the stream,
       and wich component (the second one loaded)  will  hal_stream_attach  to
       the already-created stream.

       The  userspace  part  can be halstreamer or halsampler.  In the case of
       halstreamer the key is 0x48535430 plus the channel number.  In the case
       of halsampler the key is 0x48534130 plus the channel number.


   hal_stream_create
       Create  the  given  stream,  initializing the stream which is passed by
       reference.  If is an undiagnosed error if a  stream  has  already  been
       created with the same key.


   hal_stream_destroy
       Destroy  the given stream.  It is an undiagnosed error if the stream is
       still attached by another component.  It is an undiagnosed error if the
       stream  was  attached  with  hal_stream_attach rather than created with
       hal_stream_create.   It  is  an  undiagnosed  error  if  the  call   to
       hal_stream_destroy is omitted.


   hal_stream_attach
       Attach  the  given stream, which was already created by hal_stream_cre‐
       ate.  If the typestring is specified, this call fails if  it  does  not
       match  the  typestring  the stream was created with.  If the typestring
       argument is NULL, then any typestring is accepted.


   hal_stream_detach
       Detach the given stream.  It is an undiagnosed error if the stream  was
       created    with    hal_stream_create    rather   than   attached   with
       hal_stream_attach.   It  is  an  undiagnosed  error  if  the  call   to
       hal_stream_detach is omitted.


   hal_stream_element_count
       Returns the number of pins.


   hal_stream_element_type
       Returns the type of the given pin number.


   hal_stream_readable
       Returns true if the stream has at least one sample to read

   hal_stream_read
       If the stream has one sample to read, stores it in buf.

   hal_stream_writable
       Returns true if the stream has room for at least one sample to be writ‐
       ten.

   hal_stream_depth
       Returns the number of samples waiting to be read.

   hal_stream_maxdepth
       Returns the depth argument that the stream was created with.

   hal_stream_num_overruns
       Returns a number which is incremented  each  time  hal_stream_write  is
       called without space available.

   hal_stream_num_underruns
       Returns  a  number  which  is  incremented each time hal_stream_read is
       called without a sample available.


   hal_stream_wait_readable
       Waits until the stream is readable or the stop flag is set.


   hal_stream_wait_writable
       Waits until the stream is writable or the stop flag is set.


   hal_stream_read
       Reads a record from stream.  If successful, it is stored in  the  given
       buffer.   Optionally, the sample number can be retrieved.  If no sample
       is available, num_underruns is incremented.  It is an undetected  error
       if  more than one component or real-time function calls hal_stream_read
       concurrently.


   hal_stream_write
       Writes a record to the stream.  If successful, it copied from the given
       buffer.   If  no  room  is  available, num_overruns is incremented.  In
       either case, the internal sampleno value is incremented.
         It is an undetected error if more than  one  component  or  real-time
       function calls hal_stream_write concurrently.


ARGUMENTS
       stream A  pointer to a stream object.  In the case of hal_stream_create
              and hal_stream_attach this is an uninitialized stream; in  other
              cases,  it  must  be  a stream created or attached by an earlier
              call and not yet detached or destroyed.


       hal_id An HAL component identifier  returned  by  an  earlier  call  to
              hal_init.


       key    The key for the shared memory segment.


       depth  The  number of samples that can be unread before any samples are
              lost (overrun)


       typestring
              A typestring is a case-insensitive string which consists of  one
              or more of the following type characters:

           B      for bool / hal_bit_t

           S      for int32_t / hal_s32_t

           U      for uint32_t / hal_u32_t

           F      for real_t / hal_float_t
       A typestring is limited to 16 characters.

       buf    A buffer big enough to hold all the data in one sample.


       sampleno
              If  non-NULL,  the  last  sample number is stored here.  Gaps in
              this sequence indicate that an overrun occured between the  pre‐
              vious  read and this one.  May be NULL, in which case the sample
              number is not retrieved.


       stop   A pointer to a value which is monitored while waiting.  If it is
              nonzero,  the  wait operation returns early.  This allows a wait
              call to be safely terminated in the case of a signal.


SAMPLE CODE
       In the source tree under src/hal/components, sampler.c  and  streamer.c
       are realtime components that read and write hal streams.


REALTIME CONSIDERATIONS
       hal_stream_read,         hal_stream_readable,         hal_stream_write,
       hal_stream_writable,   hal_stream_element_count,    hal_tream_pin_type,
       hal_stream_depth,     hal_stream_maxdepth,    hal_stream_num_underruns,
       hal_stream_number_overruns may be called from realtime code.

       hal_stream_wait_writable, hal_stream_wait_writable may be  called  from
       ULAPI code.

       Other  functions  may be called in any context, including realtime con‐
       texts.

RETURN VALUE
       hal_stream_create   ,    hal_stream_attach    ,    hal_stream_read    ,
       hal_stream_write  ,  hal_stream_detach and hal_stream_destroy return an
       RTAPI status code.  Other functions' return values are explained above.


BUGS
       The memory overhead of a stream can be large.  Each element in a record
       uses  8  bytes, and the implicit sample number also uses 8 bytes.  As a
       result, a stream which is used to transport 8-bit values  uses  94%  of
       its memory as overhead.  However, for modest stream sizes this overhead
       is not important.  (this memory is part of its own shared memory region
       and  does not count against the HAL shared memory region used for pins,
       parameters and signals)


SEE ALSO
       sampler(9), streamer(9), halsampler(1), halstreamer(1)



LinuxCNC Documentation            2006-10-12                  hal_stream(3hal)

------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
Emc-developers mailing list
Emc-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/emc-developers

Reply via email to