C - Renesas e

advertisement
ID A20C: Using “C” for
Embedded Design
What to know as you take the plunge into “C”
BNS Solutions
Vin D’Agostino
Principal
14 October 2010
Version: 1.1
Renesas Technology and Solution Portfolio
Microcontrollers
& Microprocessors
#1 Market share
worldwide *
ASIC, ASSP
& Memory
Advanced and
proven technologies
Solutions
for
Innovation
Analog and
Power Devices
#1 Market share
in low-voltage
MOSFET**
* MCU: 31% revenue
basis from Gartner
"Semiconductor
Applications Worldwide
Annual Market Share:
Database" 25
March 2010
** Power MOSFET: 17.1%
on unit basis from
Marketing Eye 2009
(17.1% on unit basis).
Renesas Technology and Solution Portfolio
Microcontrollers
& Microprocessors
#1 Market share
worldwide *
Solutions
for
Innovation
ASIC, ASSP
& Memory
Advanced and
proven technologies
Analog and
Power Devices
#1 Market share
in low-voltage
MOSFET**
* MCU: 31% revenue
basis from Gartner
"Semiconductor
Applications Worldwide
Annual Market Share:
Database" 25
March 2010
** Power MOSFET: 17.1%
on unit basis from
Marketing Eye 2009
(17.1% on unit basis).
3
Agenda
 A quick Journey into Embedded C
 Setting up Projects in HEW
 Managing the System and the Solution
 Layer Drawing
 Documentation
 Conclusions
A quick Journey into Embedded C
5
Why C? Why not assy? Why not C++?
 C is not a magic bullet: there is nothing you can do in C that
you can’t do in assy, but most likely won’t
 C “encourages” you to write structured code
 Structured code is inherently more
 Maintainable
 Reusable
 Documentable
 C “modules” can be written for one processor family and
reused, mostly without major modification, on another
family
 C gives you the advantages of a higher level language
without the burden of much overhead
 Flexible preprocessor directives can be used for conditional
inclusion and code placement
 Real library of public domain algorithms –but– be careful!
6
A brief C overview
 Two books
 The C Primer Plus, Sams (ISBN-13: 978-0672326967)
 The C Programming Language, K&R (ISBN: 0-13-110362-8 )
 History
 Bell Labs
 Designed for writing OS’s and compilers






7
Code always starts at “main()”
Some small initialization code is automatically generated
Pre-processor scan “manages” compilation process
Compiles to re-locatable code
Links to absolute memory space
Extensible language
Common myths about C
 Code written in C is always significantly larger than in assy
 Code written in C always runs slower than in assy
 C code does not run well on processors with small RAM
space
 C compilers are expensive
 Embedded C code is not transportable between hardware
platforms
 C is a “write only” language: who can read that mess?
 C makes it harder to get to the hardware than assy
8
Why is writing C for small system different?
 Code for small systems must take memory usage (RAM &
ROM), machine cycles, and library usage into account
 There is typically no real “API” that is written to – the
application addresses hardware directly
 Often, there is no OS or scheduler – the application itself is
the OS
 Often the understanding of physical movement of bits can
result in more compact and responsive code
 Reusable “modules” are inherently more granular and
focused
 e.g. Multiple versions of “readA2D()” one for each processor
family
 Header files may have 1 or 2 lines of code
9
Why is writing C for small system different?
 Debugging has it’s own quirks, hardware interaction
 Interrupt handling can get “interesting” when 1 line of C
becomes 20 lines of assy
 main() procedure typically never terminates
 Why use local variables in main()?
 What happens if it DOES terminate
 What calls main()?
10
Setting up Projects in HEW
11
Structuring the project
 All global variables in a single file to be managed
appropriately
 Liberal use of header files for maintaining literal values and
compile “switch” conditions
 All source files in a single directory – unless there is real
need to subdivide (common files, external sources, etc)
 Make sure that the tools are set up properly
 Use “sessions” and “configurations” within HEW to manage
what is compiled when, and how
 Place all ISR code in a single file, calling functions as
appropriate
 Divide the code by the hardware peripherals you will be
utilizing
 Place all hardware interaction code in a single file, or file
hardware specific C & H files
12
Files: What goes where?
 “globals.c” for all global variables and constants
 “extern.h” a parallel file to globals.c used to “expose” each
source file to the global variables/constants
 “main.c” or “<projectName>.c” holds “main() procedure
 <peripheralType>.c used to hold code that processes
peripheral information
 e.g. “keyboard.c”
 e.g. “serial.c”
 parallel named header files (e.g. “keyboard.h”) used to hold
 compilation switch values
 #define constant definitions
 Data structures
 All code that interfaces with hardware in a separate file
“HAL.c” (If you choose the “file per peripheral” structure, 2 C
files, one for “algorithmic” code and one for hardware.)
13
Let’s look at some code…
14
Global variable are NOT evil
 Global variables are used to link mainline code with ISRs
 Global variables can reduce stack size and execution time
 Global variables can be used to house cross-procedure
values that would cost time and space to pass
 Global variables can be used instead of local variables in
main() to reduce the size of the stack [don’t forget, main()
never terminates, so those variables are always there!]
 Global variables can be a more convenient place to hold
status flags
 Just, for heaven’s sake, name them well!
15
Managing the System and the Solution
16
Interrupts and mainline code
 Rule # 1: Do as little as possible in interrupts
 Rule # 2: Rule # 1 can be broken
 Rule # 3: Set ISR priorities appropriately




What
What
What
What
has to happen, no matter what?
interrupt handler can be interrupted?
is the frequency of interrupts?
is the interrupt processing time?
 Make sure that interrupts using global variables actually
have access to the whole value
 What does main() look like?
 Only function calls?
 Giant switch statement?
 Inline code?
17
Laying out the code design
 Divide the task into a minimum of 4 layers:




Application (top layer)
Processing, filters, and drivers (layer 2)
Hardware Abstraction Layer (layer 1)
Hardware layer (layer 0)
 Write a “throwaway” main.c file, or include (inline) a
CodeTest.c” file
 Start with layer 1 and “expose” the upper layers to the
hardware, but in an abstracted way. This will give the code
in layer 2 maximum reusability
 Move to writing isr code
 Write code in layer 2 to expose all needed information for
“application level” decisions
 Write application code, calling only layer 2 code and using
global variables
18
Layer drawings
 Can aid in overall organization of code and thoughts
 Can support “top-down design” “bottom up implementation”
 Can help highlight areas where development can be divided
amongst colleagues
 Can show logical test interfaces in code
 Can be used to show hardware/firmware interaction
 Convenient documentation tool
19
Example Layer drawing…
20
Procedure performance
 How are procedures affected by code structure?







Loops and tests
switch vs. if-then-else
Syntax of literals
Intermediate value casting
Use of logical vs. arithmetic operators
Values of denominators
Order of operation – don’t assume left to right with
communitive operators/operations
 How are procedures affected by variable declaration?
 Source and destination variables and types
 Global vs. stack
 Intermediate variable optimization
21
Functions or procedures?
Functions return values… but…
Procedures can take the resultant variable as a parameter
Values can also be global variables
Functions are more easily transportable… usually
Functions return a single value (which can also be a pointer,
a structure, etc.)
 Decisions are based on stack size, execution speed, and
overall code design
 Consider function/procedure tables with pointers to make
state machines more easily changed, and typically smaller
 Function/procedure based state machines can run faster
than interrupts





22
“That’s real hardware ya got there, buddy…”
 Direct manipulation of registers, bits, pins
 Memory is hardware, too – use logical operators (and, or,
shift, etc.) to save code space
 Write bit masks in a way that makes logical sense and can
be “self documenting
 processFlags |= KEYBOARD_TIMER_EXPIRED;
 processFlags &= ~KEYBOARD_TIMER_EXPIRED;
 Observe rollover issues when processing 16 bit hardware
registers
 Don’t “wait” for register flags unless you have to
 We live in an analog world, and sometimes it ain’t pretty…
 Hardware filtering may not be enough
 Debugging can be tough if you hit a breakpoint with 10A
flowing
23
printf() IS evil
 printf and sprintf are pieces of general code not typically
optimized for small systems
 Write your own, knowing that you (typically) have a limited
number of things to say
 Use a “debug dump” for tracing critical values during
execution
 LCD module and LCD peripheral code can be more easily
written to focus on what you need, and will be “lighter”
 An “encapsulated” packeted protocol can be much more
efficient, and writing the code on the PC side is a breeze
24
Let’s look at some code…
25
What library routines are you REALLY using?
 Look at variables
 Check code size every compile (I like to scratch the last
value on a pad next to my computer)
 Look at literals: 10 is different than 10. and 0x10 can be
different than 0x0010
 What advanced arithmetic/trigonometric functions are you
using?
 Are you processing strings?
 Do you really need floating point?
 (Fred * 1000) / 256 is the same as Fred * 3.906
 (Fred * 1000) >> 8 is even better
 All these things can include libraries that you hadn’t
intended
26
To optimize or not to optimize? That is the
question
 Optimized code can change more severely from toolchain
rev to toolchain rev
 Optimizing for speed usually increases size
 Optimizing for size usually decreases speed
 Optimization can reduce RAM footprint
 Precompiled code will typically not be re-optimized
 Try different combinations of optimization levels
 Properly written, appropriately optimized code can be
smaller than assy code you’d write on your own, and still be
readable
27
Can variable declarations help code efficiency?




“volatile” keyword
Structures and unions
“static” keyword
Code size for variable types
 What libraries are pulled in?
 Does “casting” help or hurt?
 Pointers
28
Documentation
29
Flowcharting: Nassi & Schneidermann, not
songwriters




Structured flowcharting
Code flow always enters from the top
Code flow always exits from the bottom
Limited number of code structure types





Sequential statement
Loop – test at top
Loop – test at bottom
Conditional if-then-else
Switch – multiple choice
 Statements embed into a graphic path
 Great documentation tool
 Code can be written (almost) directly from chart
 Let’s look at one…
30
Commenting
 Variable, procedure/function name, macros can have very
descriptive names to make much of the code self
documenting
 Many companies have coding standards; if they cover the C
language, try to use them
 Each piece of code should at least have a header
 Each file should at least have a header
 Break up parameters one line at a time; add comments on
each line about the parameter
31
How does all this fit with Design flow?
 Big topic, too big to fully cover here, but…
 Waterfall
 N-S flowcharting and layer diagram done first as a result of
spec
 Reviewed with design team and “product manager”
 Hardware implementation proven first
 Documentation done as code is implemented, bottom to top
 Agile/Iterative
 Hardware can be done in first or second sprint
 Some code can be proven on a dev kit or similar platform
before HW is up
 Enough of the hardware specific code needs to be up and
running in one way or another to start implementing stories
 Code and hardware development from initial platform can be
developed in sprints as any code development
32
Conclusions
 C can be used to write small footprint efficient code for small
platforms
 C can help manage global variables to minimize risk
 C can make highly optimized code on the assy level readable
 C can allow you to generate reusable code from a processor,
algorithm, and peripheral perspective
 C, and the associated structured documentation tools, can
increase efficiency when working as a team
 C techniques can actually augment understanding of the
firmware/hardware interface
 Good practice naming conventions and style can produce
“self documenting” code
33
Contact Info:
Vin D’Agostino
BNS Solutions
vindag@bnssolutions.com
+1.508.668.6132
Thank You
Download