EmbeddedRelated.com
Forums
Memfault State of IoT Report

bit names in CMSIS

Started by Tim Mitchell March 2, 2012
Hi Phil,

I am writing my first embedded C++ project right now and noticed your
comment below. I've programmed a good bit of C++ in Windows and Linux,
but this is my first for a microprocessor.

Are there some papers or websites with pointers on using C++ in embedded
projects that you can recommend? I've read various articles on it but
seeing that you are using C++ regularly I bet you know some good sources
to help me get started. I'm using GCC with an LPC1752.

Thanks,
Moses

On 03/02/2012 08:32 AM, Phil Young wrote:

> Since I write all of my code in C++ this is even more relevant since I have

An Engineer's Guide to the LPC2100 Series

Hi Moses,

I can't point to any specific books for this I'm afraid, but it's really not
that much different to writing in C, except there are a few things to be
wary about.

Since this is a topic on CMSIS I won't pollute it further by going off
topic, but if you want to open a separate topic on using C++ then I'm sure
there are many of us who can contribute our specific experiences and tips.

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
Moses McKnight
Sent: 02 March 2012 15:48
To: l...
Subject: Re: [lpc2000] bit names in CMSIS

Hi Phil,

I am writing my first embedded C++ project right now and noticed your
comment below. I've programmed a good bit of C++ in Windows and Linux,
but this is my first for a microprocessor.

Are there some papers or websites with pointers on using C++ in embedded
projects that you can recommend? I've read various articles on it but
seeing that you are using C++ regularly I bet you know some good sources
to help me get started. I'm using GCC with an LPC1752.

Thanks,
Moses

On 03/02/2012 08:32 AM, Phil Young wrote:

> Since I write all of my code in C++ this is even more relevant since I
have




Thanks for the note Phil. I meant to change the title of the last post
but forgot before I hit send.

So, any tips on using C++ for embedded projects would be appreciated.
I've heard numbers of things, some contradictory.

Some people say don't do any dynamic allocation, some some to use it
except for the most safety critical stuff.

One person mentioned using templates for memory reduction - how does
that work?

Other than no exceptions and rtti, are there any other things I can do
to keep flash and RAM usage down?

Any particular GCC settings to use?

Thanks in advance for any tips.
Moses

On 03/02/2012 10:19 AM, Phil Young wrote:
> Hi Moses,
>
> I can't point to any specific books for this I'm afraid, but it's really not
> that much different to writing in C, except there are a few things to be
> wary about.
>
> Since this is a topic on CMSIS I won't pollute it further by going off
> topic, but if you want to open a separate topic on using C++ then I'm sure
> there are many of us who can contribute our specific experiences and tips.
>
> Regards
>
> Phil.
>
> From: l... [mailto:l...] On Behalf Of
> Moses McKnight
> Sent: 02 March 2012 15:48
> To: l...
> Subject: Re: [lpc2000] bit names in CMSIS
>
> Hi Phil,
>
> I am writing my first embedded C++ project right now and noticed your
> comment below. I've programmed a good bit of C++ in Windows and Linux,
> but this is my first for a microprocessor.
>
> Are there some papers or websites with pointers on using C++ in embedded
> projects that you can recommend? I've read various articles on it but
> seeing that you are using C++ regularly I bet you know some good sources
> to help me get started. I'm using GCC with an LPC1752.
>
> Thanks,
> Moses
>
> On 03/02/2012 08:32 AM, Phil Young wrote:
>
>> Since I write all of my code in C++ this is even more relevant since I
> have
>
There are a number of things, and it depends on which core you are using.

Some cores have specific instructions that can make use of signed bitfields
for example, e..g. M3 / M4 variants, others don't.

Generally there are tool specific dependencies also, e.g with the MDK tools
you should avoid having any constructors defined for anything which is
statically instantiated because the ARM init code will build a list of
objects to destroy as they are constructed, including static objects. This
causes malloc to be called and requires the heap size to be adjusted
accordingly, wasting precious memory storing lists of what to destroy on
exit.

I try to avoid using any of the standard library components and start by
defining my own stream based IO with just the operators I need.

I actually find that once these startup issues have been eliminated C++ code
is generally smaller and more efficient, this is probably due to the
efficiency of addressing.

A good point with C++ classes is that you tend to define them to group
related data and operations, this means that there is a higher likelihood of
all required data being within range of a short immediate offset from
'this', and as this offset is known at compile time the compiler can use
more optimized addressing.

As a rule I would try to avoid using virtual functions where possible, the
overhead of calling a virtual function also varies depending on the core,
since the branch range is larger on M3 than M0, but typically there is a 6+
cycle overhead and 2-3 more instructions for a virtual function call.

Be careful when overloading operators, it's all too easy to invoke a copy
constructor without meaning to, on a PC you generally won't notice this but
in an embedded target you will, so be sure to pass operands as const &
where possible.

RTTI is definitely a bad idea, and the comment about Templates makes no
sense, I suspect that was a misunderstanding of how templates are
implemented.

Dynamic allocation comes in 2 flavours, there is explicit allocation using
new / delete which occurs on the heap and implicit allocation which is on
the stack.

generally allocation is just a case of the compiler calling malloc and then
the constructor, if you don't define the constructors then it's no different
to using C anyway.

Implicit allocation also occurs when a copy constructor is required if an
object is passed to an operator, this happens when you forget to make the
operand const &, this can really hit performance but can be avoided by
correct coding.

For simple objects, if you require a copy constructor it's often better to
define your own rather than have the compiler insert a call to memcpy.

If you avoid having constructors for static objects then you will actually
eliminate a huge amount of startup and runtime overhead, reducing it to just
the same overhead as with any normal C program, and since C++ is derived
from C you will find that there is no real difference to using C++ in an
embedded target except for the efficiencies that come from the coding style.

That's all I can think of at the moment.

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
Moses McKnight
Sent: 02 March 2012 16:53
To: l...
Subject: [lpc2000] Embedded C++ tips

Thanks for the note Phil. I meant to change the title of the last post
but forgot before I hit send.

So, any tips on using C++ for embedded projects would be appreciated.
I've heard numbers of things, some contradictory.

Some people say don't do any dynamic allocation, some some to use it
except for the most safety critical stuff.

One person mentioned using templates for memory reduction - how does
that work?

Other than no exceptions and rtti, are there any other things I can do
to keep flash and RAM usage down?

Any particular GCC settings to use?

Thanks in advance for any tips.
Moses

On 03/02/2012 10:19 AM, Phil Young wrote:
> Hi Moses,
>
> I can't point to any specific books for this I'm afraid, but it's really
not
> that much different to writing in C, except there are a few things to be
> wary about.
>
> Since this is a topic on CMSIS I won't pollute it further by going off
> topic, but if you want to open a separate topic on using C++ then I'm sure
> there are many of us who can contribute our specific experiences and tips.
>
> Regards
>
> Phil.
>
> From: l...
[mailto:l... ] On
Behalf Of
> Moses McKnight
> Sent: 02 March 2012 15:48
> To: l...
> Subject: Re: [lpc2000] bit names in CMSIS
>
> Hi Phil,
>
> I am writing my first embedded C++ project right now and noticed your
> comment below. I've programmed a good bit of C++ in Windows and Linux,
> but this is my first for a microprocessor.
>
> Are there some papers or websites with pointers on using C++ in embedded
> projects that you can recommend? I've read various articles on it but
> seeing that you are using C++ regularly I bet you know some good sources
> to help me get started. I'm using GCC with an LPC1752.
>
> Thanks,
> Moses
>
> On 03/02/2012 08:32 AM, Phil Young wrote:
>
>> Since I write all of my code in C++ this is even more relevant since I
> have
>



> So, any tips on using C++ for embedded projects would be appreciated.
> I've heard numbers of things, some contradictory.

Embedded as such is not the point. Memory and timing constraints
(especially hard real-time requirements) are. Depending on whether and
to what extent they apply to your case determine which advices are
correct. Programing an LPC1114 (8K Flash, 2K RAM) is not the same as
programming a Linux system, yet both can be used in embedded systems.

My main focus is C++ on 32-bit microcontrollers, whith real-time
constraints. In THAT case I would say

> Some people say don't do any dynamic allocation, some some to use it
> except for the most safety critical stuff.

Dynamic allocation is fine, but deallocation is not. Allocate-only can
be done with a simple (almost zero-time) stack-wise allocation, and will
probably be done in the startup only.

> One person mentioned using templates for memory reduction - how does
> that work?

Can't comment on that without specifics.

> Other than no exceptions and rtti, are there any other things I can do
> to keep flash and RAM usage down?

Avoid all standard libraries, including (sadly) cout.

> Any particular GCC settings to use?

optimize, but often for size, not speed -Os
-fno-rtto -fno-exceptions
-ffunction-sections -fdata-sections (also when linking)
-nostartupfiles (I make my own)

--

Wouter van Ooijen

-- -------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
C++ on uC blog: http://www.voti.nl/erblog

Thanks Phil and Wouter.

On 03/02/2012 01:22 PM, Wouter van Ooijen wrote:
>> So, any tips on using C++ for embedded projects would be appreciated.
>> I've heard numbers of things, some contradictory.
>
> Embedded as such is not the point. Memory and timing constraints
> (especially hard real-time requirements) are. Depending on whether and
> to what extent they apply to your case determine which advices are
> correct. Programing an LPC1114 (8K Flash, 2K RAM) is not the same as
> programming a Linux system, yet both can be used in embedded systems.
>
> My main focus is C++ on 32-bit microcontrollers, whith real-time
> constraints. In THAT case I would say

I'm using an LPC1752 for this project - 64k flash, 16k ram, with USB.

>> Some people say don't do any dynamic allocation, some some to use it
>> except for the most safety critical stuff.
>
> Dynamic allocation is fine, but deallocation is not. Allocate-only can
> be done with a simple (almost zero-time) stack-wise allocation, and will
> probably be done in the startup only.

I'm curious what is wrong with deallocation?

>> One person mentioned using templates for memory reduction - how does
>> that work?
>
> Can't comment on that without specifics.

I don't remember for certain the context I saw that mention, but I'm
thinking the person might have been using templates instead of subclassing?

>> Other than no exceptions and rtti, are there any other things I can do
>> to keep flash and RAM usage down?
>
> Avoid all standard libraries, including (sadly) cout.
>
>> Any particular GCC settings to use?
>
> optimize, but often for size, not speed -Os
> -fno-rtto -fno-exceptions
> -ffunction-sections -fdata-sections (also when linking)
> -nostartupfiles (I make my own)

Ok, the -nostartupfiles interests me. How do you make your own? I just
found (again) your articles on http://www.embeddedrelated.com about c++
on microcontrollers, so I'm reading those and I'll check the sample code
to see if you have startup files in there. I tried using
-nostartupfiles and got errors when compiling or linking before.

Thanks for the information. Exactly the kind of stuff I need.

Moses
De-allocation is a more complex task in most memory management systems since
the 'free' routine (at some point ) attempts to unify smaller contiguous
fragments into larger more useful fragments in order to prevent complete
memory fragmentation from occurring.
Of course the complexity of this also depends on how complex malloc is, but
generally the simpler the malloc routine, the more work left for free to do
when returning memory to the heap.
In general you want malloc to be fast so that your program isn't slowed
down, but often it is possible to free unused memory later when the system
is less busy, although be careful not to get to the point where you get
memory starvation or you will end up with the slowdowns that are typical for
Basic / Java when running garbage collection.

I do occasionally dynamically allocate memory in embedded systems, but I
usually do this by writing a pool manager for the class that I want to
allocate, then I allocate a small pool of blocks to that class and re-use
that pool rather than calling free when a block is finished with.
Of course this can mean a small increase in memory requirement but it means
that freeing blocks can be as fast as allocating them since I just keep a
linked list of blocks for the class.

For Startup files there are a few things that need to be done, depending on
the toolchain since GNU handles things very differently to the ARM
compilers, although the MDK provide all the required startup for you anyway.

Basic tasks for starting an embedded system are listed below, these may be
done in different orders depending on the toolchain.
Intialize stack and heap
Zero memory
Initialize memory manager (if required)
Relocate any code sections as necessary
Initialize global initialized variables
Call constructors
Initialize vector table
Jump to main
The order often changes, but generally there are a few dependancies to watch
out for, it is necessary to have stack and usually also the heap initialized
before calling constructors (since they may call malloc, although for static
global objects malloc is not required to instantiate them since their
location is assigned by the linker).

If you don't call malloc / free then you can even get away with no heap,
provided it is not required by any libraries you call, or in the case of the
MDK it may be required if you have defined destructors for global objects or
use semihosting.

Regards

Phil.

-----Original Message-----
From: l... [mailto:l...] On Behalf Of
Moses McKnight
Sent: 02 March 2012 20:52
To: l...
Subject: Re: [lpc2000] Embedded C++ tips

Thanks Phil and Wouter.

On 03/02/2012 01:22 PM, Wouter van Ooijen wrote:
>> So, any tips on using C++ for embedded projects would be appreciated.
>> I've heard numbers of things, some contradictory.
>
> Embedded as such is not the point. Memory and timing constraints
> (especially hard real-time requirements) are. Depending on whether and
> to what extent they apply to your case determine which advices are
> correct. Programing an LPC1114 (8K Flash, 2K RAM) is not the same as
> programming a Linux system, yet both can be used in embedded systems.
>
> My main focus is C++ on 32-bit microcontrollers, whith real-time
> constraints. In THAT case I would say

I'm using an LPC1752 for this project - 64k flash, 16k ram, with USB.

>> Some people say don't do any dynamic allocation, some some to use it
>> except for the most safety critical stuff.
>
> Dynamic allocation is fine, but deallocation is not. Allocate-only can
> be done with a simple (almost zero-time) stack-wise allocation, and
> will probably be done in the startup only.

I'm curious what is wrong with deallocation?

>> One person mentioned using templates for memory reduction - how does
>> that work?
>
> Can't comment on that without specifics.

I don't remember for certain the context I saw that mention, but I'm
thinking the person might have been using templates instead of subclassing?

>> Other than no exceptions and rtti, are there any other things I can
>> do to keep flash and RAM usage down?
>
> Avoid all standard libraries, including (sadly) cout.
>
>> Any particular GCC settings to use?
>
> optimize, but often for size, not speed -Os -fno-rtto -fno-exceptions
> -ffunction-sections -fdata-sections (also when linking)
> -nostartupfiles (I make my own)

Ok, the -nostartupfiles interests me. How do you make your own? I just
found (again) your articles on http://www.embeddedrelated.com about c++ on
microcontrollers, so I'm reading those and I'll check the sample code to see
if you have startup files in there. I tried using -nostartupfiles and got
errors when compiling or linking before.

Thanks for the information. Exactly the kind of stuff I need.

Moses
> I'm using an LPC1752 for this project - 64k flash, 16k ram, with USB.

But more important is the type of application. Controlling an airbag is
very different from a home automation console (airbag == very stringent
timeing requirements, no user interface; console = exactly the opposite).

> I'm curious what is wrong with deallocation?

The combination of allocation and deallocation leads to a non-trivial
heap management. The trouble is that the malloc (or free) call does not
have a fixed (or even bounded) execution time, which does not match well
with real-time constraints. The combination is the trouble, dwallocation
without alocation makes no sense, so allocation-only is the viable
trouble-free choice, which sort-of makes deallocation the bad guy.

As Phil Young stated: allocation + deallocation is no problem, provided
that the memory chunks you allocate and deallocate are all the same
size. This can be done (within C++) with custom memory management for a
specific class.

> I don't remember for certain the context I saw that mention, but I'm
> thinking the person might have been using templates instead of subclassing?

Both are useful. Templates can be used instead of inheritance in some
cases (especially to avoid the heavy base class syndrome), but that is a
normal C++ programing technique, not something specific to
resource-constrained systems.

> Ok, the -nostartupfiles interests me. How do you make your own?

Steal what you need from an existing startup file and delete the rest.
This of course requires that you know what is required in the first place!

> I tried using
> -nostartupfiles and got errors when compiling or linking before.

You must provide some startup yourself. Cortex is nice in this aspect
because both PC and SP are loaded automatically, so the startup code can
be in C/C++ (provided that you know what you are doing). ARM loaded PC
only, so you needed assembler to load the SP.

--

Wouter van Ooijen

-- -------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
C++ on uC blog: http://www.voti.nl/erblog

Hi,

> The combination of allocation and deallocation leads to a non-trivial
> heap management. The trouble is that the malloc (or free) call does not
> have a fixed (or even bounded) execution time, which does not match well
> with real-time constraints.

Well-known buddy heaps have bounded performance. Binary buddy heaps are a great way to go for bounded time, if you can deal with fragmentation issues.

> As Phil Young stated: allocation + deallocation is no problem, provided
> that the memory chunks you allocate and deallocate are all the same
> size. This can be done (within C++) with custom memory management for a
> specific class.

Deallocation of same-size blocks is O(1)--nice, but uninteresting. Deallocation in a buddy heap can be made to be effectively O(1) for small memory embedded systems. The nice thing about buddy allocators is that they are small, fast, provide reasonable memory management, and coalescing on deallocation is fast.

Other real-time O(1) allocators exist, but they start to trade coding simplicity:

http://www.gii.upv.es/tlsf/
http://tlsf.baisoku.org/

-- Paul.

> Deallocation of same-size blocks is O(1)--nice, but uninteresting.

For systems with strict real-time requirements O(1) is very interesting,
especially when the constant factor is small.

> Deallocation in a buddy heap can be made to be effectively O(1)
> for small memory embedded systems.

A heap can have is use in embedded systems, but IMO not in systems with
strict timing constraints, high reliability, and (very) small memory.
Some more arguments (which every one has to evaluate for himself against
his particular system):

- fragmentation: it is very unfortunate when a system works now (during
test), but fails due to some specific pattern of allocation and
deallocation (which of course happens only in the field..).

- memory leaks and dead pointers: programmers are bad at correctly
freeing memory, especially in exceptional situations. on the other side,
programmers sometimes use memory after they have free'd it. Both types
of errors are hard to test and debug (although filling freed memory with
DEAD BEEF is a good start).

- (un)predictability: for verifying timing requirements
history-dependent execution time (of malloc and/or free) can be a nightmare.

--

Wouter van Ooijen

-- -------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
C++ on uC blog: http://www.voti.nl/erblog


Memfault State of IoT Report