portable code without the pitfalls
TRANSCRIPT
Portable Code Without the Pitfalls
Pebble Bay Consulting Ltd
John Efstathiades
24-Sep-13 1 © 2012 Pebble Bay Consulting Limited
About Pebble Bay
• Independent embedded software specialists • founded 7 years ago
• based in Leamington Spa
• Consultancy • independent review and advice
• Software development • fully-managed projects
• Expertise • real-time operating systems
• hardware/software interfacing
• software porting and optimisation
24-Sep-13 © 2012 Pebble Bay Consulting Limited 2
What is Porting? • Adapting software to suit different…
• hardware
• processor architecture
• processor core
• peripherals
• run-time software
• RTOS
• tools
• compiler
• debugging tools/methods
• In any combination
24-Sep-13 © 2012 Pebble Bay Consulting Limited 3
What is Portable Code? • Binary portability
• same binary, run on different targets
• Java
• EABI
• Source portability • same source, built for different targets
• Linux, gcc, …
• “I’m building an embedded system…why should I care?” • things always change!
• improve potential for re-use
reduce cost of future developments
24-Sep-13 © 2012 Pebble Bay Consulting Limited 4
Direct Hardware Access • Make it hard to “untangle” hardware-specific parts from
hardware-independent parts of software
Isolate hardware access from application logic
Use device drivers • can be very simple/thin/informal
• may be required if using an RTOS
24-Sep-13 © 2012 Pebble Bay Consulting Limited 5
application software
hardware
application software
hardware
device drivers
Direct Calls to OS • Make it hard to port application to new OS
Use standard libraries if possible • ANSI C
• POSIX
Use OS abstraction layer • may be a single source file
24-Sep-13 © 2012 Pebble Bay Consulting Limited 6
application software
hardware
RTOS
application software
hardware
RTOS
OS abstraction
Language/Compiler Features • Language trouble-spots – for example, in C:
• implementation-defined
• example: size of integer, allocation of bit fields, …
• unspecified
• example: order of evaluation
• undefined
• example: a[i] = i++;
Use ANSI fixed-width integers for • hardware registers
• communication protocol fields
Avoid language extensions, non-standard libraries • special hardware features – bit manipulation, etc.
24-Sep-13 © 2012 Pebble Bay Consulting Limited 7
#include <stdint.h>
typedef uint32_t STATUS_REG;
Byte Order (“Endianness”) • Critical when accessing “real-world”, external data
• i/o device registers
• communication protocols
• files
Define external data formats carefully – including byte order
Define macros/routines for byte order conversion • example: (Linux) htobe32(), betoh32(), …
Use religiously • even when processor and data have same byte order…
Don’t rely on byte order to access high/low bytes of integers! • use shift and mask instead
24-Sep-13 © 2012 Pebble Bay Consulting Limited 8
Alignment/Packing • Hardware defines alignment “rules”
• efficiency – aligned accesses are faster
• mis-aligned accesses may cause exceptions
• Compiler allocates memory based on these rules • structures, etc.
• Position of structure fields will vary • processor, compiler, etc.
Be careful if structures used to access • device i/o registers
• fields of a communication protocol
• objects read from/written to files
May need to add explicit packing
24-Sep-13 © 2012 Pebble Bay Consulting Limited 9
typedef struct {
uint8_t status;
uint32_t data;
…
} RESULT;
pad
Bit Fields • Very tempting abstraction, but…
• …where do the bits end up? • implementation-defined feature
• depends on compiler, processor, …
Don’t use for bits in fixed positions • i/o device registers
• communication protocol fields
Instead • define bitmasks literally
• use explicit bitwise operations
• yes, it will look messy…
24-Sep-13 © 2012 Pebble Bay Consulting Limited 10
typedef struct {
unsigned int error: 1;
unsigned int value: 6;
unsigned int ready: 1;
} STATUS;
…
/* get status */
STATUS status = …;
/* decode status */
uint8_t value;
if (status.ready) {
…
value = status.value;
…
}
typedef uint8_t STATUS;
#define S_ERROR 0x80
#define S_VALUE 0x7e
#define S_READY 0x01
…
/* get status */
STATUS status = …;
/* decode status */
uint8_t value;
if (status & S_READY) {
…
value =
(status & S_VALUE) >> 1;
…
}
Type Punning • Making an object of one data type “look like” another
• Pointer casts • example: ((STRUCT_X *)p)->member = value;
• memcpy()
• example: memcpy(&typeX, &typeY, sizeof(typeX));
• Dangerous and not portable • results depend on how compiler represents different data types
Avoid pointer casts
Don’t use memcpy() for assignment
24-Sep-13 © 2012 Pebble Bay Consulting Limited 11
Assembly Code • Obviously not portable between processor architectures
• Often used, rarely needed • access to special-purpose registers/instructions
• memory barriers/synchronisation
• interrupt locking
• atomic operations
• special arithmetic/DSP capabilities
Minimise and isolate in C-callable macros/functions
Define in single header/source file
Consider using compiler built-ins? • still not portable
24-Sep-13 © 2012 Pebble Bay Consulting Limited 12
Development Process Use coding standards
• often include rules to discourage non-portable code
• company-specific
• industry standard (MISRA, etc.)
Use static checking tools • automatically highlight non-portable code
• lint, etc.
Use code reviews • critical reader tends to spot things the author missed
• effective even without deep understanding of whole system
24-Sep-13 © 2012 Pebble Bay Consulting Limited 13
Trade-Offs • More effort to develop?
• not really, if portability considered from the start
• Lower performance? • generally not – assuming a decent compiler
• possibly, in some special cases (special hardware)
• if a major concern, minimise and isolate critical hardware-specific code
24-Sep-13 © 2012 Pebble Bay Consulting Limited 14
Benefits • Design often more modular
• easier to understand and maintain
• Code often simpler • easier to debug
• Testing often easier • possibly on different hardware
• maybe earlier in project
• Better chance of re-use
Lower development cost
Fewer bugs
24-Sep-13 © 2012 Pebble Bay Consulting Limited 15
More Information…
• Pebble Bay Consulting • www.pebblebay.com
• 01926 421700
24-Sep-13 © 2012 Pebble Bay Consulting Limited 16