topic07 introduction to embedded c programming

Upload: brett-wildermoth

Post on 04-Apr-2018

223 views

Category:

Documents


0 download

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