topic07 introduction to embedded c programming
TRANSCRIPT
-
7/29/2019 Topic07 Introduction to Embedded C Programming
1/34
C Programming for EmbeddedSystems 7
1Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
2/34
What happens when you compile?
2Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
3/34
The role of the Preprocessor
The preprocessor performs the following tasks:
Expands all macros (#define / macro operand)
Inserts the include files inline.
Creates a temporary C file.
3Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
4/34
The role of the Compiler
The compiler translates the C code into assembler andperforms optimization on the assembly code.
Using a standard assembly translation of the C control
structures.
4Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
5/34
The role of the Assembler
Converts the assembly source code into relocatablebinary.
This binary code is executable by the target, but it has
not been allocated space in the target.
5Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
6/34
The role of the Archive Utility
The archive utility is able to package your relocatablebinary into a library that can be used at a later date.
6Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
7/34
The role of the Linker and Locator
The linker is responsible for sorting out where the code andvariables are to be allocated in the memory of the Target.
Code is generally allocated into ROM and variables into RAM.
The linker checks to ensure that the code is smaller enough tofit inside the ROM of the Target.
It also ensures that there is adequate space in RAM for both theprogram variables and stack.
Because function parameters are passed via the stack and localvariables also live on the stack. The linker is able to calculatehow big the stack must be.
7Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
8/34
How to create a successful Build System?
The most important thing that is required is a hostsystem.
The hosts system should have: A Cross-compiler (runs natively on the host, but
builds binaries for our Target).
A set of Target Libraries (Optional)
A Debugger (JTAG/BDM),
A Simulator/ Emulator (optional) and
A Binary Loader for our Target.8Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
9/34
What does the Build System require?
Knowing what the compiler does it is clear that it willrequire some information about our Target.
Things like:
Where is the memory for code located? Where should variables go?
How much space do I have for each?
How can I access the I/O registers from inside C? How can I setup the Interrupt Vector Table?
How can I embedded assembly instructions in my
C code?9Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
10/34
Memory Map
How do we describe the physical hardware to our Ccompiler (the linker).
Many mainstream IDEs allow this to be done througha project settings menu.
In Code Warrior this is done automatically when youchoose the derivative of the HS12 during the new
project wizard.
In GCC this requires a text file to be created.
10Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
11/34
Memory MapMEMORY
{
page0 (rwx) : ORIGIN = 0x0, LENGTH = 2k /* I/O Registers */
eeprom (rwx) : ORIGIN = 0x0C00, LENGTH = 1k /* EEPROM */
text (rwx) : ORIGIN = 0x4000, LENGTH = 16k /* Code space [Flash] */
data : ORIGIN = 0x2000, LENGTH = 4k /* Variable Space */
}
PROVIDE (_stack = 0x03FFF); /* Starting point of Stack */
memory.x11Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
12/34
Accessing I/O Registers In C it is possible to define variables that reside in
a predetermined memory location.
This is done by assigning a pointer to a particularlocation and then dereferencing that pointer.
Since most of our I/O registers are 8 bit in sizethey are the same size as an unsigned char
variable. Since the I/O registers are not constant and
change as a result of external events they can beconsidered volatile unsigned chars.
12Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
13/34
Accessing I/O Registers
so an IO register can be mapped to a variable in thefollowing fashion:
#define PORTA *(unsigned char volatile *) (0x0000)
The value 0x0000 refers to the memory location$0000 that is of type volatile unsigned charwhichis given the name PORTA.
13Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
14/34
Accessing I/O Registers
The PORTA data register can then be accessedfrom within C as if it was a normal variable.
Reading from PORTAC= PORTA;
Writing to PORTAPORTA=0xFF;
14Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
15/34
Interrupts in C
Interrupt service routines are defined in C as standard void functions.void ISR(void)
But a standard C function is the same as a subroutine in assembly. It isterminated with an RTS. How then do we tell the compiler this is an ISR andtherefore should terminate with an RTI instead.
Every compiler uses a different method of declaring interrupt serviceroutines, so it pays to look it up in the compilers manual.
Some examples void __attribute__((interrupt)) ISR(void); (GCC)
void __interrupt(vector_address) ISR (void); (Tasking 8051)
15Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
16/34
Interrupts in C
Interrupt service routines are defined in C as standard void functions.void ISR(void)
But a standard C function is the same as a subroutine in assembly. It isterminated with an RTS. How then do we tell the compiler this is an ISR andtherefore should terminate with an RTI instead.
Every compiler uses a different method of declaring interrupt serviceroutines, so it pays to look it up in the compilers manual.
Some examples void __attribute__((interrupt)) ISR(void); (GCC)
void __interrupt(vector_address) ISR (void); (Tasking 8051)
15Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
17/34
Interrupts in C
Interrupt service routines are defined in C as standard void functions.void ISR(void)
But a standard C function is the same as a subroutine in assembly. It is
terminated with an RTS. How then do we tell the compiler this is an ISR andtherefore should terminate with an RTI instead.
Every compiler uses a different method of declaring interrupt serviceroutines, so it pays to look it up in the compilers manual.
Some examples void __attribute__((interrupt)) ISR(void); (GCC)
void __interrupt(vector_address) ISR (void); (Tasking 8051)
15Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
18/34
Interrupts in C
Interrupt service routines are defined in C as standard void functions.void ISR(void)
But a standard C function is the same as a subroutine in assembly. It is
terminated with an RTS. How then do we tell the compiler this is an ISR andtherefore should terminate with an RTI instead.
Every compiler uses a different method of declaring interrupt serviceroutines, so it pays to look it up in the compilers manual.
Some examples void __attribute__((interrupt)) ISR(void); (GCC)
void __interrupt(vector_address) ISR (void); (Tasking 8051)
15Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
19/34
Defining the Vector Table
Some compiler link the ISR to the vector tableautomatically for you.
Others, like the GCC compiler require you to do itmanually.
In GCC the ISR is inserted in the Vector table by definingthe table in GCC assembly.
16Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
20/34
Defining the Vector Table
.sect .vectors
.globl vectors
.globl vectors_addr
vectors_addr=0XFFF0
def=0x0000;
vectors:
.word def ; FFF0
.word ISR ; FFF2
.word def ; FFF4
.word def ; FFF6
.word def ; FFF8
.word def ; FFFA
.word def ; FFFC
.word _start ; FFFE (reset)
Tells Linker to put this in the vectors section of the memory map.
Defines vectors and vector_addr to be global variables.
Variables
Vector Table in GCC-AS.word is the equivalent to DC.W
vector.s17Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
21/34
Defining the Vector Table
.sect .vectors
.globl vectors
.globl vectors_addr
vectors_addr=0XFFF0
def=0x0000;
vectors:
.word def ; FFF0
.word ISR ; FFF2
.word def ; FFF4
.word def ; FFF6
.word def ; FFF8
.word def ; FFFA
.word def ; FFFC
.word _start ; FFFE (reset)
Tells Linker to put this in the vectors section of the memory map.
Defines vectors and vector_addr to be global variables.
Variables
Vector Table in GCC-AS.word is the equivalent to DC.W
Same name as as our ISR
vector.s17Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
22/34
Defining the Vector Table
.sect .vectors
.globl vectors
.globl vectors_addr
vectors_addr=0XFFF0
def=0x0000;
vectors:
.word def ; FFF0
.word ISR ; FFF2
.word def ; FFF4
.word def ; FFF6
.word def ; FFF8
.word def ; FFFA
.word def ; FFFC
.word _start ; FFFE (reset)
Tells Linker to put this in the vectors section of the memory map.
Defines vectors and vector_addr to be global variables.
Variables
Vector Table in GCC-AS.word is the equivalent to DC.W
vector.s
17Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
23/34
Defining the Vector Table
.sect .vectors
.globl vectors
.globl vectors_addr
vectors_addr=0XFFF0
def=0x0000;
vectors:
.word def ; FFF0
.word ISR ; FFF2
.word def ; FFF4
.word def ; FFF6
.word def ; FFF8
.word def ; FFFA
.word def ; FFFC
.word _start ; FFFE (reset)
Tells Linker to put this in the vectors section of the memory map.
Defines vectors and vector_addr to be global variables.
Variables
Vector Table in GCC-AS.word is the equivalent to DC.W
Program starts in the functionnamed _start.
vector.s
17Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
24/34
Defining the Vector Table
.sect .vectors
.globl vectors
.globl vectors_addr
vectors_addr=0XFFF0
def=0x0000;
vectors:
.word def ; FFF0
.word ISR ; FFF2
.word def ; FFF4
.word def ; FFF6
.word def ; FFF8
.word def ; FFFA
.word def ; FFFC
.word _start ; FFFE (reset)
Tells Linker to put this in the vectors section of the memory map.
Defines vectors and vector_addr to be global variables.
Variables
Vector Table in GCC-AS.word is the equivalent to DC.W
vector.s
17Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
25/34
Assembly in C
If you want to include assembly code into your Cprogram this can be done using a keyword asm. Eachcompiler is different so it pays to look it up.
__asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
Tasking 8051 compiler
18Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
26/34
Assembly in C
asm ( assembler template: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
GCC Compiler
19Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
27/34
Assembly in CGCC Example
#define SaveContext(TaskID)\
asm("LDD 8,SP\n\tSTD %0"::"m"(Tasks[TaskID].context.CCR));\ asm("LDD 8+2,SP\n\tSTD %0"::"m"(Tasks[TaskID].context.D));\ asm("LDD 8+4,SP\n\tSTD %0"::"m"(Tasks[TaskID].context.IX));\ asm("LDD 8+6,SP\n\tSTD %0"::"m"(Tasks[TaskID].context.IY));\ asm("LDD 8+8,SP\n\tSTD %0"::"m"(Tasks[TaskID].context.PC));\ asm("TFR SP,D\n\tADDD #8+10\n\tSTD%0"::"m"(Tasks[TaskID].context.SP));
20Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
28/34
Pros
Allows fast software developments.
Easy readable code.
Access to C profilers and debuggers. Can be prototyped on the host.
Simpler Better error detection
21Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
29/34
Cons
Limited control over resulting binary. Simplest programs suffer from bloat.
Code tends to run slower in C than it wouldif develop in Assembler.
Code is bigger in size.
Compilers can be expensive. Can be difficult when mixing assembler with
C...
22Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
30/34
Putting it all togetherAn example using GCC
Ensure you have installed the gcc-68hc1x compiler +binutils-68hc1x (available from http://www.gnu-m68hc11.org/m68hc11_pkg_rpm.php).
Having created both the memory.x and vector.s files.
Firstly assemble the vectors.s file
m6811-elf-as -m68hcs12 -mshort vectors.s -o vectors.o
23Monday, 11 October 2010
http://www.gnu-m68hc11.org/m68hc11_pkg_rpm.phphttp://www.gnu-m68hc11.org/m68hc11_pkg_rpm.phphttp://www.gnu-m68hc11.org/m68hc11_pkg_rpm.phphttp://www.gnu-m68hc11.org/m68hc11_pkg_rpm.phphttp://www.gnu-m68hc11.org/m68hc11_pkg_rpm.php -
7/29/2019 Topic07 Introduction to Embedded C Programming
31/34
Putting it all togetherAn example using GCC
Type in this simple program
#define PORTA *(unsigned char volatile *) (0x0000)
#define DDRA *(unsigned char volatile *) (0x0002)
void main(void){
unsigned char a=0;
DDRA=0xFF;while(1) PORTA=a++;
}
Test.c
24Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
32/34
Putting it all togetherAn example using GCC
The C source is compiled using the followingcommand (ensure memory.x and vectors.o is in thesame directory).
m6811-elf-gcc -mshort -m68hcs12 -o Test.elf Test.c vectors.o memory.x
Converted to an SREC usingm6811-elf-objcopy -O srec Test.elf Test.s19
25Monday, 11 October 2010
-
7/29/2019 Topic07 Introduction to Embedded C Programming
33/34
Putting it all togetherAn example using GCC
Finally the resulting file Test.s19 can beuploaded to the Adapt9S12X using a linuxtool called binload.
A modified version of binload is available onrequest from your demonstrators.
26Monday, 11 October 2010
Need Further
-
7/29/2019 Topic07 Introduction to Embedded C Programming
34/34
Need Further
Assistance?
Ask your Demonstrator,
Post a question on the Forum, Email the Convener, or
Make an appointment.
27Monday, 11 October 2010