Slides_3 - Real-Time Embedded Systems Lab
Download
Report
Transcript Slides_3 - Real-Time Embedded Systems Lab
C Programming in Embedded Systems
Computer Science & Engineering Department
Arizona State University
Tempe, AZ 85287
Dr. Yann-Hang Lee
[email protected]
(480) 727-7507
7/23
C Programming in Embedded Systems
Assembly language
dependent of processor architecture
cache control, registers, program status, interrupt
High-level language
memory model
independent of processor architecture (partially true)
Advantages and disadvantages
performance
code size
software development and life cycle
set 3 -- 1
Manage IO Operations Using C
Access memory-mapped IO – pointers
Example
#define REG_READ (a, val) ((val) = *(volatile unsigned char *)(a))
#define REG_WRITE (a, val) (*(volatile unsigned char *)(a) = (val))
#define UART_USR0 0x4000_0204
#define UART_CR
0x4000_0208
#define UART_RX_EN
1
#define UART_TX_EN
(1<<2)
char CR_word=0;
CR_word |= UART_RX_EN | UART_TX_EN;
REG_WRITE (UART_CR, CR_word);
set 3 -- 2
Platform.h for MXL
#ifndef __MCF5213_UART_H__
#define __MCF5213_UART_H__
/* Register read/write macros */
#define MCF_UART0_UMR
#define MCF_UART0_USR
#define MCF_UART0_UCSR
#define MCF_UART0_UCR
(*(vuint8 *)(&__IPSBAR[0x000200]))
(*(vuint8 *)(&__IPSBAR[0x000204]))
(*(vuint8 *)(&__IPSBAR[0x000204]))
(*(vuint8 *)(&__IPSBAR[0x000208]))
According to Linux C/C++ coding style:
“_” Variable not intended to be exposed externally to the user.
Internal workings only. Most often used by compiler and library
authors. Sometimes used (not preferred) as a suffix to
represent a class member variable.
“__” Marks an use as extension to ANSI C++. Often not compiler
independent. Usually reserved for use by compiler writers.
set 3 -- 3
Bit Manipulation
Boolean operation
operate on 1 (true) and 0 (false)
(2 || !6 ) && 7 ??
Bitwise operation
Operation
Boolean op.
Bitwise op.
AND
&&
&
OR
||
|
XOR
unsupported
^
NOT
!
~
operate on individual bit positions within the operands
(2 | ~6 ) & 7 = (0x0002 OR 0xFFF1) AND 0x0007
if (bits & 0x0040)
bits |= (1 <<7)
if (bits & (1 <<6))
bits &= ~(1<<7)
long integer: bits &= ~(1L << 7)
set 3 -- 4
Interface C and Assembly Language
Why combine C and assembly language
performance
C doesn’t handle most architecture features, such as registers,
program status, etc.
Develop C and assembly programs and then link
them together
at source level – in-line assembly code in C program
at object level – procedure call
mwasmcf
mwldmcf
mwccmcf
set 3 -- 5
Calling Convention
GCC calling convention
stack pointer
arguments passed in registers and in stack
dynamic area
registers saved by caller and callee
(including frame pointer and returning PC)
frame pointer points just below the
last argument passed on the stack
(the bottom of the frame)
stack pointer points to the first word
after the frame
frame pointer
local variables
saved registers
(by callee)
argument x
argument y
saved registers
(by caller)
set 3 -- 6
Coldfire Calling Convention
Passes all parameters on the stack in reverse order.
Push the last argument first
Compact — Passes on even sized boundary for parameters smaller than
int (2 for short and char).
Standard — Like compact, but always padded to 4 bytes.
Register — Passes in scratch registers D0 — D2 for integers, A0— A1 for
pointers.
Returning
returns an integer value in register D0.
returns a pointer value in register A0.
If it returns a value of any other type,
the caller reserves temporary storage area
for that type in the caller's stack and passes
a pointer to that area as the last argument.
the called function returns its value in the temporary storage area.
set 3 -- 7
Register Usage by Coldfire C Compiler
Save code pointer (the value of pc) allows the function
corresponding to a stack backtrace structure to be located
Save frame and stack pointers to locate stack frame
Register usage
A0-A1, D0-D2 – scratch registers
A2 through A5 — for pointers
D3 through D7 — for integers and pointers.
A6 – frame pointer
A7 – stack pointer
Caller needs to save D0-D2 and A0-A2 before calling if the values
must be preserved
Callee needs to save D3-D7 and A3-A5 if they are used in the
procedure
set 3 -- 8
Stack Usage by Coldfire C Compiler
Allocation of local variable in stack
Save frame and stack pointers to locate stack
frame
Entry code
link
a6, #-framesize ; save and set up fp and sp,
movem.l ….., -(sp)
; save registers
move.l
(.., a6), d0
; retrieve parameters
; link instruction: SP – 4 → SP; Ay → (SP);
;
SP → Ay; SP + dn → SP
On function exit
move.l
…., d0
; return value
movem.l (sp)+,….
; restore registers
unlk
a6
; restore sp and fp
; unlk instruction -- Ax → SP; (SP) → Ax;
;
SP + 4 → SP
rts
set 3 -- 9
Calling Assembly Routine from C
In C program
char *srcstr = "First string - source ";
char *dststr = "Second string - destination ";
strcopy(dststr,srcstr);
Assembly routine
.global strcopy
strcopy: move.l
move.l
next:
move.b
move.b
bne.b
rts
.end
(4,sp), a0
(8,sp), a1
(a1)+, d0
d0, (a0)+
next
; a0 points to destination string.
; a1 points to source string.
; Load byte and update address.
; Store byte and update address
; Check for zero terminator.
; Return.
set 3 -- 10
Inline Assembly Code in C Program
A feature provided by C compiler
to specify that a block of code in your file as assembly language
use the “asm” keyword.
compiler will do the insertion and knows the variables and the registers
Example: function level
long int b;
struct mystruct {
long int a;
};
static asm long f(void)
// Legal asm qualifier
{
move.l
struct(mystruct.a)(A0),D0
// Accessing a struct.
add.l
b,D0
// Using a global variable, put
rts
// return value in D0.
// Return from the function:
// result = mystruct.a + b
}
set 3 -- 11
Inline Assembly and Access Control Registers
Statement level
long square(short a)
{
long
result=0;
asm {
move.w a,d0
// fetch function argument ‘a’
mulu.w
d0,d0
// multiply
move.l
d0,result // store in local ‘result’ variable
}
return result;
}
Access local and global variables and inline assembly directives
Write to the special purpose registers
_mcf5xxx_wr_sr:
_mcf5xxx_wr_vbr:
move.l
4(SP),D0
move.l
4(SP),D0
.long 0x4e7b0801
/* movec d0,VBR */
move.w D0,SR
nop
rts
rts
set 3 -- 12
Example sumsq
int *sum, array[5];
void sumsq (int *sum, int size, int array[])
{
int total=0;
int i;
for ( i = size-1; i < 0; i--)
total= total + array[i]^2;
*sum=total;
}
int main()
{
sumsq(sum, 5, array);
while(1);
// Idle
}
set 3 -- 13
Example sumsq -- main
int *sum, array[5];
; 19: int main()
; 20: {
; 21:
0x00000000
_main:
;
main:
0x00000000 0x4E560000
0x00000004 0x4FEFFFF4
;
; 22: sumsq(sum, 5, array);
; 23:
;
0x00000008 0x41F900000000
0x0000000E 0x2F480008
0x00000012 0x7005
0x00000014 0x2F400004
0x00000018 0x41F900000000
0x0000001E 0x2010
0x00000020 0x2E80
0x00000022 0x4EB900000000
link
lea
a6,#0
-12(a7),a7
lea
move.l
moveq
move.l
lea
move.l
move.l
jsr
_array,a0
a0,8(a7)
#5,d0
d0,4(a7)
_sum,a0
(a0),d0
d0,(a7)
_sumsq
set 3 -- 14
Example sumsq -- main
;
; 24: while(1);
// Idle
; 25:
;
0x00000028 0x60FE
bra.s
*+0
0x0000002A 0x4E71
nop
; 10:
; 11: void sumsq (int *sum, int size, int array[])
; 12: {
;
0x00000000
_sumsq:
;
sumsq:
0x00000000 0x4E560000
link
a6,#0
0x00000004 0x4FEFFFF4
lea
-12(a7),a7
; 13: int total=0;
; 14: int i;
0x00000008 0x7000
moveq #0,d0
0x0000000A 0x2D40FFF8
move.l
d0,-8(a6)
; 0x00000028
set 3 -- 15
Example sumsq
;
; 15:
for ( i = size-1; i < 0; i--)
;
0x0000000E 0x202E000C
0x00000012 0x5380
0x00000014 0x2D40FFF4
0x00000018 0x6030
0x0000004a
;
; 16:
total= total + array[i]^2;
;
0x0000001A 0x202EFFF4
0x0000001E 0x2D40FFFC
0x00000022 0x202EFFFC
0x00000026 0x206E0010
0x0000002A 0x222EFFFC
0x0000002E 0x202EFFF8
0x00000032 0xD0B01C00
0x00000036 0x0A8000000002
move.l
subq.l
move.l
bra.s
12(a6),d0
#1,d0
d0,-12(a6)
*+50
move.l
move.l
move.l
movea.l
move.l
move.l
add.l
eori.l
-12(a6),d0
d0,-4(a6)
-4(a6),d0
16(a6),a0
-4(a6),d1
-8(a6),d0
(a0,d1.l*4),d0
#0x2,d0
;
; '....'
set 3 -- 16
Example sumsq
0x0000003C
0x00000040
0x00000044
0x00000046
0x0000004A
0x0000004E
0x00000050
;
; 17:
;
0x00000052
0x00000056
0x0000005A
;
; 18: }
0x0000005C
0x0000005E
0x2D40FFF8
0x202EFFF4
0x5380
0x2D40FFF4
0x202EFFF4
0x4A80
0x6DC8
move.l
move.l
subq.l
move.l
move.l
tst.l
blt.s
d0,-8(a6)
-12(a6),d0
#1,d0
d0,-12(a6)
-12(a6),d0
d0
*-54
; 0x0000001a
*sum=total;
0x206E0008
0x202EFFF8
0x2080
movea.l 8(a6),a0
move.l -8(a6),d0
move.l d0,(a0)
0x4E5E
0x4E75
unlk
rts
a6
set 3 -- 17