HU powerpoint-presentatie

HU powerpoint-presentatie

Objects? No Thanks! Using C++ effectively on small microcontrollers Wouter van Ooijen MSc Hogeschool Utrecht, Netherlands, senior lecturer Computer Engineering [email protected] BeC++ 2016-06-30 Embedded a meaning Means: part of something larger (not stand-alone) subservient to that larger thing with a dedicated task (not general-purpose). Note that this does not imply a particular type of hardware or style of programming. Often computer hardware is used for embedded systems that is the same or very similar to what is used on a desktop. C++ on small microcontrollers -2 Embedded some differences The computer hardware is part of the product

The price of the hardware is reflected in the price of the product. There is economic pressure to be efficient (use the cheapest posible hardware). Often the larger thing has (hard) real-time requirements. The embedded system must (always) be fast enough. Often the system is used to control real hardware. Failures have interesting consequences (up to loss of life). C++ on small microcontrollers -3 Real-Time Means: utility depends critically on some timing parameter. Variations (terms vary): Soft real-time: usefulness degrades (rapidly) Firm real-time: may occasionally be late or lower-quality C++ on small microcontrollers -4

Soft real-time usefulness degrades (rapidly) beyond the deadline C++ on small microcontrollers (if there was any to begin with) -5 Firm real-time If the perfect result cant be calculated in time give what you have, but be on time! C++ on small microcontrollers -6 Hard real-time (and mission-critical) Late might even be worse than not at all C++ on small microcontrollers -7 Embedded a wide range of seriousness Consequently, a wide range of development styles:

JBF*, Agile, prototyping, waterfall, C++ on small microcontrollers * Jan Boere Fluitjes: Dutch saying, meaning roughly casual, with as little effort as possible -8 C++ in (very) serious embedded systems CppCon 2014: Mark Maimone "C++ on Mars: Incorporating C++ into Mars Rover Flight Software" CppCon2014: Bill Emshoff "Using C++ on Mission and Safety Critical Platforms" C++ on small microcontrollers -9 Embedded a wide range of hardware capabilities 1Kb 1Mb

1Gb C++ on small microcontrollers - 10 Embedded a wide range of hardware capabilities 1Kb 1Mb 4-bit 1Gb 64-bit 8-bit : 8051, PIC, AVR, No full standard C/C++ 16-bit : MSP430, PIC, 32-bit : ARM, MIPS, Intel, C++ on small microcontrollers

- 11 Embedded a wide range of hardware capabilities 1Kb 1Mb 1Gb Wide range of support software: Bare metal: libraries, but no OS RTOS Desktop OS: Linux Windows C++ on small microcontrollers - 12

Some small micro-controllers PIC12F200 8-bit CPU 256 Flash 16 RAM [email protected] As yet no C++ compiler*: 8-bits crazy CPU architecture MKE04Z8VTG 4 32-bit CPU 8k Flash 2k RAM [email protected] A low-end chip for C++: 32 bits Cortex-M0 GCC * There are 8-bit CPUs that do support C++ (well, most of it).

Objects? No Thanks! - 13 Micro-controllers are everywhere Objects? No Thanks! - 14 Small micro-controller programming Typically Applications are small Volumes are high Worst-case timing constraints must be met (average timing is not important) User-requirements are fixed (but hardware might change over time) C dominates (even assembler is still used) Objects? No Thanks! - 15 Small microcontroller economics n

Product cost scales with use of resources: CPU speed (power consumption!!) code size (Flash) data size (RAM) Those prices are payed by the manufacturer, not by the end user (as for desktop software). Pressure on the developers to reduce resource use: every data byte or instruction counts (even if only in the perception of the managers). Objects? No Thanks! - 16 Embedded programming languages VDC survey 2010; languages *used*, != LOC C++ on small microcontrollers - 17 Use across the spectrum 1Mb 1Kb

Assembly 1Gb C C++, C, Java, C#, Perl, Python, C++ on small microcontrollers - 18 Code re-use Is hindered by Small size, so (perceived) benefit is small Code is often written by electrical engineers Lack of abstraction mechanisms in C Each application has unique aspects, down to the lowest levels Objects? No Thanks! - 19 Language use across the spectrum 1Mb

1Kb 1Gb C++ gap Assembly C C++, C, Java, C#, Perl, Python, C++ on small microcontrollers - 20 So why should C++ be used? As a better C

Enables other programming styles (same programming style, less room for errors) (OO, functional, templates, . . .) More opportunities for (efficient) code re-use Objects? No Thanks! - 21 But not like C++ on a desktop

Performance is different Heap: forget it Floating point: often not practical Exceptions: debatable C++ standard library: large parts are unusable (heap, float/double, worst-case performance) OO at run-time (virtuals): often not needed ROM is scarce, RAM even more so std::ostream, std::cout ?? C++ on small microcontrollers - 22 Heap The heap is flexibility with respect to the amount of data, at the cost of (some) unpredictability in run-time and maximum available memory (fragmentation). A typical small embedded system has a rigidly prescribed task, including the size of the data involved Must meet real-time constraints Should be certain to meet work OK all the time (not just for a certain sequence of actions).

A heap and a small embedded system dont match very well. Better: Global allocation (!) Fixed size pools or (better?) fixed size containers on the stack Avoiding some dangling pointer is a nice extra C++ on small microcontrollers - 23 Exceptions Exceptions are great to handle a local problem that requires a (more) global response. A small system often has a rather simple, rigidly defined task there are no exceptions, only different situations. No heap one reason less to use exceptions.

Exception implementation often uses the heap. Straw man: exceptions are slow and have unpredictable timing. C++ on small microcontrollers - 24 Floating point FP is useful when a wide dynamic range is needed. For an embedded application the ranges are often very well known. Small micro-controllers often dont have a hardware FPU. A software FP library Is considerably slower Generally not needed (value range is known) Takes up ROM C++ on small microcontrollers - 25 C++ test case: blink a LED The embedded equivalent of Hello world Objects? No Thanks! - 26

Blink a LED in C // return the pointer to an IO port related register #define GPIOREG( port, offset ) \ (*(volatile int *)( 0x50000000 + (port) * 0x10000 + (offset))) // set the pin port.pin to value #define PIN_SET( port, pin, value ) \ { GPIOREG( (port), 0x04 << (pin) ) = (value) ? -1 : 0; } int main(){ for(;;){ PIN_SET( 1, 0, 1 ); delay(); PIN_SET( 1, 0, 0 ); delay(); } } Some ugly details (initialization, timing, ) have been omitted to concentrate on making the pin high and low. .L97: ldr

r4, .L98 // mov r3, #1 // neg r0, r3 str r0, [r4] // bl delay mov r1, #0 str r1, [r4] // bl delay b .L97 .align 2 .L98: .word 1074036740 get the I/O register address get -1 into r3 store -1 in the I/O register store 0 in the I/O register

Objects? No Thanks! - 27 PIN_SET( 1, 0, 1 ) // set the pin port.pin to value #define PIN_SET( port, pin, value ) \ { GPIOREG( (port), 0x04 << (pin) ) = (value) ? -1 : 0; } Abstraction of an I/O pin + Efficient - Cant easily be replaced or augmented by the user - It is a macro! (scope, textual parameters, ) Objects? No Thanks! - 28 Classic OO pin abstraction struct pin_out { virtual void set( bool ) = 0; }; volatile int & gpioreg( int port, int offset ){ return * (volatile int *) ( 0x50000000 + port * 0x10000 + offset ); } void blink( pin_out & pin ){

struct lpc1114_gpio : public pin_out { for(;;){ const int port, pin; pin.set( 1 ); delay(); lpc1114_gpio( int port, int pin ) pin.set( 0 ); : port{ port }, pin{ pin }{} delay(); } void set( bool x ) override { } gpioreg( port, 0x04 << pin ) = x ? -1 : 0; } int main(){ }; lpc1114_gpio led( 1, 0 ); blink( led ); } Abstract class with virtual functions Objects? No Thanks! - 29 Metrics for set(1) + set(0) + support code

PIN_SET( 1, 0, 1 ); PIN_SET( 1, 0, 0 ); Code (bytes Flash) RAM CPU cycles C (macro) 16 0 ~9 pin.set( 1 ); pin.set( 0 ); C++ (virtual functions) 68 12 ~ 56 What has gone wrong?

Objects? No Thanks! - 30 Generated code (C++ OO-style) push {r4, lr} mov r4, r0 .L12: ldr r3, [r4] mov r0, r4 ldr r3, [r3] mov r1, #1 blx r3 bl _Z5delayv ldr r3, [r4] mov r0, r4 ldr r3, [r3] mov r1, #0 blx r3 bl _Z5delayv b .L12

void blink( pin_out & pin ){ for(;;){ pin.set( 1 ); delay(); pin.set( 0 ); delay(); } } int main(){ lpc1114_gpio led( 1, 0 ); blink( led ); } ldr r3, .L14 add r0, sp, #4 str r3, [sp, #4] mov r3, #1 str r3, [sp, #8] mov r3, #0 str r3, [sp, #12] bl _Z5blinkR7pin_out .align 2 .L14: .word

1342177284 18 _ZN12lpc1114_gpio3setEb: ldr r3, [r0, #4] push {r4, lr} mov r4, #160 lsl r4, r4, #7 add r2, r3, r4 ldr r3, [r0, #8] mov r0, #4 lsl r2, r2, #16 lsl r0, r0, r3 add r3, r2, r0 neg r1, r1 str r1, [r3] pop {r4, pc} 26 24

Objects? No Thanks! - 31 Why so much code? Run-time polymorphism: Connection between operation and implementation is made at run time This takes code, CPU cycles, even some RAM, and blocks optimizations Fixed-hardware embedded systems dont need such run-time flexibility, but Efficient use of libraries does require compile-time flexibility Objects? No Thanks! - 32 Alternative: compile-time polymorphism

Static classes (or structs) can be used as compile-time encapsulation of data and operations. Template parameters can be used to pass such an encapsulation to another one. These are compile-time-only actions, hence fully visible to the optimizer. Objects? No Thanks! - 33 Run-time polymorphism Compile-time polymorphism struct pin_out { virtual void set( bool ) = 0; }; struct pin_out_archetype { typedef void has_pin_out; static void set( bool value ){} }

struct lpc1114_gpio : public pin_out { lpc1114_gpio( . . . ) . . . void set( bool x ) override { . . . } }; template< int port, int pin > struct lpc1114_gpio : public pin_out_archetype { static void set( bool value ){ . . . } }; struct blink { pin_out & pin; blink( pin_out & pin ): pin( pin ){} void run(){ . . . pin.set( 1 ); } } template< typename pin > struct blink { void run(){ . . .

pin::set( 1 ); } } int main(){ blink( lpc1114_gpio( 1, 2 )).run(); } int main(){ blink< lpc1114_gpio< 1, 2 >>::run(); } As before, some ugly details (initialization, timing, ) are omitted. Objects? No Thanks! - 34 Generated code (C versus C++ C-T-P) // C with macros .L97: ldr r4, .L98 mov r3, #1 neg

r0, r3 str r0, [r4] bl delay mov r1, #0 str r1, [r4] bl delay b .L97 // C++ with compile-time polymorphism .L3: ldr r4, .L5+12 mov r3, #1 neg r3, r3 str r3, [r4] ldr r0, .L5+16 bl

_...waiting_324waitEj mov r3, #0 str r3, [r4] ldr r0, .L5+16 bl _...waiting_324waitEj b .L3 Code (bytes Flash) RAM C 16 0 C++ 16 0 CPU cycles

~9 ~9 Objects? No Thanks! - 35 Blink: some (ugly?) details #include "targets/lpc1114fn28.hpp" typedef hwcpp::lpc1114fn28<> target; template< typename arg_pin, typename arg_timing > struct blinking { int main(){ hwcpp::blink< target::gpio_1_2, target::waiting >::run(); } #include "targets/lpc1114fn28.hpp" typedef arg_pin >target; pin;

typedefpin_out_from< hwcpp::lpc1114fn28<> typedef waiting_from< arg_timing > timing; Type narrowing int main(){ typedef typename timing::duration duration; hwcpp::blink< target::gpio_0_0, target::waiting >::run(); } static void run( const duration t = duration::ms( 500 ) ){ timing::init(); pin::init(); for(;;){ pin::set( 1 ); timing::wait( t / 2 ); pin::set( 0 ); timing::wait( t / 2 ); } }

Explicit initialization }; Objects? No Thanks! - 36 Four pin archetypes struct pin_in_archetype { typedef void has_pin_in; static void init(); static bool get(); }; struct pin_out_archetype { typedef void has_pin_out; static void init(); static void set( bool value ); }; struct pin_in_out_archetype { typedef void has_pin_in_out; static void init(); static void direction_set_input(); static void direction_set_output();

static bool get(); static void set( bool value ); }; struct pin_oc_archetype { typedef void has_pin_oc; static void init(); static bool get(); static void set( bool value ); }; Objects? No Thanks! - 37 Type narrowing class target { typedef . . . pin_a0; } class target { typedef . . . pin_a0; } typedef target::pin_a0 alarm; typedef pin_out_from< target::pin_a0 > alarm;

int main(){ alarm::init(); alarm::direction_set_output(); alarm::set( false ); int main(){ alarm::init(); alarm::direction_set_output(); alarm::set( false ); if( . . . ){ alarm::set( true ); } } if( . . . ){ alarm::set( true ); }

} The template parameter is type-checked The template adapts to the parameter type Initialization is complete The code cant accidentally use an inappropriate method Objects? No Thanks! - 38 pin_out_from< . . . > template template< class unsupported, class dummy = void > struct pin_out_from { static_assert( sizeof( unsupported ) == 0, . . . ); }; template< class unsupported, pin > struct class pin_out_from pin,>typename pin::has_pin_out > : dummy =

{ static class void init(){ pin::init(); } template< pin > struct pin_out_from < pin, typename pin::has_pin_out > : static pin_out_archetype void set( bool value ){ pin::set( value ); } public }; { static void init(){ pin::init(); } template< classset( pin bool > struct pin_out_from < value pin, typename pin::has_pin_oc > : static void

value ){ pin::set( ); } template< class unsupported, class dummy = void > struct pin_out_from { }; public pin_out_archetype { static_assert( sizeof( unsupported ) == 0, . . . ); }; static template< static public }; { void init(){

pin::init(); } class pin > struct pin_out_from < pin, typename pin::has_pin_oc > : void set( bool value ){ pin::set( value ); } pin_out_archetype static template< static }; public { static static };

void init(){ pin::init(); } classset( pin bool > struct pin_out_from < value pin, typename pin::has_pin_in_out > : void value ){ pin::set( ); } pin_out_archetype void init(){ pin::init(); pin::direction_set_output(); } void set( bool value ){ pin::set( value ); } Objects? No Thanks! - 39 invert< . . . > Dont say it in a comment decorator namespace target { typedef . . . pin_a0;

} typedef target::pin_a0 alarm_led; // the alarm LED pin is active low constexpr bool alarm_led_active = false; int main(){ alarm_led::set( ! alarm_led_active ); if( . . . ){ alarm_led::set( alarm_led_active ); } } Say it in the code namespace target { typedef . . . pin_a0; } typedef invert< target::pin_a0 > alarm_led; int main(){ alarm_led::set( false ); if( . . . ){ alarm_led::set( true ); } } Objects? No Thanks! - 40

Pin invert< . . . > template template< class unsupported, class dummy = void > struct invert { static_assert( sizeof( unsupported ) == 0, ". . ." ); }; template< class pin > struct invert< pin, typename pin::has_pin_in > : public pin_in_archetype { static void init(){ pin::init(); } static bool get(){ return ! pin::get(); } }; template< class pin > struct invert< pin, typename pin::has_pin_out > : public pin_out_archetype { static void init(){ pin::init(); } static void set( bool x ){ pin::set( ! x ); } }; template< class pin > struct invert< pin, typename pin::has_pin_in_out > : public pin_in_out_archetype { static void init(){ pin::init(); } static void direction_set_input(){ pin::direction_set_input(); } static void direction_set_output(){ pin::direction_set_output(); } static void set( bool x ){ pin::set( ! x ); } static bool get(){ return ! pin::get(); } }; template< class pin > struct invert< pin, typename pin::has_pin_oc > : public pin_oc_archetype { static void init(){ pin::init(); } static void set( bool x ){ pin::set( ! x ); } static bool get(){ return ! pin::get(); } };

Often: ZERO cost! Objects? No Thanks! - 41 Some more pin & port decorators // create the stated pin or port type from p pin_in_from< p > pin_out_from< p > pin_in_out_from< p > pin_oc_from< p > port_in_from< p > port_out_from< p > port_in_out_from< p > port_oc_from< p > // create a port of the stated type from pins port_in_from_pins< p, ... > port_out_from_pins< p, ... > port_in_out_from_pins< p, ... > // invert the value read from or written to p invert< p > // pin or port that writes to all pins or ports all< p, ... >

Objects? No Thanks! - 42 Using static class templates: consequences (1) Abstraction tool is the class template with only static contents (classes, methods, attributes) Composition is by template instantiation Method call syntax is class::method() instead of object.method() Header-only

Objects? No Thanks! - 43 Using static class templates: consequences (2) No objects (of such classes) are created No memory management, no dangling references Sharing of identical constructs is automatic No automatic construction: explicit init() calls Overhead can be zero Objects? No Thanks! - 44 Long term view A use case

Write library code for reading the temperature from an LM75 chip (I2C interface). Write it once and for all. What should be in this code? Getting the data bits from the LM75 (using I2C) Converting the data bits to a temperature Maybe detecting errors in the data bits (passing I2C errors along?) What should NOT be in this code? I/O pin handling I2C protocol Timing Conversion to the requested datatype (int, float, double, fixed-point, ) Conversion to the requested unit (Kelvin, Celcius, Fahrenheit, ) Floating point calls Objects? No Thanks! - 45 Next steps Identify and/or implement abstraction(s) for

Values (units, fixed-point) Timing (including multithreading) Error handling Handle parallel hierachies (mix with objects) Objects? No Thanks! - 46 Devirtualization? Compilers are starting to do devirtualization (as part of whole-program optimization). How would perfect devirtualization compare to the static-class-template approach? Objects + ideal devirtualization Static class templates Run-time allocation Compile/link time allocation Global, stack or heap allocation

Only global allocation Danger of dangling references No such danger Run-time flexibility Requires extra effort Sharing requires planning Sharing is automatic (prevention is tricky) Well-known syntax & style Unfamiliar syntax & style Objects? No Thanks! - 47 C++ language issues

Class templates and plain classes cant have the same name. The syntax for using static attributes of class templates can be horrible. A LOT of template and typename prefixes can be required to disambiguate (template parameter-) dependent names. C++0x11 has override for virtual methods, but there is no equivalent for static methods. Objects? No Thanks! - 48 Summary Current C++ libraries and programming practices are often not optimal for very small systems. Compile-time polymorphism using static class templates (no objects!) Can be as efficient as C macros.

Has an abstraction power comparable in power but very different in nature to classic run-timeobjects-based OO. There is a lot of interesting work to do to create C++ libraries that help programming very small systems. Objects? No Thanks! - 49

Recently Viewed Presentations

  • SEG 2100 Software Design II

    SEG 2100 Software Design II

    Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 8: Modelling Interactions and Behaviour 8.1 Interaction Diagrams Interaction diagrams are used to model the dynamic aspects of a software system They help you to visualize how the system...
  • Sargent House - crjustice.org

    Sargent House - crjustice.org

    Introduction to Effective Practices in Community Correctional settings and how we use it within SJSD. EPICS Coaching Sessions: Monthly EPICS training sessions for case managers where different modules are reviewed to keep EPICS on the forefront at the SJS programs...
  • Diapositiva 1 - Presentaciones.org

    Diapositiva 1 - Presentaciones.org

    No había nadie allí, salvo Latif. Ninguna puerta, o ventana, ninguna puerta secreta, ningún mueble que permitiera ocultar a alguien. Sólo había en el piso un plato de madera desgastado, en un rincón una vara de caminante y en el...
  • Vocabulary for &quot;The Sniper&quot;

    Vocabulary for "The Sniper"

    Arial Calibri Baskerville Old Face Wingdings Office Theme Vocabulary for "The Sniper" Check your spelling! Paroxysm noun a sudden activity, outburst , or convulsion Oh—an FYI: This story also contains the word "parapet." You don't need to write it down,...
  • Chapter 12

    Chapter 12

    Describe what might make a food "functional," and how these types of foods might affect health, dietary quality, and overall nutrient intake ... "Vitamin C may reduce the risk of gastric cancer. ... however, there are some individuals and groups...
  • OTHER PROGRESSIVE ERA MOVEMENTS UNIONS, FARMERS AND INDUSTRIAL

    OTHER PROGRESSIVE ERA MOVEMENTS UNIONS, FARMERS AND INDUSTRIAL

    A sawmill worker fell onto a large, unguarded circular saw and was split in two. When a worker got caught in the large flywheel of the main steam power plant of a navy yard, his arms and legs were torn...
  • Nutrition for Kids with Type I Diabetes

    Nutrition for Kids with Type I Diabetes

    Calorie King (book, website, app) My Fitness Pal (website, app) Livestrong MyPlate (website, app) The Exchange List. Exchange list go-to's. 1 slice of bread . 1/2 C potato. 1/3 C pasta. 1/3 C rice. 1 C milk or yogurt. 1...
  • Katalyzované reakce

    Katalyzované reakce

    Katalyzované reakce Kinetika katalyzovaných reakcí, vliv vnitřní difuze na selektivitu Heterogenní katalýza Chemisorpce Reakce látky s aktivním místem na povrchu katalyzátoru Adsorpční izoterma Závislost rovnovážného množství adsorbované látky na složení směsi Langmuirova izoterma adsorpce v jediné vrstvě stupeň pokrytí povrchu...