<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    My 10 Cents on 'Embedded friendlyness':<br>
    <br>
    Objects and simple functions/procedures do not differ much in
    flash/memory usage as long as you do not use
    constructors/destructors.<br>
    <br>
    Calling your first constuctor adds arround 750 bytes of extra code
    (on avr platform). As those avr devices can have very low amount of
    flash i'd stay away from constuctors if possible.I'd also try to
    avoid virtual methods as the compiler will have to create a vmt and
    this will cost you precious RAM.<br>
    <br>
    Enhanced Records are also a good choice because you can save some
    bytes as the compiler can reuse the "self" parameter to address
    other fields in the record. This saves space on arm/mipsel targets
    where Devices like spi/uart/i2c are modeled as records and you
    usually address more than one register in a typical call to
    initialize or use the device.<br>
    Last time I checked Enhanced Records also do not have
    constructors/vmt's (OK, not true for delphi...) so also no easy
    chance to waste that extra Flash/Ram on constuctors and vmt's.....<br>
    <br>
    Besides those memory saving arguments here are some more ideas:<br>
    <br>
    When using Objects or advanced records you can simplify code that
    can use more than one communications protocol, e.g. those cheap
    OLED-Displays often are able to be driven via either SPI and I2C.
    When you create a thin layer on SPI/I2C then it is quite easy to
    support both protocols with low overhead and quite clean code for
    this kind of devices.<br>
    <br>
    From the "syntax candy" side of things I would definitely prefer
    Objects/Advanced Records over raw functions/procedures as you will
    get nice syntax help for all methods/properties as soon as you type
    the name of your instance in Lazarus.<br>
    <br>
    So what about classes?<br>
    <br>
    In a perfect world where everybody uses high performance 32bit
    microcontrollers (CortexM4/M7 chips from Microchip(Atmel)/ST/NXP) I
    would only use Classes and be happy forever, but unfortunately it
    seems that those 'big' chips, although beeing quite cheap (arround
    $10 to $40 for a very decent development board) do not catch that
    much attention, wonder why...<br>
    <br>
    And on all the small chips (LPC8xx/LPC11xx, AVR...,SAMD10/11) are
    absolutely not suited for classes as usage of classes will usually
    come with a high memory footprint , you will use all language
    features available and this requires you to often include additional
    units like sysutils which alone comes with a huge memory overhead
    and code generated for classes often includes hidden helpers that
    cost you extra CPU-Cycles and even more Flash..... Also Classes ar
    instanciated on Heap, so you also need to include HeapMgr, not the
    biggest price to pay but anoher few k of flash are gone....<br>
    <br>
    If you want to dig deeper i'd recommend to compile your code with
    the '-a' parameter, this parameter tells fpc to not delete the
    generated assembler files and simply by looking at those you get a
    good feel on what code is efficient and what code wastes
    cycles/flash like hell.<br>
    <br>
    So, to sum up, for me advanced records are currently the most
    efficient way to program microcontrollers, mainly because of my
    focus on smaller executables for the widest range of controllers,
    but depending on your requirements your mileage may vary.....<br>
    <br>
    Michael<br>
    <br>
    <br>
    Here's a lpi file to get you started in your investigations, you may
    need to change a few paths as they are unix specific....<br>
    <br>
    <tt><?xml version="1.0" encoding="UTF-8"?></tt><tt><br>
    </tt><tt><CONFIG></tt><tt><br>
    </tt><tt>  <ProjectOptions></tt><tt><br>
    </tt><tt>    <General></tt><tt><br>
    </tt><tt>      <UseAppBundle Value="False"/></tt><tt><br>
    </tt><tt>    </General></tt><tt><br>
    </tt><tt>    <BuildModes Count="1"></tt><tt><br>
    </tt><tt>      <Item1 Name="default" Default="True"/></tt><tt><br>
    </tt><tt>    </BuildModes></tt><tt><br>
    </tt><tt>    <Units Count="1"></tt><tt><br>
    </tt><tt>      <Unit0></tt><tt><br>
    </tt><tt>        <Filename Value="test.lpr"/></tt><tt><br>
    </tt><tt>        <IsPartOfProject Value="True"/></tt><tt><br>
    </tt><tt>        <IsVisibleTab Value="True"/></tt><tt><br>
    </tt><tt>        <Loaded Value="True"/></tt><tt><br>
    </tt><tt>      </Unit0></tt><tt><br>
    </tt><tt>    </Units></tt><tt><br>
    </tt><tt>  </ProjectOptions></tt><tt><br>
    </tt><tt>  <CompilerOptions></tt><tt><br>
    </tt><tt>    <Target></tt><tt><br>
    </tt><tt>      <Filename Value="test"/></tt><tt><br>
    </tt><tt>    </Target></tt><tt><br>
    </tt><tt>    <SearchPaths></tt><tt><br>
    </tt><tt>      <UnitOutputDirectory
      Value="lib/$(TargetCPU)-$(TargetOS)"/></tt><tt><br>
    </tt><tt>    </SearchPaths></tt><tt><br>
    </tt><tt>    <CodeGeneration></tt><tt><br>
    </tt><tt>      <TargetCPU Value="avr"/></tt><tt><br>
    </tt><tt>      <TargetOS Value="embedded"/></tt><tt><br>
    </tt><tt>    </CodeGeneration></tt><tt><br>
    </tt><tt>    <Linking></tt><tt><br>
    </tt><tt>      <Debugging></tt><tt><br>
    </tt><tt>        <GenerateDebugInfo Value="True"/></tt><tt><br>
    </tt><tt>        <DebugInfoType Value="dsDwarf2"/></tt><tt><br>
    </tt><tt>        <UseLineInfoUnit Value="False"/></tt><tt><br>
    </tt><tt>      </Debugging></tt><tt><br>
    </tt><tt>    </Linking></tt><tt><br>
    </tt><tt>    <Other></tt><tt><br>
    </tt><tt>      <CustomOptions Value="-Cpavr5</tt><tt><br>
    </tt><tt>-XP/usr/local/bin/avr-</tt><tt><br>
    </tt><tt>-WpATMEGA328P</tt><tt><br>
    </tt><tt>-dATMEGA328P</tt><tt><br>
    </tt><tt>-MObjFpc</tt><tt><br>
    </tt><tt>-a</tt><tt><br>
    </tt><tt>      "/></tt><tt><br>
    </tt><tt>    </Other></tt><tt><br>
    </tt><tt>  </CompilerOptions></tt><tt><br>
    </tt><tt></CONFIG></tt><tt><br>
    </tt><br>
    <div class="moz-cite-prefix">Am 01.06.19 um 15:37 schrieb Dimitrios
      Chr. Ioannidis via fpc-devel:<br>
    </div>
    <blockquote type="cite"
      cite="mid:7d59afc4-a6d8-1967-dd7b-3c13c8f77e8c@nephelae.eu">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <p><tt>Hi,</tt></p>
      <p><tt>  I started to write a driver ( <a
            class="moz-txt-link-freetext"
            href="https://github.com/dioannidis/fp_ethernet_enc28j60.git"
            moz-do-not-send="true">https://github.com/dioannidis/fp_ethernet_enc28j60.git</a>
          ) for this chip ( ENC28J60 Ethernet Controller ) first for the
        </tt><tt><tt> AVR platform, </tt>( heavily inspired from the
          UIPEthernet library ( <a class="moz-txt-link-freetext"
            href="https://github.com/UIPEthernet/UIPEthernet.git"
            moz-do-not-send="true">https://github.com/UIPEthernet/UIPEthernet.git</a>
          )) and I want to ask the community, of course, is there anyone
          that already done it ? <br>
        </tt></p>
      <p><tt>  My goal is to made the free pascal users able to use a
          very low cost solution Arduino Nano / UNO  development board
          with a ENC28J60 module for a little IoT ( and not only ) fun,
          learning e.t.c. ...<br>
        </tt></p>
      <p><tt>  I managed to configure the chip and the driver receives
          packets ( </tt><tt><span class="pl-c">broadcast packets </span>configured
          to allow only ARP ). <br>
        </tt></p>
      <p><tt>  Now, because I'm not embedded developer I'm thinking that
          I would need help / advices to take some decisions so here I
          am. <br>
        </tt></p>
      <p><tt>  First and more important, in the new FPC version, will
          the AVR platform review / resolve the following issues : <br>
        </tt></p>
      <tt>    "AVR - incorrect stack error checking" (<a
          class="moz-txt-link-freetext"
          href="https://bugs.freepascal.org/view.php?id=35332"
          moz-do-not-send="true">https://bugs.freepascal.org/view.php?id=35332</a>)
      </tt><br>
      <tt>    "AVR - Assembler routines for 8, 16 & 32 bit unsigned
        div (code contribution)" ( <a class="moz-txt-link-freetext"
          href="https://bugs.freepascal.org/view.php?id=32103"
          moz-do-not-send="true">https://bugs.freepascal.org/view.php?id=32103</a>
        )</tt><br>
      <tt>    "</tt><tt>AVR - invalid address used when evaluating a
        variable in gdb" ( <a class="moz-txt-link-freetext"
          href="https://bugs.freepascal.org/view.php?id=33914"
          moz-do-not-send="true">https://bugs.freepascal.org/view.php?id=33914</a>
        )</tt><br>
      <tt>    "AVR - Incorrect SPI clock rate bit constant names in some
        microcontroller units" ( <a class="moz-txt-link-freetext"
          href="https://bugs.freepascal.org/view.php?id=32339"
          moz-do-not-send="true">https://bugs.freepascal.org/view.php?id=32339</a>
        ) </tt><br>
      <tt>    and add support for the</tt><tt> avrxmega3 subarch, atmega
        3208, 3209, 4808, 4809 ( from Christo Crause's repository <a
          class="moz-txt-link-freetext"
          href="https://github.com/ccrause/freepascal.git"
          moz-do-not-send="true">https://github.com/ccrause/freepascal.git</a>
        ) ?</tt>
      <p><tt>  Except from Laksen's ethernet stack ( <a
            class="moz-txt-link-freetext"
            href="https://github.com/Laksen/fp-ethernet.git"
            moz-do-not-send="true">https://github.com/Laksen/fp-ethernet.git</a>
          ) is there other, more lightweight, ethernet stack library
          written in Object Pascal ?<br>
        </tt></p>
      <p><tt>  As I'm not a compiler guy, is</tt><tt><tt> the "volatile"
            intrinsic supported in AVR platform ( I didn't find it in
            intrinsics unit ) ?</tt></tt></p>
      <p><tt>  In FPC embedded world/platforms, is the Object approach
          more SRAM hungry ( my tests are inconclusive ) from the
          procedure / function approach ?<br>
        </tt></p>
      <p><tt>  What's more embedded "friendly" ?</tt></p>
      <p><tt>this :<br>
        </tt></p>
      <p><tt>interface</tt></p>
      <tt>type</tt><br>
      <tt>  TUART = Object<br>
          private<br>
            FBaudRate: DWord;<br>
            function Divider: Integer;<br>
          public<br>
            procedure Init(const ABaudRate: DWord = 57600);<br>
            procedure SendChar(c: char);<br>
            function ReadChar: char;<br>
            procedure SendString(s: ShortString);<br>
            procedure SendStringLn(s: ShortString = '');<br>
          end;</tt>
      <p><tt>or this :</tt></p>
      <tt>interface<br>
      </tt><br>
      <tt>  var</tt><br>
      <tt>    FBaudRate: DWord;</tt><br>
      <tt>    function Divider: Integer;</tt><br>
      <tt>    procedure Init(const ABaudRate: DWord = 57600);</tt><br>
      <tt>    procedure SendChar(c: char);</tt><br>
      <tt>    function ReadChar: char;</tt><br>
      <tt>    procedure SendString(s: ShortString);</tt><br>
      <p><tt>    procedure SendStringLn(s: ShortString = '');</tt></p>
      <p><tt><br>
        </tt></p>
      <p><tt>And of course anyone who wants to help is welcome .<br>
        </tt></p>
      <p><tt>regards,</tt></p>
      <p><tt>-- <br>
        </tt></p>
      <p><tt>Dimitrios Chr. Ioannidis<br>
        </tt></p>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
fpc-devel maillist  -  <a class="moz-txt-link-abbreviated" href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a>
<a class="moz-txt-link-freetext" href="http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>
</pre>
    </blockquote>
  </body>
</html>