C++ usage in embedded systems

后端 未结 17 1498
南旧
南旧 2021-01-30 22:45

What features of C++ should be avoided in embedded systems?

Please classify the answer by reason such as:

  • memory usage
  • code size
  • speed<
相关标签:
17条回答
  • 2021-01-30 23:04

    Using an ARM7 and assuming you don't have an external MMU, dynamic memory allocation problems can be harder to debug. I'd add "judicious use of new / delete / free / malloc" to the list of guidelines.

    0 讨论(0)
  • 2021-01-30 23:05

    Regarding code bloat, I think the culprit is much more likely to be inline than templates.

    For example:

    // foo.h
    template <typename T> void foo () { /* some relatively large definition */ }
    
    // b1.cc
    #include "foo.h"
    void b1 () { foo<int> (); }
    
    // b2.cc
    #include "foo.h"
    void b2 () { foo<int> (); }
    
    // b3.cc
    #include "foo.h"
    void b3 () { foo<int> (); }
    

    The linker most likely will merge all the definitions of 'foo' into a single translation unit. Therefore the size of 'foo' is no different to that of any other namespace function.

    If your linker doesn't do this, then you can use an explicit instantiation to do that for you:

    // foo.h
    template <typename T> void foo ();
    
    // foo.cc
    #include "foo.h"
    template <typename T> void foo () { /* some relatively large definition */ }
    template void foo<int> ();        // Definition of 'foo<int>' only in this TU
    
    // b1.cc
    #include "foo.h"
    void b1 () { foo<int> (); }
    
    // b2.cc
    #include "foo.h"
    void b2 () { foo<int> (); }
    
    // b3.cc
    #include "foo.h"
    void b3 () { foo<int> (); }
    

    Now consider the following:

    // foo.h
    inline void foo () { /* some relatively large definition */ }
    
    // b1.cc
    #include "foo.h"
    void b1 () { foo (); }
    
    // b2.cc
    #include "foo.h"
    void b2 () { foo (); }
    
    // b3.cc
    #include "foo.h"
    void b3 () { foo (); }
    

    If the compiler decides to inline 'foo' for you then you will end up with 3 different copies of 'foo'. No templates in sight!

    EDIT: From a comment above from InSciTek Jeff

    Using explicit instantiations for the functions that you know will be used only, you can also ensure that all unused functions are removed (which may actually reduce the code size compared with the non template case):

    // a.h
    template <typename T>
    class A
    {
    public:
      void f1(); // will be called 
      void f2(); // will be called 
      void f3(); // is never called
    }
    
    
    // a.cc
    #include "a.h"
    
    template <typename T>
    void A<T>::f1 () { /* ... */ }
    
    template <typename T>
    void A<T>::f2 () { /* ... */ }
    
    template <typename T>
    void A<T>::f3 () { /* ... */ }
    
    template void A<int>::f1 ();
    template void A<int>::f2 ();
    

    Unless your tool chain is completely broken, the above will generate code only for 'f1' and 'f2'.

    0 讨论(0)
  • 2021-01-30 23:08

    Having used both the GCC ARM compiler and the ARM's own SDT I'd have the following comments:

    • The ARM SDT produces tighter, faster code but is very expensive (>Eur5k per seat!). At my previous job we used this compiler and it was ok.

    • The GCC ARM tools works very well though and it's what I use on my own projects (GBA/DS).

    • Use 'thumb' mode as this reduces code size significantly. On 16 bit bus variants of the ARM (such as the GBA) there is also a speed advantage.

    • 64k is seriously small for C++ development. I'd use C & Assembler in that environment.

    On such a small platform you'll have to be careful of stack usage. Avoid recursion, large automatic (local) data structures etc. Heap usage will also be an issue (new, malloc etc). C will give you more control of these issues.

    0 讨论(0)
  • 2021-01-30 23:13

    One particular problem that surprised me with ATMega GCC 3.something: when I added a virtual ember function to one of my classes, I had to add a virtual destructor. At that point, the linker asked for operator delete(void *). I have no idea why that happens, and adding an empty definition for that operator slolved the problem.

    0 讨论(0)
  • 2021-01-30 23:14

    RTTI and Exception Handling:

    • Increases code-size
    • Decreases performance
    • Can often be replaced by cheaper mechanisms or a better software-design.

    Templates:

    • be careful with them if code-size is an issue. If your target CPU has no or only a very tiny ínstruction cache it may reduce the performance as well. (templates tend to bloat code if used without care). Otoh clever meta-programming can decrease the code-size as well. There is no clear cut answer on his.

    Virtual functions and inheritance:

    • These are fine for me. I write almost all of my embedded code in C. That does not stop me from using function-pointer tables to mimic virtual functions. They never became a peformance problem.
    0 讨论(0)
  • 2021-01-30 23:14

    I wouldn't have said there's a hard and fast rule to this; it depends a lot on your application. Embedded systems are typically:

    • More constrained in the amount of memory they have available
    • Often run on slower hardware
    • Tend to be closer to hardware i.e. driving it in some way like fiddling with register settings.

    Just like any other development though, you should balance all of the points you've mentioned against the requirements you were given / derived.

    0 讨论(0)
提交回复
热议问题