Académique Documents
Professionnel Documents
Culture Documents
Bjarne Stroustrup
www.stroustrup.com/Programming
Abstract
This lecture provides a brief overview of what distinguishes embedded systems programming from ordinary programming. It then touches upon facilities that become prominent or problems when working close to the hardware such as free store use, bit manipulation, and coding standards. Remember: not all computers are little grey boxes hiding under desks in offices.
Stroustrup/Programming 2
Overview
Resource management
Access to hardware
Coding standards
Stroustrup/Programming
Embedded systems
correctness is not an abstract concept but I assumed that the hardware worked correctly is no excuse
Over a long time and over a large range of conditions, it simply doesnt
Stroustrup/Programming
Embedded systems
That usually doesnt look like a computer That usually controls physical devices Critical as in if the system fails someone might die
Often resources (memory, processor capacity) are limited Often real-time response is essential
Stroustrup/Programming 5
Embedded systems
Assembly line quality monitors Bar code readers Bread machines Cameras Car assembly robots Cell phones Centrifuge controllers CD players Disk drive controllers Smart card processors
Fuel injector controls Medical equipment monitors PDAs Printer controllers Sound systems Rice cookers Telephone switches Water pump controllers Welding machines Windmills Wrist watches
Stroustrup/Programming
Computer Engineers You will build and oversee the building of these systems
All close to he hardware code resembles this The concern for correctness and predictability of embedded systems code is simply a more critical form of what we want for all code
Electrical Engineers You will build and oversee the building of these systems.
You have to work with the computer guys You have to be able to talk to them You may have to teach them You may have to take over for them
Computer scientists youll know to do this or only work on web applications (and the like)
Stroustrup/Programming 7
Predictability
E.g., you can simply measure the time for an add operation or a virtual function call and thatll be the cost of every such add operation and every virtual function call (pipelining, caching, implicit concurrency makes this somewhat trickier on some modern processors)
Free store allocation (new) Exception throw
Ideals/aims
Dont write glorified assembler code Represent your ideas directly in code
As always, try to write the clearest, cleanest, most maintainable code Dont optimize until you have to
People far too often optimize prematurely John Bentley's rules for optimization
First law: Dont do it Second law (for experts only): Dont do it yet
Stroustrup/Programming
You (usually) have to be much more aware of the resources consumed in embedded systems programming than you have to in ordinary programs
Time Space Communication channels Files ROM (Read-Only Memory) Flash memory
You must take the time to learn about the way your language features are implemented for a particular platform
Looking at specialized features of an RTOS (Real Time Operating System) Using a Non-hosted environment (thats one way of saying a language right on top of hardware without an operating system) Involving (sometimes complex) device driver architectures Dealing directly with hardware device interfaces Thats what specific courses and manuals are for
Stroustrup/Programming
11
New object
Allocation delays
The effort needed to find a new free chunk of memory of a given size depends on what has already been allocated
Fragmentation
If you have a hole (free space) of size N and you allocate an object of size M where M<N in it, you now have a fragment of size N-M to deal with After a while, such fragments constitute much of the memory
Stroustrup/Programming 12
Solution: pre-allocate
Stack:
Global objects
Stacks
Pool:
And no malloc() (memory allocation during runtime) either (for those of you who speak C)
Define (or borrow) fixed-sized Pools Define (or borrow) fixed-sized Stacks
Stroustrup/Programming
14
Pool example
// Note: element type known at compile time // allocation times are completely predictable (and short) // the user has to pre-calculate the maximum number of elements needed template<class T, int N>class Pool { public: Pool(); // make pool of N Ts construct pools only during startup T* get(); // get a T from the pool; return 0 if no free Ts void free(T*); // return a T given out by get() to the pool private: // keep track of T[N] array (e.g., a list of free objects) }; Pool<Small_buffer,10> sb_pool; Pool<Status_indicator,200> indicator_pool;
Stroustrup/Programming 15
Stack example
// Note: allocation times completely predictable (and short) // the user has to pre-calculate the maximum number of elements needed template<int N>class Stack { public: Stack(); // make an N byte stack construct stacks only during startup void* get(int N); // allocate n bytes from the stack; return 0 if no free space void free(void* p); // return the last block returned by get() to the stack private: // keep track of an array of N bytes (e.g. a top of stack pointer) }; Stack<50*1024> my_free_store; // 50K worth of storage to be used as a stack void* pv1 = my_free_store.get(1024); int* pi = static_cast<int*>(pv1); // you have to convert memory to objects void* pv2 = my_free_store.get(50); Pump_driver* pdriver = static_cast<Pump_driver*>(pv2);
Stroustrup/Programming 16
Templates
Stroustrup/Programming
17
Failing how?
In general, we cannot know In practice, we can assume that some kinds of errors are more common than others
Why?
Power surges/failure The connector vibrated out of its socket Falling debris Falling computer X-rays E.g., only when the temperature exceeds 100 F. and the cabinet door is closed E.g., on Mars
Errors that occur away from the lab are the worst
Stroustrup/Programming
18
Replicate
In emergency, use a spare Know when the program (or hardware) is misbehaving
Self-check
Make systems modular Have some other module, computer, part of the system responsible for serious errors
Monitor (sub)systems
Absolute addresses
Physical resources (e.g., control registers for external devices) and their most basic software controls typically exist at specific addresses in a low-level system We have to enter such addresses into our programs and give a type to such data For example
Device_driver* p = reinterpret_cast<Device_driver*>(0xffb8); Serial_port_base *COM1 = reinterpret_cast<Serial_port_base*>(0x3f8);
Stroustrup/Programming
20
// 8 bits // typically 16 bits // typically 16 bits or 32 bits // (check before using) // many embedded systems have 16-bit ints // typically 32 bits or 64 bits
std::vector<bool> vb(93); // 93 bits Use only if you really need more than 32 bits std::bitset bs(314); // 314 bits Use only if you really need more than 32 bits Typically efficient for multiples of sizeof(int)
Stroustrup/Programming 21
Bit manipulation
a: b: 1 0 1 0 1 0 1 0 0xaa 0 0 0 0 1 1 1 1 0x0f
a&b: 0 0 0 0 1 0 1 0 0x0a a|b: a^b: a<<1: b>>2: ~b: 1 0 1 0 1 1 1 1 0xaf 1 0 1 0 0 1 0 1 0xa5 0 1 0 1 0 1 0 0 0x54 0 0 0 0 0 0 1 1 0x03 1 1 1 1 0 0 0 0 0xf0
Stroustrup/Programming
22
Bit manipulation
Bitwise operations
Sign bit
8 bits == 1 byte & (and) val | (or) 0 1 1 0 0 0 1 1 0 1 0 0 1 1 0 1 ^ (exclusive or xor) << (left shift) >> (right shift) 0xff: 1 1 1 1 1 1 1 1 ~ (one's complement) 0 1 0 0 1 1 0 1 Basically, what the hardware provides right: true false
For example
void f(unsigned short val) // assume 16-bit, 2-byte short integer { unsigned char right = val & 0xff ; // rightmost (least significant) byte unsigned char left = (val>>8) & 0xff ; // leftmost (most significant) byte bool negative = val & 0x8000 ; // sign bit (if 2s complement) // }
Stroustrup/Programming 23
Bit manipulation
Or |
0xff: val
1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0
Set a bit
And &
For example:
enum Flags { bit4=1<<4, bit3=1<<3, bit2=1<<2, bit1=1<<1, bit0=1 }; unsigned char x = bit3 | bit1; // x becomes 8+2 x |= bit2; // x becomes 8+4+2 if (x&bit3) { // is bit3 set? (yes, it is) // } unsigned char y = x &(bit4|bit2); // y becomes 4 Flags z = Flags(bit2|bit0); // the cast is necessary because the compiler // doesnt know that 5 is in the Flags range
Stroustrup/Programming
24
Bit manipulation
Exclusive or (xor) ^
Stroustrup/Programming
25
Unsigned integers
Try never to use unsigned just to get another bit of precision If you need one extra bit, soon, youll need another Dont mix signed and unsigned in an expression
signed
Indexing into standard library containers uses unsigned (in my opinion, thats a design error) vector<int> v; unsigned correct, but pedantic // for (int i = 0; i<v.size(); ++i) for (vector<int>::size_type i = 0; i<v.size(); ++i) for (vector<int>::iterator p = v.begin(); p!=v.end(); ++p)
Stroustrup/Programming 26
Complexity
Who use features they dont understand Who dont use the most appropriate features
Undereducated programmers
Stroustrup/Programming
27
Coding standards
A coding standard is a set of rules for what code should look like
E.g., use Stroustrup layout E.g., dont use new or throw to avoid predictability problems
Often they fail and create more complexity than they manage
Stroustrup/Programming
28
Coding standards
I wouldnt start a major (multi-person, multi-year) industrial project without one C++ coding standards that restrict programming to something like the C subset do harm They are not uncommon Even the good ones All programmers want to write their code exactly their own way
Coding standards
Common aims
Stroustrup/Programming
30
No function shall have more than 200 lines (30 would be even better)
that is, 200 non-comment source lines E.g., int a = 7; x = a+7; f(x,9); using #ifdef and #ifndef // violation!
May contain common abbreviations and acronyms When used conventionally, x, y, i, j, etc., are descriptive Use the number_of_elements style rather than the numberOfElements style Type names and constants start with a capital letter
Stroustrup/Programming
31
Declarations shall be declared in the smallest possible scope Variables shall be initialized
Casts should be used only when essential Code should not depend on precedence rules below the level of arithmetic expressions
E.g., x = a*b+c; if( a<b || c<=d) // ok // violation: parenthesize (a<b) and (c<=d)
Stroustrup/Programming
32
Dont look too hard at the code (unless you happen to need a good simple encryption algorithm for an application); its simply to give you the flavor of some bit manipulation code It takes one word (4 bytes at a time)
It assumes 4-byte long integers Explanation is at the link (and in the book)
Without the explanation this is just an example of how bit manipulation code can look. This code is not meant to be self-explanatory.
Stroustrup/Programming 33
TEA
void encipher( const unsigned long *const v, unsigned long *const w, const unsigned long * const k) { unsigned long y = v[0]; unsigned long z = v[1]; unsigned long sum = 0; unsigned long delta = 0x9E3779B9; unsigned long n = 32; while(n-->0) { y += (z << 4 ^ z >> 5) + z ^ sum + k[sum&3]; sum += delta; z += (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3]; } w[0]=y; w[1]=z; } Stroustrup/Programming
34
void decipher( const unsigned long *const v, unsigned long *const w, const unsigned long * const k) { unsigned long y = v[0]; unsigned long z = v[1]; unsigned long sum = 0xC6EF3720; unsigned long delta = 0x9E3779B9; unsigned long n = 32; // sum = delta<<5; in general, sum = delta * n while(n-->0) { z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3]; sum -= delta; y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3]; } w[0]=y; w[1]=z; } Stroustrup/Programming
TEA
35