discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] Constant carrier digital transmission


From: Inspire Me
Subject: Re: [Discuss-gnuradio] Constant carrier digital transmission
Date: Thu, 18 Aug 2016 20:05:29 +1000

Hi Ed

I have the continuous Flags working thanks to the information and explanations. I owe thanks to you and to Nick and Marcus for the help. End the end it was quite simple to modify the current HDLC Framer to output flags when there are no messages in the queue. 

Kind Regards
Frank




On 17 Aug 2016, at 1:20 pm, Ed Criscuolo-3 [via GnuRadio] <address@hiddennabble.com> wrote:

On 8/16/16 11:28 PM, Inspire Me wrote:

> Hi Ed
>
> Much appreciated. You mentioned latency due to queued flags. This has
> potential to cause us issues. I was wondering if it is possible to build
> a block as a sort of switch that takes input from the standard HDLC
> Framer but executues continuously, ie once every symbol period T=
> n*(1/(9600*4), it would check to see if any items are in the input
> buffer and if not push nFlags out (n being small), boost sleep for on
> n*symbol period and repeat. I know this would be highly inefficient but
> given it will be a very basic block it would only execute for a fraction
> of the symbol time. The other option was to have a seperate thread in
> the block for sending the flags which runs independent of the Work
> function and use a semaphore to enable / disable the sending of flags..
> Your thoughts and insight would be valuable.

Again, I repeat that GnuRadio blocks are timing agnostic.  You cannot
"pace" the bitstream in real-time by the use of "sleeps".

You need to write a block that has NO bitstream inputs, and one
bitstream output. This is known as a "source" block. In addition
it should have a message port for receiving HDLC frames.  As in
the example I showed you, this new block should check the message
port for an HDLC frame, bitstuff it into the output bitstream, and
repeat this until either the message port is empty or the output
buffer is full.  If the message port is empty on the initial entry
to work, output a single FLAG worth of bits and exit, returning a
value of 8.
>
> Q.I thought I read that the schedular only schedules work function when
> there is input data to process. In other words if no input is available
> then the work function would not be scheduled. Is this correct ? If not
> where can I find more information on the scheduler. I have read material
> available online including (
> https://static.squarespace.com/static/543ae9afe4b0c3b808d72acd/543aee1fe4b09162d0863397/543aee20e4b09162d0863578/1380223973117/gr_scheduler_overview.pdf
> )

The scheduler will schedule a block to run if there is input available
AND the output buffer is available.  That is, all of the immediately
downstream blocks have indicated that they have consumed the data.
This is called backpressure.  In the case of a source block, there
are no inputs, and the block is run whenever the output buffer space is
available.
>
> Once again thank you for spending time helping.

No problem.  I believe you said you're doing a CubeSat application?
On small satellites, often the best approach to this problem is to
use an HDLC framer chip, which does all this for you and produces
a simple bitstream with flags and frames all in their proper places.
This bitstream is then straightforward to handle and send to a modulator.

One last note.  Keep the discussion on-list so others may benefit
(do a "Reply All" instead of a "Reply", otherwise it just comes to me).

@(^.^)@  Ed

>
> Kind Regards
> Frank
>
> On 17 August 2016 at 11:59, Ed Criscuolo <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     In a GnuRadio block that is derived from a "sync" block, the number of
>     input and output items are the same, so the work function is supplied
>     with a single value called "nitems".  The normal control flow of a
>     typical work function uses a loop that iterates over nitems, taking
>     one item from the input(s) buffer(s) and producing one item into the
>     output buffer. This process repeats until all input items are consumed
>     and all output buffer item spaces are full.  The work function then
>     returns a value of "nitems" to indicate to the scheduler how many items
>     were consumed and produced.
>
>     But it is perfectly legal for the loop in the work function to
>     terminate early, in which case it should return the number of items
>     _actually_ processed.  The scheduler will take care of keeping track
>     of the partial buffers and no data will be lost.  But performance
>     will be reduced.
>
>     GnuRadio blocks are timing agnostic.  They run as fast as they can,
>     and process an entire buffer's worth of items (typically 64K items)
>     per call to the work function.  This is done to improve throughput.
>     Timing only happens when your bitstream meets up with a hardware
>     device, like a USRP. But as long as the _average_ throughput is
>     fast enough to keep up with the hardware, everything is fine.
>     The amount of CPU processing "headroom" determines how far you can
>     degrade a block's average throughput without creating underruns.
>
>     This level of understanding is fundamental to writing any GnuRadio
>     blocks, so you really should take the time to play with it and get
>     to know it.
>
>     Here is a snippet of VERY OLD code for example only. It that always
>     runs "nitems" times. When idle (ie - no hdlc packets available), it
>     produces 64k bits (8k of flags) on every invocation! This results in
>     a large latency when a packet finally does come along.
>     It should be modified to break the loop on the second fifo empty
>     test and return "i" instead of "nitems"
>
>     int
>     sc_hdlc_router_source_b::work (int                       noutput_items,
>                                             gr_vector_const_void_star
>     &input_items,
>                                             gr_vector_void_star
>       &output_items)
>     {
>        unsigned char * outbuf = (unsigned char *) output_items[0];
>        int             i;
>
>        // Loop until the requested number of output stream bytes have
>     been generated
>        for(i=0; i<noutput_items; i++)
>        {
>          if (d_fifo.empty())
>            {
>              // Process a single incoming packet on the tun/tap pseudo
>     network device
>              // by bitstuffing it, encapsulating it in an MPoFR frame,
>     and pushing
>              // it into the bit_buf fifo.
>              encapsulate_incoming_packet();
>            }
>
>          // If bit_buf fifo is still empty, push a FLAG into it
>          if(d_fifo.empty())
>            {
>              push_flag();
>            }
>
>          // Output a bit from the bitbuf in the low-order bit of the
>     output byte
>          outbuf[i] = d_fifo.pop();
>        }
>
>        return noutput_items;
>     }
>
>
>     @(^.^)@  Ed
>
>
>     On 8/16/16 8:12 PM, Inspire Me wrote:
>
>         Hi Ed
>
>         Thank you for the response.
>         I like the idea of the second option. Could please expand the
>         explaination. I am new to gnuradio and don't yet fully grasp how the
>         scheduler works in detail. How do you terminate the work
>         function early
>         and ensure the single 0x7E gets streamed immediately to the
>         modulator so
>         that we don't get under runs. How quickly will the work function
>         be re
>         executed by the scheduler ? As fas as CPU is concerned, I have a
>         machine
>         with 16 cores ( 32 threads). I am not concened if one thread is
>         consumed
>         by this. Could you send me a snippet of the work function you
>         implemented.
>
>         Your assitance is much appreciated.
>
>         Kind Regards
>         Frank
>
>         On 17 August 2016 at 02:00, Ed Criscuolo <[hidden email]
>         <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>
>              Hi Frank,
>
>              I'm the author of the GMSK Spacecraft Groundstation project you
>              referenced.  Been on vacation for the last 2 weeks without
>         internet,
>              so I'm just seeing this.
>
>              All in all, Marcus is giving you good advice.  At the time
>         I wrote
>              it, there were no tags or messages, so everything related to
>              PDU-like behavior had to be implemented in a single  C++
>         block. Now,
>              packets can come in as PDUs, and get converted into a
>         bitstream in a
>              single, much simpler block.
>
>              As for the issue of putting HDLC flag octets out
>         back-to-back as the
>              "idle" pattern between frames, I had tried two different
>         solutions,
>              one of which Marcus touched upon.
>
>              First approach was to simply reduce the buffer size of all
>         blocks by
>              recompiling GnuRadio with the appropriate global constant
>         reset to a
>              smaller value.  This has significant impact on overall
>         performance,
>              but because our data rate was modest (only a few hundred
>         Kbits/sec)
>              and we had some wicked fast hardware (for the times!) we
>         were able
>              to get this to work, reducing the added latency of outbound
>         packets
>              from over ten seconds to only a few seconds. This was OK
>         for our
>              particular requirements, but not for a general purpose
>         system.  It
>              was an easy but VERY brute-force solution.
>
>              Later, I modified the block to to implement a solution
>         similar to
>              Marcus' "Option A".  Every time the block's work function
>         was entered,
>              it checked for an available packet (I was using sockets,
>         but modern
>              GnuRadio would use PDUs and message queues). If a packet
>         was available,
>              it would be bitstuffed and the bitstream written to the output
>              buffer. This would continue until either no more packets were
>              available, or the
>              output buffer reached capacity.  If there were NO packets
>         available
>              when the work function was called, it would put a SINGLE
>         0x7E (that
>              is, a bitstream of eight bits) on the output buffer and
>         terminate
>              the work function early, returning only the numbers of bits
>         actually
>              produced.
>              This is perfectly allowable, but it will result in the
>         block consuming
>              a large amount of CPU when generating idle flags.  At least
>         this
>              solution only effects a single block instead of all the blocks.
>
>              If the resulting CPU usage is too high, it could be
>         reduced, at the
>              cost of adding latency, by outputting 2 or more flags at a
>         time.
>
>              Hope this helps.
>
>              @(^.^)@  Ed
>
>
>              On 8/15/16 7:00 PM, Inspire Me wrote:
>
>                  Hi Nick / Marcus
>
>                  Great discussion, obviously this issue has been solved
>         before, as
>                  mentioned in the 2009 discussion the
>         GMSKSpacecraftGroundstation
>                  project
>                  (
>         https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation>
>
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation>>
>
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation>
>
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation
>         <https://moo.cmcl.cs.cmu.edu/trac/cgran/wiki/GMSKSpacecraftGroundstation>>>
>                  )
>                  seems to have solved it. I acknowledge that gnuradio
>         has moved
>                  on, but I
>                  would like to see how it was solved and possibly adapt
>         it to the
>                  current
>                  gnuradio. *Is there anyway to get access to the code ?*
>         I am
>                  stuck at
>                  the moment.
>
>                  The only idea I have is to impelement a source block
>         with very small
>                  buffers to feed into the Tx Chain and some sort of
>         switch to toggle
>                  between data stream and flag stream based on a message
>         / tag
>                  from up the
>                  chain.
>
>                  Nick can you elaborate on the modification of the
>         Work() function. I
>                  thought this was scheduled only when sufficient data is
>         in the Input
>                  buffer ? Is there a way to have this execute more often
>         or when
>                  no data
>                  exists in the input buffer ? Is there a way to implement a
>                  switch block
>                  that monitors input streams and efectively switches the
>         output
>                  stream
>                  such that it is not blocked waiting for input from one
>         of the
>                  streams ?
>
>                  Once again thank you for the help
>
>                  Kind Regards
>                  Frank
>
>                  On 16 August 2016 at 03:14, Marcus Müller
>                  <[hidden email]
>         <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>
>                  <mailto:[hidden email]
>         <mailto:[hidden email]>
>
>                  <mailto:[hidden email]
>         <mailto:[hidden email]>>>> wrote:
>
>                       Hi Nick,
>
>
>                       On 15.08.2016 19:19, Nick Foster wrote:
>
>                           This is a pretty familiar problem. A lot of satcom
>                      systems require
>                           continuous transmission when in an idle state
>         so the
>                      receiver can
>                           use slow (i.e., sensitive) frequency and timing
>                      estimator loops.
>                           I'm sorry to say there's no great answer.
>
>                           But you have some options:
>                           a) modify the HDLC block so that when work()
>         is called,
>                      if nothing
>                           is in the msg queue just output some fixed
>         number of
>                      0x7Es and sit
>                           on its thumbs until the next call.
>
>                       'doh! Could've thought of that; makes a lot of
>         sense, here.
>
>                           b) modify whatever block is generating
>         messages so that
>                      it outputs
>                           0x7E frames periodically
>                           c) modify the FPGA (or whatever DUC backend you're
>                      using) to both
>                           do the modulating and send 0x7Es (modulated) when
>                      there's nothing
>                           coming in
>
>                           Each approach has its disadvantages:
>                           a) because Gnuradio buffers can be quite
>         large, you
>                      will incur a
>                           latency penalty as GR (i.e., all of the
>         buffers of all
>                      of the
>                           blocks downstream of the HDLC framer)
>         propagates your
>                      frame downstream
>
>                       Not if he adds the functionality to include a
>         tx_time tag; that
>                       wouldn't /reduce/ latency, but it would allow for
>         time-slotted
>                       transmissions!
>
>                           b) message sources don't have backpressure, so
>         this
>                      won't really
>                           work -- either you'll underflow and interrupt your
>                      sample stream
>                           or build up a huge stack of unsent data just
>         as in a)
>                           c) this is a lot of work, and requires that
>         the whole
>                      modulator,
>                           soup-to-nuts, is implemented in the FPGA.
>
>                           I'd start with approach a) and work your way
>         towards c)
>                      if your
>                           application can't handle the latency.
>
>                           --n
>
>                       Best regards,
>                       Marcus
>
>                       _______________________________________________
>                       Discuss-gnuradio mailing list
>         [hidden email] <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>
>                  <mailto:[hidden email]
>         <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>>
>         https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>
>
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>>
>
>           <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>
>
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>>>
>
>
>
>
>                  _______________________________________________
>                  Discuss-gnuradio mailing list
>         [hidden email] <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>
>         https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>
>
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>         <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>>
>
>
>
>
>
>
>     _______________________________________________
>     Discuss-gnuradio mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>     <https://lists.gnu.org/mailman/listinfo/discuss-gnuradio>
>
>



_______________________________________________
Discuss-gnuradio mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio



If you reply to this email, your message will be added to the discussion below:
http://gnuradio.4.n7.nabble.com/Constant-carrier-digital-transmission-tp27764p61256.html
To unsubscribe from Constant carrier digital transmission, click here.
NAML


reply via email to

[Prev in Thread] Current Thread [Next in Thread]