Title: Embedded Development in C
1Lecture 3
- Embedded Development in C
- R3000 Dynamic C Specifics
2Embedded C vs. PC
- Embedded C environments typically differ from
pure ANSI C - Data Types
- Memory Allocation
- Typically many extensions which allow more
control over hardware - Aspects of C which do not fit target architecture
well are left out. - REF Dynamic C Users Manual (Ch 4)
3Data Types
unsigned int j0 while(1)
printf(d\n,j) // send j to serial port
j
on ADSP21065-L (Visual DSP)
on R3000 (Dynamic C)
0 1 65535 0 1
0 1 4294967295 0 1
4Data Types
5ADSP Data types
6Basic Numbering Formats
- Three main numbering formats that we need to
know - unsigned representation
- 2s complement representation (for signed types)
- floating point representations
- Fixed point representations of fractions
- Saturating arithmetic
- Multiplication of fractions
7Standard signed and unsigned representations
unsigned
2n-1
20
range 0..2n-1
signed
-(2n-1)
20
range -2n-1..2n-1-1
Arithmetic operations are the same, so the same
hardware handles both types
8IEEE Std Floating Point Representation
- IEEE floating point numbers have three basic
components the sign, the exponent, and the
mantissa. The mantissa is composed of the
fraction and an implicit leading digit (explained
below). The exponent base (2) is implicit and
need not be stored. - single (32-bit) and double (64-bit) precision
floating-point standards exist, Dynamic C
supports single with type float.
23 bit mantissa (bits 22-0)
exponent127 8-bits
leading 1 is implied, bit 222-1 bit 21 2-2
etc.
sign bit 1negative
Lets represent the number 525 1000001101. This
is like saying 1.000001101 e9 so gt
01000100000000110100000000000000
9Fractional Representations
- Its clear how floating point notation can
represent fractions how about representing
fractions in such a way that they can be dealt
with by standard hardware?. - Think of number as number shifted such that the
desired range is covered. - For instance -20 2-1 2-2 2-3 2-15
- Arithmetic operations still work the same, the
programmer simply needs to know that what the
processor thinks is an int is actually something
with Q15 notation. Q-format representation QN
tells the number of digits that are after the
implied binary point. - Its all up to you here there are no defined
data types for this (usually) - Why fractional?
- lots of multiplies keep expanding the number of
bits needed to represent the number. We can
either overflow (or saturate) as the number gets
too big, or we can lose precision (far more
desirable usually) - Examples with 4-bit arithmetic.
10Memory Allocation
- In a typical embedded system, we must know ahead
of time what is going where. - Chances are, youll run out of space somewhere
- Ex TMS320VC5510 memory map and linker command
file - Programmer is far more intimately knowledgeable
about what memory exists, where it is, and its
performance
11SECTIONS vectors gt VECS PAGE 0
/ interrupt vector table /
.cinit gt SARAM0 PAGE 0 .text
gt SARAM1 PAGE 0 .stack gt
DARAM1 PAGE 0 .sysstack gt DARAM1 PAGE
0 .sysmem gt DARAM2 PAGE 0
.cio gt DARAM2 PAGE 0 .data
gt DARAM2 PAGE 0 .ext_mem
ext_mem.obj (.bss) gt CE0_0 PAGE 0
.ext_mem2 ext_mem2.obj (.bss) gt CE0_1 PAGE 0
.ext_mem3 ext_mem3.obj (.bss) gt CE0_2
PAGE 0 .ext_mem4 ext_mem4.obj (.bss)
gt CE0_3 PAGE 0 .ext_mem5 ext_mem5.obj
(.bss) gt CE0_4 PAGE 0 .ext_mem6
ext_mem6.obj (.bss) gt CE0_5 PAGE 0
.hp_mem hp_mem.obj (.bss) gt SARAM11 PAGE 0
.bss gt SARAM0 PAGE 0
.const gt DARAM3 DARAM2 PAGE 0
.csldata gt DARAM0 PAGE 0 dmaMem
gt DARAM0 PAGE 0
Linker Command File (Programmer creates)
12R3000 Memory Allocation in Dynamic C
- R3000 is memoryless
- Code and Data both reside on external memory
- Addresses in instructions are 16-bits for an
addressable range of 64kB. - Using Banking with a memory management unit, this
range is extended by another 4 bits to 20-bits
(or 1Mbyte) - Dynamic C is responsible for allocation of code
and data (via the Rabbit BIOS source code is
provided, so this can be changed)
13(No Transcript)
14Root and Extended Space
- 64kBytes of Root space, allocated between code
and data. - simple enough, just a 16-bit address that goes in
an instruction - Extended Space
- involves making changes to registers first, to
control what bank of extended memory gets put
into a particular section of logical (memory) - Dynamic C can put code and data in extended
memory. Caveats - Code running in Xmem only takes a few extra
cycles on the call / return, so no major penalty
there - Data in Xmem cant be referred to by pointers!
- put code in xmem first if you run out of space
- Can be copied to/from root space
- really large stuff can be stored in flash (slow)
15Keywords for root/xmem allocation
specific to Dynamic C
- root myfunction (void)
- //Tells Dynamic C to place function in root space
- xmem myfunction (void)
- // Place function in xtended space
- xdata my_data 1,2,3,4,5,6,7,8
- // Place constant bunch of data into initialized
flash - xstring legaldisclaimer please be aware that
any claims made about the performance of the
Rabbit3000 are not to be construed as saying that
the Rabbit3000 is suitable for any purpose,
including, but not limited to the following
applications. - xstring errorcodes error user error- you are a
fool, errorprogrammer error, call 555-1212 - // Place constant bunch of data into initialized
flash - memmap
- can be memmap root, memmap xmem, memmap anymem
NNNN. Defines rules for where code goes - root all functions not declared as xmem go to
root - xmem all functions not declared as root go to
xmem - anymem NNNN when code comes within NNNN bytes
of end of root code space, start putting in xmem.
- Default is memmap anymem 0x2000
16Data allocation
- static variables
- have a permanent fixed location in memory
- in root data space
- global variables are by definition static
- auto variables
- A functionss local variable is located on the
system stack and exists as long as the function
call does
17Local Variables
Examples int func() auto int x
int func() static int x
accesses to this variable may be slower
particularly if there are a lot (gt128) variables
declared this way.
This variable will persist, and its space may not
be used by other functions, which could be
inefficient
18Dynamic C Functions for putting non constant data
in xmem
To access xmem data, use function calls to
exchange data between xmem and root memory. Use
the Dynamic C functions root2xmem(), xmem2root()
and xmem2xmem()to move blocks of data between
logical memory and physical memory. long
xalloc(long sz) // use this to GET an xmem adr to
use DESCRIPTION Allocates the specified number
of bytes in extended memory. PARAMETERS sz Number
of bytes to allocate. RETURN VALUE The 20-bit
physical address of the allocated data
Success. 0 Failure. Note This return value
cannot be used with pointer arithmetic. LIBRARY ST
ACK.LIB
19Assorted Hints / Tips
- Efficiency
- declare functions as nodebug with static
variables - nodebug int myfunc (void)
- static int j
- removes the sprinkled breakpoints after every
instruction - Finding extra Root Memory
- use memmap xmem
- change DATAORG in Rabbitbios.c
- increasing DATAORG gives more code space by
changing the place that data starts to a later
address. - corollary, you have less data space
- if you have printfs with literal strings, those
get put in root space. Try to reuse them, or put
them in xmem and copy them just before printing.
20(No Transcript)
21Date-Time Clock
- R3000 has built-in Real-Time Clock
- Works with inexpensive 32.768 kHz oscillator
Vbat (4uA)
Ripple delay 4ns/bit?
48-bit ripple counter
32.768kHz
48-bits 248 ticks 272.4 years 250 mah
battery / .004 mA 62500 hrs (7 yrs)
22Reading the RTC
6 bytes 48-bits
Sequence 1) Write to RTC0R 2) Read holding
registers 3) Write to RTC0R 4) Read holding
registers
23Setting the RTC
Cant write a value to RTC directly
Clear RTC with 0x40, then xC0 to RTCCR Write a
sequence of values to RTCCR to increment The
various bytes to desired Result. Write 0 to
RTCCR to enable Counter to count. Takes up to
255 write cycles
24Dynamic C Utility Functions (RTCLOCK.LIB)
- unsigned long read_rtc(void)
- returns rtc time in seconds since midnight Jan1
1980 (if clock is set correctly) - void write_rtc(unsigned long int time)
- writes a 32-bit seconds value to the RTC, zeros
other bits - unsigned int mktm(struct tm timeptr, unsigned
long time) - struct tm char tm_sec // seconds
0-59 char tm_min // 0-59 char
tm_hour // 0-23 char tm_mday //
1-31 char tm_mon // 1-12 char
tm_year // 80-147 (1980-2047) char
tm_wday // 0-6 0sunday - unsigned long mktime(struct tm timeptr) // the
reverse
25Periodic Interrupt
- It is frequent that in an embedded program its
nice to have some reasonable, but crude concept
of time - task switching in OS
- delays for real-world controls, timeouts
- Periodic IRQ is an IRQ based on the RTC counter.
16clks 488us
Note we arent talking about precise timing
controls or measurements that responsibility
falls to the timer system
26Virtual Driver
- Dynamic C by default enables the periodic
interrupt for use as part of the Virtual Driver - compiled to target with your code
- Run before main is called
- initialization services
- turns on periodic interrupt
- initializes timer variables
- periodic interrupt services
- Hits hardware watchdog timer
- Maintains software watchdog timers
- Keeps global timer variables
- helps drive multi-tasking services built into
Dynamic C -
27Timer Variables
- SEC_TIMER, MS_TIMER, TICK_TIMER
- unsigned long int
- on initialization, SEC_TIMER synchronized with
real-time clock. - periodic interrupt adjusts these values
- same oscillator drives periodic interrupt as RTC,
so no issues with getting out of sync - user code can simply read these memory locations
for time, rather than the cumbersome reading of
RTC registers.
28Using the Global Timer Vars
example in DC Users Manual using MS_TIMER to
measure execution time in us of an integer add
29Virtual Watchdogs
- Virtual Driver maintains 10 counters in memory
and decrements them periodically in the periodic
interrupt - Application software can use one of these timers
for error detection / recovery by periodically
resetting them in application code. - if the counter gets to 0 in the virtual driver,
the board will be reset
30Virtual WD Timer Functions (VDRIVER.LIB)
- int VdGetFreeWd(char count)
- returns a free v-watchdog and starts it from
count - VdHitWd(int ndog)
- resets the virtual watchdog to the original
count. Ndog is value returned by VdGetFreeWd - VdInit
- called by BIOS without user action before main
unless you have specifically disabled it.
31Watchdog Timer
- 17-bit Counter
- Free runs on 32.768kHz oscillator if enabled
- When counter reaches predetermined value, pulse
from output resets processor - 250ms,500ms,1s,2s
- Software disables this reset by writing to WDTCR
before the output reaches the predetermined
value. - Resets the timer and sets the future compare value
R3000 Users Manual 7.8 has some software
suggestions
32BitWise I/O
- Toggling individual bits can be cumbersome
- Write only registers require local copy
- Processor must AND, OR to avoid other bits
- Parallel Port D,E bits can be individually
addressed in sep. registers - PEB7R, PEB6Retc
- Write to the corresponding register changes that
bit only
33Drive Control
- Port D,F,G have configurable output drivers as
set by PxDCR - 0 Default Driver drives output high and low
depending - 1 Open Drain Driver drives low only,
presumably pulled high by an external resistor
Picture Here
Ref R3000 UM Sec. 4.2
34Output Synchronization
- As mentioned in class earlier
- Parallel Ports DEFG
- Data register is written to ahead of time but
will actually change on - PCLK/2, (default) or
- Timer_A1
- Timer_B1
- Timer_B2
Ref Creating Precisely Timed Output Pulses
(R3000 UM 4.1)
35Misc RdPortE, WrPortE
- RdPortI, WrPortI, (and BitRdPortIetc) all access
internal R3000 registers this is called
internal I/O space. Address 0 in internal I/O
space is not equivalent to address 0 in Memory
space, (or address 0 in external i/o space) - access to various spaces is done via different
instructions more when assembly language is
discussed - RdPortE, WrPortE call the instructions which
access the external i/o space
36Example System with External I/O device
Other Hardware with memory-like interface
Processor
True Memory Devices
Address / Data Bus Interface
could be in either place but concept of I/O
space allows simple interfacing to a
separate port.
Other Hardware with memory-like interface
3716C550 UART (for RS-232 comms)
Device has 8 registers on board that we need to
be able to read and write to.
For hooking this to a R3000, A0-2 would be hooked
to PB2-4 (IA0-2). D7-D0 would be hooked to PA7-0
(ID7-0). Then, after enabling the external i/o
bus (setting SPCR bits 2 and 3), we can write to
and read from the registers on the chip with
simple read and write instructions, or the
RdPortE, WrPortE
38Lab 2
- Look in Samples\RTCLOCK directory for some good
examples of how to use the real time clock
functions in Dynamic C - Check out the assembly generated by repeated
calls to BitWrPortI