Portability: Harmony between PC and microcontroller

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?=

    Portability: Harmony between PC and microcontroller


    I'll try to summarise this as best I can, as my last thread wasn't
    very to-the-point:

    The C Standard says the following two things:

    * int is the natural integer type for the system.
    * int must be at least 16-Bit.

    Now the problem here is that these two criteria conflict if the
    natural type for the system is in fact 8-Bit, which is the case with
    many microcontroller s today.

    As an example, let's take the following code:

    char unsigned x, y;
    ...
    x = y;

    On my microcontroller compiler, this produces different assembler
    depending on whether 'x' is an "unsigned int" or an "unsigned char".
    If it's an "unsigned char", then the assembler is:

    MOVF y, W /* Copy y to the accumulator */
    MOVWF x /* Copy the accumulator to x */

    However, if 'x' is an "unsigned int", then the assembler is:

    MOVF y, W /* Copy y to the accumulator */
    MOVWF x /* Copy the accumulator to x */
    MOVF y+1, W /* Copy the next byte of y to the acc */
    MOVWF x+1 /* Copy the acc to the next byte of x */

    Now quite plainly to see, the "int" version takes twice as many
    instructions in this case, and will therefore take exactly twice as
    long to execute, and so will be twice as slow. In other situations,
    the difference is far worse; let's take for example the following
    code:

    if (condition) x = y;

    Depending on the type of x and y, this produces either:

    MOVF y, W /* Copy y to the accumulator */
    BTFSC condition /* If condition is false, skip the next
    instruction */
    MOVWF x /* Copy the accumulator to x */

    or:

    BTFSS condition /* Skip the next instruction if condition is true
    */
    GOTO There
    MOVF y, W /* Copy y to the accumulator */
    MOVWF x /* Copy the accumulator to x */
    MOVF y+1, W /* Copy the next byte of y to the acc */
    MOVWF x+1 /* Copy the acc to the next byte of x */
    There:

    Not only does the int version consist of more instructions, but it
    also involves a goto which will take up even more time. So basically
    if your microcontroller is running at 8 MHz, then you may aswell
    pretend it's running at 4 MHz or 2 MHz if you're going to be using int
    for doing everyday arithmetic.

    Now we could go down the road of discussing how C is inadequate in
    terms of its accommodation of microcontroller s, but I'd rather discuss
    ways of "making it right". The reason I'm so eager to bridge the gap
    is that, other than the "int" situation, C is actually great for
    programming an embedded system. I used it in my college project this
    year to program a portable electronic Connect4 game, and it worked
    great!

    One way of making things right is to stop using int for arbitrarily
    storing numbers, and instead use something like ufast8 (the fastest
    integer type that's at least 8-Bit). In this way, neither the
    microcontroller s nor the PC's suffer.

    Examples of a piece of code that could be brought between PC's and
    microcontroller s is something like a look-up table as follows:

    ufast8 days_in_month[12] =
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    To those people out there who are enthusiastic about writing portable
    code, how do you feel about using types such as ufast8 instead of int?

    stdint.h is great and all, but I find the type names to be too long
    winded. For instance I'd rather write "ufast8" instead of
    "uint_fast8 _t".
  • Jack Klein

    #2
    Re: Portability: Harmony between PC and microcontroller

    On Sun, 4 May 2008 18:16:43 -0700 (PDT), Tomás Ó hÉilidhe
    <toe@lavabit.co mwrote in comp.lang.c:
    >
    I'll try to summarise this as best I can, as my last thread wasn't
    very to-the-point:
    >
    The C Standard says the following two things:
    >
    * int is the natural integer type for the system.
    * int must be at least 16-Bit.
    You are, perhaps unintentionally , paraphrasing the standard in a way
    that appears to change the meaning. These are not two isolated
    statements, but are in fact combined in one sentence.

    "A ‘‘plain’’ int object has the natural size suggested by the
    architecture of the execution environment (large enough to contain any
    value in the range INT_MIN to INT_MAX as defined in the header
    <limits.h>)."

    If you think about it for a bit, the standard is highlighting the fact
    that the single most important requirement for the int data type is
    meeting or exceeding the range of values specified by those macros.
    The first part of the sentence exists in the context of the
    requirement in parentheses.

    So an int is not just the natural size suggested by the architecture,
    and just also, separately, must be at least 16 bits to meet the range
    requirements.

    The meaning of the standard is that, above all other considerations,
    int must represent a minimum range of values. The type that an
    implementation uses is the natural size, that is perhaps, the "best"
    or "most efficient" type for meeting that primary requirement.
    Now the problem here is that these two criteria conflict if the
    natural type for the system is in fact 8-Bit, which is the case with
    many microcontroller s today.
    One of the things that you might not realize is that the C programming
    language was developed originally on a 16-bit minicomputer. At the
    time Dennis was developing C, there was no such thing as an 8-bit
    microprocessor in existence. Let alone 8-bit microcontroller s which
    evolved after the microprocessor.

    At the time of the first C compilers, I don't think there was an
    architecture, and certainly not a common one, where the natural size
    for an integer type was less than 16 bits.

    Remember as well that the C language was not designed for embedded
    systems in general, let alone for 8-bit devices in particular.

    C was designed as a system programming language for minicomputers on
    up through mainframes and super computers, where 16-bit processors
    where the smallest kids on the block.

    It was a decision by the embedded programming community to adopt C as
    an embedded programming language, not any conspiracy by the "C Mafia"
    or the UNIX zealots to push it on us.

    C is not perfect for embedded use in many ways, even on 16- and 32-bit
    hardware, but it is so vastly superior to all the alternatives that
    most of us have ever seen, there is no contest.

    So we make do with "ANSI standard" compilers that are missing required
    data types and other parts of the language, to get what C does
    provide, namely a simple and standard core language that allows
    efficient code generation for the architectures that we use. Of
    course "efficient" is a relative term.

    If you want to know why we took to C so readily, take a look at some
    of the alternatives. If I never see or write code in PL/M as long as
    I live, it will be too soon. Spend a little time looking into Forth,
    while you're at it.
    As an example, let's take the following code:
    >
    char unsigned x, y;
    ...
    x = y;
    >
    On my microcontroller compiler, this produces different assembler
    depending on whether 'x' is an "unsigned int" or an "unsigned char".
    If it's an "unsigned char", then the assembler is:
    I don't really want to be antagonistic or overly patronizing, but I
    would like you to consider a few other points.

    The first is that you are doing a large amount of preaching based on a
    little experience with exactly one 8-bit architecture, and a severely
    brain-dead one at that. Long before the PIC was developed, there were
    8-bit processors such as the Z80 or 6809 which could handle 16-bit
    ints much better than PIC can.

    But there is another important fact that you seem to be overlooking.
    It is rare, even in 8-bit embedded systems, for an entire application
    to not use any values too large to fit in an unsigned char.

    You have put together a small embedded system as an educational
    experience, either as part of a course or on your own initiative. From
    your description of the hardware on another group, it is a relatively
    simple project that reads a few switches and drives a few LEDs.

    In the real world, most embedded systems have more complex jobs to do,
    even 8-bit ones.

    You are not going to execute a PID control loop using only values in
    the range 0 to 255. Nor would you be able to execute much in the way
    of complex timing calculations.

    The fact that, in your particular 8-bit project, you could do
    everything using only the unsigned char data type is actually quite
    artificial. I may have worked on a few embedded systems over the
    years that never needed anything larger than 16-bit values, but I'm
    fairly sure I never worked on a real world embedded system that never
    needed anything larger than 8 bits.
    MOVF y, W /* Copy y to the accumulator */
    MOVWF x /* Copy the accumulator to x */
    >
    However, if 'x' is an "unsigned int", then the assembler is:
    >
    MOVF y, W /* Copy y to the accumulator */
    MOVWF x /* Copy the accumulator to x */
    MOVF y+1, W /* Copy the next byte of y to the acc */
    MOVWF x+1 /* Copy the acc to the next byte of x */
    >
    Now quite plainly to see, the "int" version takes twice as many
    instructions in this case, and will therefore take exactly twice as
    long to execute, and so will be twice as slow. In other situations,
    the difference is far worse; let's take for example the following
    code:
    Happily, there are 8-bit architectures that have been around more than
    30 years that can handle 16-bit data more efficiently.
    if (condition) x = y;
    >
    Depending on the type of x and y, this produces either:
    >
    MOVF y, W /* Copy y to the accumulator */
    BTFSC condition /* If condition is false, skip the next
    instruction */
    MOVWF x /* Copy the accumulator to x */
    >
    or:
    >
    BTFSS condition /* Skip the next instruction if condition is true
    */
    GOTO There
    MOVF y, W /* Copy y to the accumulator */
    MOVWF x /* Copy the accumulator to x */
    MOVF y+1, W /* Copy the next byte of y to the acc */
    MOVWF x+1 /* Copy the acc to the next byte of x */
    There:
    >
    Not only does the int version consist of more instructions, but it
    also involves a goto which will take up even more time. So basically
    if your microcontroller is running at 8 MHz, then you may aswell
    pretend it's running at 4 MHz or 2 MHz if you're going to be using int
    for doing everyday arithmetic.
    Now we're getting somewhere. "Everyday" arithmetic, indeed. You have
    just discovered that there is often nothing "everyday" about embedded
    systems.
    Now we could go down the road of discussing how C is inadequate in
    terms of its accommodation of microcontroller s, but I'd rather discuss
    ways of "making it right". The reason I'm so eager to bridge the gap
    is that, other than the "int" situation, C is actually great for
    programming an embedded system. I used it in my college project this
    year to program a portable electronic Connect4 game, and it worked
    great!
    Here's where there's a point of view difference between you and many
    in this group, not limited to me. C is not "inadequate " in
    accommodating microcontroller s. No accommodation is required for
    architectures like ARM and PowerPC, and even some of the 16-bit
    architectures.

    On the other hand, C's accommodation for 8-bit hardware can't be
    described as either adequate or inadequate, because there is no C
    accommodation at all for such platforms. Remember again that it was
    the embedded community that decided to adopt C, not the developers of
    C who targeted them.
    One way of making things right is to stop using int for arbitrarily
    storing numbers, and instead use something like ufast8 (the fastest
    integer type that's at least 8-Bit). In this way, neither the
    microcontroller s nor the PC's suffer.
    Actually, you're wrong about the fact that there is no downside to
    such code on a PC.

    To explain what that is, I have to lecture a bit.

    You express a certain amount of indifference, if not disdain, to
    professional programming. I have a feeling that you have little
    understanding of professional programming in particular, and perhaps
    engineering disciplines in general. Especially when it comes to what
    it takes to develop safety critical and other high reliability
    applications.

    Who is going to do the analysis on every integer value used in a
    complex operation to determine whether it will or will not ever exceed
    8 bits? Who is going to write the additional test cases to prove it?
    Examples of a piece of code that could be brought between PC's and
    microcontroller s is something like a look-up table as follows:
    >
    ufast8 days_in_month[12] =
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    >
    To those people out there who are enthusiastic about writing portable
    code, how do you feel about using types such as ufast8 instead of int?
    The problems is that you are not encouraging portable programming so
    much as you are encouraging people who have no relationship to 8- and
    16-bit platforms to write code that might happen to more efficient
    when compiled for small platforms.

    I've never been a programming manager, nor do I want to be, but if I
    were and I saw a programmer making the extra effort to do the analysis
    and testing to do this on desktop code, Windows or Linux or Mac, I
    would correct him for wasting time. And it he was doing it without
    performing the extra analysis and testing, I'd correct him even more
    severely. He'd be wasting time and effort on detail that would have
    absolutely no benefit to the final program.

    Try doing another embedded project, this time with an ARM. ST just
    announced some ARM parts with up to 2MB of flash and 96KB of RAM.

    Or even develop a more realistic and complex application on a PIC.
    stdint.h is great and all, but I find the type names to be too long
    winded. For instance I'd rather write "ufast8" instead of
    "uint_fast8 _t".
    That is an unfortunate attitude. The extended types defined in
    stdint.h are indeed not particularly attractive, but they have the
    advantage of being part of the language standard. They replace the
    great balkanization of type names invented by many others in the years
    before C added them.

    unit_fast8_t is absolutely 100% standard. Every conforming C99
    compiler must define this type in stdint.h. By now, the latest
    versions of most embedded compilers include a stdint.h that defines
    this alias.

    If you were truly interested in portability you would use the types
    that the language instead of inventing your own to suit your
    esthetics.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
    alt.comp.lang.l earn.c-c++

    Comment

    • CBFalconer

      #3
      Re: Portability: Harmony between PC and microcontroller

      Jack Klein wrote:
      >
      .... snip ...
      >
      One of the things that you might not realize is that the C
      programming language was developed originally on a 16-bit
      minicomputer. At the time Dennis was developing C, there was no
      such thing as an 8-bit microprocessor in existence. Let alone
      8-bit microcontroller s which evolved after the microprocessor.
      Cough, hack. Remember the PDP8? :-) Also the Microdata 800
      series, which were less common, and 8 bit oriented. The
      microprogrammed Microdata 810 was a 16 bit (and byte) oriented
      machine. In 1968 as I recall.

      --
      [mail]: Chuck F (cbfalconer at maineline dot net)
      [page]: <http://cbfalconer.home .att.net>
      Try the download section.


      ** Posted from http://www.teranews.com **

      Comment

      • Martin Ambuhl

        #4
        Re: Portability: Harmony between PC and microcontroller

        CBFalconer wrote:
        Jack Klein wrote:
        .... snip ...
        >One of the things that you might not realize is that the C
        >programming language was developed originally on a 16-bit
        >minicomputer . At the time Dennis was developing C, there was no
        >such thing as an 8-bit microprocessor in existence. Let alone
        >8-bit microcontroller s which evolved after the microprocessor.
        >
        Cough, hack. Remember the PDP8? :-)
        Cough, hack. The PDP-8 and PDP-5 were 12 bit machines.

        Comment

        • Bartc

          #5
          Re: Portability: Harmony between PC and microcontroller


          "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
          news:582c24fa-1cc4-49f0-8ca7-171928a1a38e@8g 2000hse.googleg roups.com...
          >
          I'll try to summarise this as best I can, as my last thread wasn't
          very to-the-point:
          >
          The C Standard says the following two things:
          >
          * int is the natural integer type for the system.
          * int must be at least 16-Bit.
          >
          Now the problem here is that these two criteria conflict if the
          natural type for the system is in fact 8-Bit, which is the case with
          many microcontroller s today.
          >
          As an example, let's take the following code:
          >
          char unsigned x, y;
          ...
          x = y;
          It doesn't seem an insurmountable problem.

          If you want a default int size that is best for your cpu, try something
          like:

          typedef unsigned char uint; /* Or uint_fast8_t etc. */
          typedef signed char sint;

          Then use uint and sint everywhere in place of unsigned/signed int.

          When moving to a bigger processor, you need to change those two lines or use
          some conditional compilation tricks.

          --
          Bartc


          Comment

          • =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?=

            #6
            Re: Portability: Harmony between PC and microcontroller


            Thanks for the reply.


            On May 5, 3:42 am, Jack Klein <jackkl...@spam cop.netwrote:
            Try doing another embedded project, this time with an ARM.  ST just
            announced some ARM parts with up to 2MB of flash and 96KB of RAM.

            For my next hobby project, I want to make a very simple two-port
            router. When the router receives a packet, it will look up the IP
            address in its routing table, and then decide what port to forward it
            out on and what destination MAC address to use. That's pretty much all
            it will do. Of course I'll have to make it do a few other things, like
            send and receive ARP requests, but nothing too complicated.

            I started throwing some code together in notepad, just to see how I'd
            make it work. Now the thing is, I see no reason why I shouldn't be
            able to move this code over to a PC. Here's the beginnings of it:

            typedef uint_fast32_t IPv4addr;
            typedef uint_fast64_t MACaddr;

            typedef struct RoutingTableEnt ry {
            IPv4addr addr;
            IPv4addr mask;
            IPv4addr router_addr;
            uint_fast8_t port; /* Here's a great example of where I'd
            normally use "unsigned int" */
            } RoutingTableEnt ry;


            typedef struct InfoForForwardi ng {
            uint_fast8_t port;
            MACaddr dst_mac;
            } InfoForForwardi ng;

            #define LEN_ROUTING_TAB LE 16u
            RoutingTableEnt ry routing_table[LEN_ROUTING_TAB LE]; /* Hold 16
            routes max in the table */
            #define pend_routing_ta ble (routing_table + LEN_ROUTING_TAB LE)

            InfoForForwardi ng GetInfoForForwa rding(IPv4addr const dst_ip)
            {
            InfoForForwardi ng iff = { 0 };

            RoutingTableEnt ry const *p = routing_table;

            do
            {
            if ((dst_ip & p->mask) == p->addr)
            {
            iff.port = p->port;

            /* Now consult ARP table to get MAC address of router */
            iff.dst_mac = GetMACaddr(iff. port,p->router_addr) ;

            return iff;
            }

            } while (pend_routing_t able != ++p);

            return iff;
            }

            As I hope you'll agree from looking at this code, there's nothing
            microcontroller-specific or PC-specific about it. There's no reason
            why the code couldn't be used to make a PC program that would
            implement a "virtual router" between two network cards.

            It appears that quite a few people think that PC programming and
            embedded programming are quite separate from each other, but I hope my
            code example above shows why there's no reason why code can't migrate
            and be portable between the two. Many C programmers already are
            enthusiastic about their code being portable, but I just hope they'd
            consider microcontroller s too.

            Slightly off-topically, I don't know if you've been following my
            thread entitled "Ethernet in its most basic form". I've been asking
            around to see what microcontroller I should use for making my little
            two port router. I've been given many suggestions of microcontroller s
            that will work with one sole ethernet port, but obviously I'll need a
            microcontroller that will work with two. (Or then again I might need
            two microcontroller s that will communicate with each other... ?). I
            don't suppose you'd have any idea what I should use for that? I want
            to work at 100 MBps full-duplex.

            Comment

            • Keith Thompson

              #7
              Re: Portability: Harmony between PC and microcontroller

              "Bartc" <bc@freeuk.comw rites:
              "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
              news:582c24fa-1cc4-49f0-8ca7-171928a1a38e@8g 2000hse.googleg roups.com...
              >>
              >I'll try to summarise this as best I can, as my last thread wasn't
              >very to-the-point:
              >>
              >The C Standard says the following two things:
              >>
              >* int is the natural integer type for the system.
              >* int must be at least 16-Bit.
              >>
              >Now the problem here is that these two criteria conflict if the
              >natural type for the system is in fact 8-Bit, which is the case with
              >many microcontroller s today.
              [...]
              >
              It doesn't seem an insurmountable problem.
              >
              If you want a default int size that is best for your cpu, try something
              like:
              >
              typedef unsigned char uint; /* Or uint_fast8_t etc. */
              typedef signed char sint;
              >
              Then use uint and sint everywhere in place of unsigned/signed int.
              >
              When moving to a bigger processor, you need to change those two lines or use
              some conditional compilation tricks.
              *Please* don't call them "uint" and "sint".

              What the name "uint" says to me is "unsigned int, but I care more
              about saving a few keystrokes than writing clear code"; likewise for
              "sint". The only thing worse than typedef'ing "unsigned int" to
              "uint" is typedef'ing something else to "uint". I understand that
              "uint" is intended to convey "unsigned integer" rather than "unsigned
              int", but that's not how it comes across.

              If you want to call them, say, "small_sign ed" and "small_unsigned ",
              that's fine.

              --
              Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
              Nokia
              "We must do something. This is something. Therefore, we must do this."
              -- Antony Jay and Jonathan Lynn, "Yes Minister"

              Comment

              • CBFalconer

                #8
                Re: Portability: Harmony between PC and microcontroller

                Martin Ambuhl wrote:
                CBFalconer wrote:
                >Jack Klein wrote:
                >.... snip ...
                >>One of the things that you might not realize is that the C
                >>programming language was developed originally on a 16-bit
                >>minicompute r. At the time Dennis was developing C, there was no
                >>such thing as an 8-bit microprocessor in existence. Let alone
                >>8-bit microcontroller s which evolved after the microprocessor.
                >>
                >Cough, hack. Remember the PDP8? :-)
                >
                Cough, hack. The PDP-8 and PDP-5 were 12 bit machines.
                Exactly. Those are not exactly 16 bit minicomputers.

                --
                [mail]: Chuck F (cbfalconer at maineline dot net)
                [page]: <http://cbfalconer.home .att.net>
                Try the download section.


                ** Posted from http://www.teranews.com **

                Comment

                • CBFalconer

                  #9
                  Re: Portability: Harmony between PC and microcontroller

                  Tomás Ó hÉilidhe wrote:
                  Jack Klein <jackkl...@spam cop.netwrote:
                  >
                  >Try doing another embedded project, this time with an ARM. ST just
                  >announced some ARM parts with up to 2MB of flash and 96KB of RAM.
                  >
                  .... snip ...
                  >
                  As I hope you'll agree from looking at this code, there's nothing
                  microcontroller-specific or PC-specific about it. There's no reason
                  why the code couldn't be used to make a PC program that would
                  implement a "virtual router" between two network cards.
                  I suggest you avoid all those peculiar definitions of integral
                  objects. The use of char, short, int, long is normally all you
                  need (unsigned or signed) and doesn't confuse the reader with yards
                  of definitions. C is based on values, not sizes of operands. See
                  limits.h.

                  --
                  [mail]: Chuck F (cbfalconer at maineline dot net)
                  [page]: <http://cbfalconer.home .att.net>
                  Try the download section.


                  ** Posted from http://www.teranews.com **

                  Comment

                  • Chris Dollin

                    #10
                    Re: Portability: Harmony between PC and microcontroller

                    Tomás Ó hÉilidhe wrote:
                    >
                    I'll try to summarise this as best I can, as my last thread wasn't
                    very to-the-point:
                    >
                    The C Standard says the following two things:
                    >
                    * int is the natural integer type for the system.
                    * int must be at least 16-Bit.
                    >
                    Now the problem here is that these two criteria conflict if the
                    natural type for the system is in fact 8-Bit, which is the case with
                    many microcontroller s today.
                    That just means that those microcontroller s aren't a natural fit
                    to C, so programmers writing looks-like-C for them need to be
                    aware that natural-C idioms might not work as nicely.

                    I don't see a problem here.

                    --
                    "It was the first really clever thing the King had /Alice in Wonderland/
                    said that day."

                    Hewlett-Packard Limited registered no:
                    registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

                    Comment

                    • =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?=

                      #11
                      Re: Portability: Harmony between PC and microcontroller

                      On May 6, 12:33 pm, Chris Dollin <chris.dol...@h p.comwrote:
                      That just means that those microcontroller s aren't a natural fit
                      to C, so programmers writing looks-like-C for them need to be
                      aware that natural-C idioms might not work as nicely.

                      This is what I'm against. When I first started programming in C for
                      embedded systems, I was weary of the compiler's compliance to the
                      Standard. I was hesitant to rely on rules from the Standard when it
                      came to things like:
                      * Minimum size of integer types
                      * Behaviour of overflow
                      * Existance and usage of a stack

                      Having written a fully working program though in C for embedded
                      systems, and also having looked at the assembler produced to check
                      what it's actually doing, I've seen that my embedded compile is
                      extremely compliant. I defined an object as "long unsigned", and lo
                      and behold the assembler produced used four bytes to store it (even
                      though it can only do arithmetic on 8-Bit numbers).

                      I don't see a problem here.

                      The problem comes with writing portable code. For instance, I'm
                      currently writing code to implement an internet protocol router. The
                      code show be able to run on both a microcontroller and on a PC.
                      However, if the code uses "int" then the code will be less efficient
                      on a microcontroller . And if it uses "char" then the code will be less
                      efficient on a PC. Usage of uint_fast8_t would produce optimal
                      assembler for both systems.

                      There's no reason why there has to be an "embedded version of C"
                      distinct from "Standard C".

                      Comment

                      • Chris Dollin

                        #12
                        Re: Portability: Harmony between PC and microcontroller

                        Tomás Ó hÉilidhe wrote:
                        On May 6, 12:33 pm, Chris Dollin <chris.dol...@h p.comwrote:
                        >
                        >That just means that those microcontroller s aren't a natural fit
                        >to C, so programmers writing looks-like-C for them need to be
                        >aware that natural-C idioms might not work as nicely.
                        >
                        >
                        This is what I'm against. When I first started programming in C for
                        embedded systems, I was weary of the compiler's compliance to the
                        Standard. I was hesitant to rely on rules from the Standard when it
                        came to things like:
                        * Minimum size of integer types
                        * Behaviour of overflow
                        * Existance and usage of a stack
                        >
                        Having written a fully working program though in C for embedded
                        systems, and also having looked at the assembler produced to check
                        what it's actually doing, I've seen that my embedded compile is
                        extremely compliant. I defined an object as "long unsigned", and lo
                        and behold the assembler produced used four bytes to store it (even
                        though it can only do arithmetic on 8-Bit numbers).
                        >
                        >
                        >I don't see a problem here.
                        >
                        >
                        The problem comes with writing portable code.
                        No, it doesn't. Not if the compiler conforms to the standard.
                        For instance, I'm
                        currently writing code to implement an internet protocol router. The
                        code show be able to run on both a microcontroller and on a PC.
                        However, if the code uses "int" then the code will be less efficient
                        on a microcontroller .
                        Your problem is not with portability; it's with performance.
                        Different platforms can have differing performance profiles
                        at whim, and portable code may need tweaking for best performance
                        on /any/ of them. Singling out performance issues on 8-bit
                        micros and thinking everyone should write code so that it
                        (by /hypothesis/) performs equally (well, badly) on those
                        implementations is, I think, obsession over microefficiency .

                        --
                        "The one you're playing, I think." /The Lion Game/

                        Hewlett-Packard Limited Cain Road, Bracknell, registered no:
                        registered office: Berks RG12 1HN 690597 England

                        Comment

                        • =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?=

                          #13
                          Re: Portability: Harmony between PC and microcontroller

                          On May 6, 1:40 pm, Chris Dollin <chris.dol...@h p.comwrote:
                          Your problem is not with portability; it's with performance.

                          They can be one in the same thing if the performance affects the
                          usability of the product. If I port a web browser to a Nintendo gaming
                          console, is it really a succesful port if it takes seven minutes to
                          load a webpage? I don't think it is.

                          Different platforms can have differing performance profiles
                          at whim, and portable code may need tweaking for best performance
                          on /any/ of them.

                          Yes but there are more fundamental concepts here, that is, the choice
                          of integer types, whether to use 1, 2, or 4 bytes to store a number.

                          You say that different platforms have differing performance profiles,
                          and you're right. What gets better performance on one system might
                          result in poorer performance on another. But let me draw a crude
                          analogy:

                          Let's say you have a farm, and you want to get the best performance
                          out of all your animals. For the sheep, you might give them a field of
                          nice thick grass. For the young chicks, you might keep them in a
                          heated enclosure. For the horses, you might give them a vast open
                          space to run around. But there'a more fundamental way of getting
                          better performance out of all your animals -- give them water.

                          Just as water is a common thing to all animals, integer types are
                          common to all computers. Before you bother doing specialised things
                          for each animal such as giving them more grass or more space, do the
                          universal thing first: water.

                          And for computers, this universal thing is the choice of integer
                          types. You can have the best optimiser in the world, but it can only
                          do so good if you're using sub-optimal integer types.

                          on 8-bit
                          micros and thinking everyone should write code so that it
                          (by /hypothesis/) performs equally (well, badly) on those
                          implementations is, I think, obsession over microefficiency .

                          Firstly, zero effort would go into making it perform equally well on
                          both systems. It's just a matter of getting into the habit of using
                          uint_fast8_t instead of unsigned int where possible.

                          For my current embedded project, if I were to change "uint_fast8 _t"
                          from "unsigned char" to "unsigned int", then I bet I'd see flicker in
                          my display (because the microcontroller can't flash the display fast
                          enough so that the human eye can't see the flashing). I've already
                          submitted my project board to my college to be graded but I should be
                          getting it back tomorrow. I'll try it out changing the integer types
                          and see if the display flickers. If it does, then I'll have to reduce
                          the duration of each flash, which will result in a dimmer display.

                          Comment

                          • soscpd@terra.com.br

                            #14
                            Re: Portability: Harmony between PC and microcontroller

                            On May 6, 9:06 am, Tomás Ó hÉilidhe <t...@lavabit.c omwrote:
                            They can be one in the same thing if the performance affects the
                            usability of the product. If I port a web browser to a Nintendo gaming
                            console, is it really a succesful port if it takes seven minutes to
                            load a webpage? I don't think it is.
                            Did it load? Yes? Then, it is. Don't think a nintendo (hey... some
                            nintendo can work very fine here... :) hardware was designed to work
                            as a http daemon (maybe that is not the product!). Performance isn't
                            100% hardware and, isn't too, 100% code. Run a vanilla 2.4 kernel in a
                            dual xeon with 1Tb memory, and run the same in a 286 with 1Mb RAM. Do
                            you really expect code tuning, best practices or hacks to make both
                            run, at least close to each other?

                            Did you pick the wrong language or the wrong hardware (haven't you
                            picked C? haven't you picked the 8 bit platform? Why mix them if you
                            think that will not work?)? That is the question I think you must
                            answer before post C standards or limits as the source of your
                            problems. The right tools Tomás. The right tools.


                            Regards
                            Rafael

                            Comment

                            • =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?=

                              #15
                              Re: Portability: Harmony between PC and microcontroller

                              On May 6, 3:32 pm, "sos...@terra.c om.br" <sos...@terra.c om.brwrote:
                              On May 6, 9:06 am, Tomás Ó hÉilidhe <t...@lavabit.c omwrote:
                              >
                              They can be one in the same thing if the performance affects the
                              usability of the product. If I port a web browser to a Nintendo gaming
                              console, is it really a succesful port if it takes seven minutes to
                              load a webpage? I don't think it is.
                              >
                              Did it load? Yes? Then, it is.

                              I'd love to actually have to take a trial of it. I'd love to have you
                              sit down in a room with a desk and a chair and my machine running the
                              ported webbrowser. I'd love to see you type in "google.ie" and wait 7
                              minutes for it to load.

                              I'd lose the plot if I had to wait one minute for a page to load, let
                              alone seven.

                              Don't think a nintendo (hey... some
                              nintendo can work very fine here... :) hardware was designed to work
                              as a http daemon (maybe that is not the product!).

                              Nintendo was an arbitrary choice on my part by the way.
                              (Also, the "daemon" is the program that runs on the server, not the
                              client. The daemon listens on a port number, e.g. port 80 for HTTP,
                              and processes requests to that port number).

                              Performance isn't
                              100% hardware and, isn't too, 100% code. Run a vanilla 2.4 kernel in a
                              dual xeon with 1Tb memory, and run the same in a 286 with 1Mb RAM. Do
                              you really expect code tuning, best practices or hacks to make both
                              run, at least close to each other?

                              I'm talking about getting optimal performance out of every system,
                              whether it runs at 31 kHz or 3.6 Ghz.

                              Did you pick the wrong language or the wrong hardware (haven't you
                              picked C? haven't you picked the 8 bit platform? Why mix them if you
                              think that will not work?)?

                              They work great if used properly.

                              That is the question I think you must
                              answer before post C standards or limits as the source of your
                              problems. The right tools Tomás. The right tools.

                              I'm not talking about changing tools, or even about critiquing the C
                              language. I'm talking about adopting a habit of using the likes of
                              uint_fast8_t instead of int, because it will lead to faster code on
                              every conceivable platform.

                              Comment

                              Working...