Lecture2

  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Lecture2 as PDF for free.

More details

  • Words: 3,724
  • Pages: 51
The C preprocessor

Hardware interfacing

Embedded Systems Programming Lecture 2 Ver´ onica Gaspes www2.hh.se/staff/vero

Center for Research on Embedded Systems School of Information Science, Computer and Electrical Engineering

November 6, 2008

The C execution model

The C preprocessor

Hardware interfacing

The C execution model

The preprocessor

Before the compiler starts transforming your program to executable code (for your computer or for another processor) the preprocessor does some textual manipulation to the source. Macro expansion Textually replace definitions. File insertion Include files as if you had written the code in your files. Instructions to the compiler For example not to compile certain parts of the program.

The C preprocessor

Hardware interfacing

The C execution model

The preprocessor

Before the compiler starts transforming your program to executable code (for your computer or for another processor) the preprocessor does some textual manipulation to the source. Macro expansion Textually replace definitions. File insertion Include files as if you had written the code in your files. Instructions to the compiler For example not to compile certain parts of the program.

The C preprocessor

Hardware interfacing

The C execution model

The preprocessor

Before the compiler starts transforming your program to executable code (for your computer or for another processor) the preprocessor does some textual manipulation to the source. Macro expansion Textually replace definitions. File insertion Include files as if you had written the code in your files. Instructions to the compiler For example not to compile certain parts of the program.

The C preprocessor

Hardware interfacing

The C execution model

The preprocessor

Before the compiler starts transforming your program to executable code (for your computer or for another processor) the preprocessor does some textual manipulation to the source. Macro expansion Textually replace definitions. File insertion Include files as if you had written the code in your files. Instructions to the compiler For example not to compile certain parts of the program.

The C preprocessor

Hardware interfacing

The C execution model

Macros

The program . . . #define SIZE 5 #define init(v) x=v;y=v;z=v main(){ int x,y,z; init(SIZE); }

becomes main(){ int x,y,z; x=5;y=5;z=5; }

before compiling.

The C preprocessor

Hardware interfacing

The C execution model

Macros

The program . . . #define SIZE 5 #define init(v) x=v;y=v;z=v main(){ int x,y,z; init(SIZE); }

becomes main(){ int x,y,z; x=5;y=5;z=5; }

before compiling.

The C preprocessor

Hardware interfacing

The C execution model

Including Files In C, larger programs are organized in files (there is no notion of a module like classes in Java). Interfaces and implementations can anyway be separate in header files and implementation files. There are preprocessor instructions to include header files. typedef struct {int x;int y;} Pt; #define initPoint(a,b) { a, b } double distanceO (Pt *p1);

point.h

#include "point.h" #include <math.h> double distanceO (Pt *p1){ return sqrt(p1->x*p1->x + p1->y*p1->y); }

point.c

The C preprocessor

Hardware interfacing

The C execution model

Including Files In C, larger programs are organized in files (there is no notion of a module like classes in Java). Interfaces and implementations can anyway be separate in header files and implementation files. There are preprocessor instructions to include header files. typedef struct {int x;int y;} Pt; #define initPoint(a,b) { a, b } double distanceO (Pt *p1);

point.h

#include "point.h" #include <math.h> double distanceO (Pt *p1){ return sqrt(p1->x*p1->x + p1->y*p1->y); }

point.c

The C preprocessor

Hardware interfacing

The C execution model

Including Files In C, larger programs are organized in files (there is no notion of a module like classes in Java). Interfaces and implementations can anyway be separate in header files and implementation files. There are preprocessor instructions to include header files. typedef struct {int x;int y;} Pt; #define initPoint(a,b) { a, b } double distanceO (Pt *p1);

point.h

#include "point.h" #include <math.h> double distanceO (Pt *p1){ return sqrt(p1->x*p1->x + p1->y*p1->y); }

point.c

The C preprocessor

Hardware interfacing

The C execution model

Including Files In C, larger programs are organized in files (there is no notion of a module like classes in Java). Interfaces and implementations can anyway be separate in header files and implementation files. There are preprocessor instructions to include header files. typedef struct {int x;int y;} Pt; #define initPoint(a,b) { a, b } double distanceO (Pt *p1);

point.h

#include "point.h" #include <math.h> double distanceO (Pt *p1){ return sqrt(p1->x*p1->x + p1->y*p1->y); }

point.c

The C preprocessor

Hardware interfacing

The C execution model

Including files Programs can now use points as follows The program . . .

becomes

#include "point.h" #include <stdio.h> main(){ Pt p = initPoint(3,4); printf("%f\n", distanceO(&p)); }

typedef struct {int x;int y;} Pt; double distanceO (Pt *p1); main(){ Pt p = { 3, 4 }; printf("%f\n",distanceO(&p)); } after preprocessor (I do not show the expansion of stdio.h!)

To compile you will need to do gcc usepoints.c point.o

The C preprocessor

Hardware interfacing

The C execution model

Including files Programs can now use points as follows The program . . .

becomes

#include "point.h" #include <stdio.h> main(){ Pt p = initPoint(3,4); printf("%f\n", distanceO(&p)); }

typedef struct {int x;int y;} Pt; double distanceO (Pt *p1); main(){ Pt p = { 3, 4 }; printf("%f\n",distanceO(&p)); } after preprocessor (I do not show the expansion of stdio.h!)

To compile you will need to do gcc usepoints.c point.o

The C preprocessor

Hardware interfacing

The C execution model

Including files Programs can now use points as follows The program . . .

becomes

#include "point.h" #include <stdio.h> main(){ Pt p = initPoint(3,4); printf("%f\n", distanceO(&p)); }

typedef struct {int x;int y;} Pt; double distanceO (Pt *p1); main(){ Pt p = { 3, 4 }; printf("%f\n",distanceO(&p)); } after preprocessor (I do not show the expansion of stdio.h!)

To compile you will need to do gcc usepoints.c point.o

The C preprocessor

Hardware interfacing

The C execution model

Including files Programs can now use points as follows The program . . .

becomes

#include "point.h" #include <stdio.h> main(){ Pt p = initPoint(3,4); printf("%f\n", distanceO(&p)); }

typedef struct {int x;int y;} Pt; double distanceO (Pt *p1); main(){ Pt p = { 3, 4 }; printf("%f\n",distanceO(&p)); } after preprocessor (I do not show the expansion of stdio.h!)

To compile you will need to do gcc usepoints.c point.o

The C preprocessor

Hardware interfacing

The C execution model

Instructions to the compiler You might want to compile different versions of your program (targetting different platforms or including debugging printouts) or you might want to include a header file only once while several parts of the program have to include it The program . . . #include "debug.h" #include <stdio.h> main(){ #ifdef DEBUG printf("in debug mode"); #endif printf("what has to be done ..."); }

Is realy two programs, depending on the content of debug.h! If the definition #define DEBUG is there the preprocessor leaves the debugging statement, otherwise it removes it (a smaller program gets compiled)

The C preprocessor

Hardware interfacing

The C execution model

Instructions to the compiler You might want to compile different versions of your program (targetting different platforms or including debugging printouts) or you might want to include a header file only once while several parts of the program have to include it The program . . . #include "debug.h" #include <stdio.h> main(){ #ifdef DEBUG printf("in debug mode"); #endif printf("what has to be done ..."); }

Is realy two programs, depending on the content of debug.h! If the definition #define DEBUG is there the preprocessor leaves the debugging statement, otherwise it removes it (a smaller program gets compiled)

The C preprocessor

Hardware interfacing

The C execution model

Instructions to the compiler You might want to compile different versions of your program (targetting different platforms or including debugging printouts) or you might want to include a header file only once while several parts of the program have to include it The program . . . #include "debug.h" #include <stdio.h> main(){ #ifdef DEBUG printf("in debug mode"); #endif printf("what has to be done ..."); }

Is realy two programs, depending on the content of debug.h! If the definition #define DEBUG is there the preprocessor leaves the debugging statement, otherwise it removes it (a smaller program gets compiled)

The C preprocessor

Hardware interfacing

The C execution model

The naked computer

CPU

CPU r the neve Whe ds a read n fi ction instru

ite wr

write

re

ad

d

rea Port

ser eu r th g eve ethin n e Wh s som e typ

When ever finds a the CPU w instru rite ction

RAM

Port

Every ? seconds

The C preprocessor

Hardware interfacing

The C execution model

The naked computer We first concentrate on how to read and write to IO ports and leave synchronization for later on

CPU

CPU r the neve Whe ds a read fin ction instru

ite wr

write

re

ad

d

rea Port

When ever finds a the CPU w instru rite ction

RAM

Port

The C preprocessor

Hardware interfacing

The C execution model

IO hardware

Access to devices is via a set of registers, both to control the device operation and for data transfer. There are 2 general classes of architecture. Memory mapped Some addresses are reserved for device registers! Typically they have names provided in some platform specific header file.

Separate bus Different assembler instructions for memory access and for device registers.

The C preprocessor

Hardware interfacing

The C execution model

IO hardware Access to devices is via a set of registers, both to control the device operation and for data transfer. There are 2 general classes of architecture. Memory mapped Some addresses are reserved for device registers! Typically they have names provided in some platform specific header file.

Separate bus Different assembler instructions for memory access and for device registers.

The C preprocessor

Hardware interfacing

The C execution model

IO hardware Access to devices is via a set of registers, both to control the device operation and for data transfer. There are 2 general classes of architecture. Memory mapped Some addresses are reserved for device registers! Typically they have names provided in some platform specific header file.

Separate bus Different assembler instructions for memory access and for device registers.

The C preprocessor

Hardware interfacing

The C execution model

Memory mapped – things to think about The documentation of a microprocessor will let you know what addresses correspond to what ports. These addresses can be used in the program as pointers. The type of the pointers depends on the size of the port.

Reading and writing is done as with ordinary variables *port1 // read *port1 = value; // write

Would you do this in a program? char * port1; // 8 bits int * port2; // 16 bits

*port = x; x = *port; Yes if it is IO! The compiler should not optimize this away:

Use unsigned to avoid confusions with signed values!

volatile int * port;

The C preprocessor

Hardware interfacing

The C execution model

Memory mapped – things to think about The documentation of a microprocessor will let you know what addresses correspond to what ports. These addresses can be used in the program as pointers. The type of the pointers depends on the size of the port.

Reading and writing is done as with ordinary variables *port1 // read *port1 = value; // write

Would you do this in a program? char * port1; // 8 bits int * port2; // 16 bits

*port = x; x = *port; Yes if it is IO! The compiler should not optimize this away:

Use unsigned to avoid confusions with signed values!

volatile int * port;

The C preprocessor

Hardware interfacing

The C execution model

Memory mapped – things to think about The documentation of a microprocessor will let you know what addresses correspond to what ports. These addresses can be used in the program as pointers. The type of the pointers depends on the size of the port.

Reading and writing is done as with ordinary variables *port1 // read *port1 = value; // write

Would you do this in a program? char * port1; // 8 bits int * port2; // 16 bits

*port = x; x = *port; Yes if it is IO! The compiler should not optimize this away:

Use unsigned to avoid confusions with signed values!

volatile int * port;

The C preprocessor

Hardware interfacing

The C execution model

Memory mapped – things to think about The documentation of a microprocessor will let you know what addresses correspond to what ports. These addresses can be used in the program as pointers. The type of the pointers depends on the size of the port.

Reading and writing is done as with ordinary variables *port1 // read *port1 = value; // write

Would you do this in a program? char * port1; // 8 bits int * port2; // 16 bits

*port = x; x = *port; Yes if it is IO! The compiler should not optimize this away:

Use unsigned to avoid confusions with signed values!

volatile int * port;

The C preprocessor

Hardware interfacing

The C execution model

Memory mapped – things to think about The documentation of a microprocessor will let you know what addresses correspond to what ports. These addresses can be used in the program as pointers. The type of the pointers depends on the size of the port.

Reading and writing is done as with ordinary variables *port1 // read *port1 = value; // write

Would you do this in a program? char * port1; // 8 bits int * port2; // 16 bits

*port = x; x = *port; Yes if it is IO! The compiler should not optimize this away:

Use unsigned to avoid confusions with signed values!

volatile int * port;

The C preprocessor

Hardware interfacing

The C execution model

Memory Mapped – more things to think about! Addresses and ports The same address may refer to two different registers: one used when reading (check device status) and one used when writing (giving commands to a device). example #define #define #define #define

IS_READY (1 CONVERT (1 STATUS_REG CMD_REG

<< 5) << 5) *((char*)0x34c) *((char*)0x34c)

if (STATUS_REG & IS_READY) {CMD_REG = CONVERT;}

Fortunately all ports in AVR are read/write!

The C preprocessor

Hardware interfacing

The C execution model

Shadowing These registers are better used via a shadow variable (another address! instead of just a def!) #define CONVERT (1<<5) #define CMD_REG *((char *)0x34c) char cmd_shadow; ... cmd_shadow = cmd_shadow | CONVERT; CMD_REG = cmd_shadow;

Notice All changes to CMD REG should be reflected in cmd shadow!

The C preprocessor

Hardware interfacing

The C execution model

Misc

Single write It is not always needed to read the value of the port when doing a modification. In some cases you know exactly what value should be written to the port. #define CTRL (1<<3) #define SIZE1 (1<<4) #define SIZE2 (2<<4) #define FLAG (1<<6) CMD_REG = FLAG | SIZE2 | CTRL;

The C preprocessor

Hardware interfacing

The C execution model

Separate I/O Bus

The port registers are accessed via special assembler instructions, usually made available to a C program as preprocessor macros. QNX real-time OS Macros like in8, out8, in16, out16 that are used as in unsigned char val = in8(0x30d); out32(0xf4,expr);

As you see, they cannot be used as ordinary variables!

The C preprocessor

Hardware interfacing

The C execution model

I/O Synchronisation

CPU

CPU r the neve Whe ds a read fin on ti c u instr

ite

wr

write

re

ad

d

rea Port

When ever finds a the CPU w instru rite ction

RAM

Port

ser

u the ver thing e ene Wh s som e typ

How does the software become aware of changes in the key status?

Every ? seconds

2 models interrupt driven (more on this later in the course) status driven (today and lab1)

The C preprocessor

Hardware interfacing

The C execution model

Busy Waiting In the status driven model the CPU polls the status registers until a change occurs Example int old = KEY_STATUS_REG; int val = old; while(old==val){ val = KEY_STATUS_REG; } On leaving the loop the status has changed!

The CPU is busy but is doing nothing useful!

The CPU has no control over when to exit the loop! What if KEY STATUS REG were an ordinary variable?

The C preprocessor

Hardware interfacing

The C execution model

Busy Waiting In the status driven model the CPU polls the status registers until a change occurs Example int old = KEY_STATUS_REG; int val = old; while(old==val){ val = KEY_STATUS_REG; } On leaving the loop the status has changed!

The CPU is busy but is doing nothing useful!

The CPU has no control over when to exit the loop! What if KEY STATUS REG were an ordinary variable?

The C preprocessor

Hardware interfacing

The C execution model

Busy Waiting In the status driven model the CPU polls the status registers until a change occurs Example int old = KEY_STATUS_REG; int val = old; while(old==val){ val = KEY_STATUS_REG; } On leaving the loop the status has changed!

The CPU is busy but is doing nothing useful!

The CPU has no control over when to exit the loop! What if KEY STATUS REG were an ordinary variable?

The C preprocessor

Hardware interfacing

The C execution model

Busy Waiting In the status driven model the CPU polls the status registers until a change occurs Example int old = KEY_STATUS_REG; int val = old; while(old==val){ val = KEY_STATUS_REG; } On leaving the loop the status has changed!

The CPU is busy but is doing nothing useful!

The CPU has no control over when to exit the loop! What if KEY STATUS REG were an ordinary variable?

The C preprocessor

Hardware interfacing

The C execution model

Busy waiting

Why is it so appealing? It can be used to define functions that make input look like reading variables (reading from memory!) char getchar(){ while(KEY_STATUS_REG & PRESSED); while(!(KEY_STATUS_REG & PRESSED)); return KEY_VALUE_REG; }

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program The following slides illustrate what happens in program memory when a C program is executed. We will refer to it later on when we introduce support for concurrent execution threads. Stack

Code

Locals of a() SP

a(){ int x;

x = PC

...

}

Globals v = 0 w = 0 v u = 0

The C preprocessor

Hardware interfacing

Execution of a C program

Stack

Code

Locals of a() SP

a(){ int x;

x = PC

...

}

Globals v = 0 w = 0 v u = 0

The C execution model

The C preprocessor

Hardware interfacing

Execution of a C program

Stack

Code

Locals of a() SP

a(){ int x;

x = 9 x = 9; w = 6; ...

PC

}

Globals v = 0 w = 6 u = 0

The C execution model

The C preprocessor

Hardware interfacing

Execution of a C program

Stack

Code

Locals of a() SP

a(){ int x;

x = 9 x = 9; w = 6; b(55);

PC

}

Globals v = 0 w = 6 u = 0

The C execution model

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack Locals of a() x = 9

SP

Code a(){ int x; x = 9; w = 6; b(55);

Locals of b() y = 55

b(int y){ PC

... }

}

Globals v = 0 w = 6 u = 0

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack Locals of a() x = 9

SP

Code a(){ int x; x = 9; w = 6; b(55);

Locals of b() y = 55

b(int y){ ... y = c();

PC

} }

Globals v = 0 w = 6 u = 0

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack Locals of a()

Code a(){ int x;

x = 9

c(){

b(int y){

int z = 23;

x = 9; w = 6; b(55);

Locals of b() y = 55

SP

}

Locals of c() z = 23 }

Globals v = 0 w = 6 u = 0

... y = c();

... PC

}

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack Locals of a()

Code a(){ int x;

x = 9

c(){

b(int y){

int z = 23;

x = 9; w = 6; b(55);

Locals of b() y = 55

SP

}

Locals of c() z = 23 }

Globals v = 0 w = 77 u = 0

... y = c(); PC

w = 77; ... }

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack Locals of a()

Code a(){ int x;

x = 9

c(){

b(int y){

int z = 23;

x = 9; w = 6; b(55);

Locals of b() y = 55

SP

}

Locals of c() z = 23 }

Globals v = 0 w = 77 u = 0

... y = c();

w = 77; return z; PC

}

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack Locals of a()

Code a(){ int x;

b(int y){

x = 9

c(){ int z = 23;

SP

x = 9; w = 6; b(55);

Locals of b() y = 23

... y = c(); PC

}

Globals v = 0 w = 77 u = 0

}

w = 77; return z;

}

The C preprocessor

Hardware interfacing

The C execution model

Execution of a C program

Stack

Code

Locals of a() SP

a(){ int x;

x = 9

b(int y){

c(){ int z = 23;

x = 9; w = 6; b(55); ...

PC

... y = c(); }

}

Globals v = 0 w = 77 u = 0

w = 77; return z;

}

The C preprocessor

Hardware interfacing

The C execution model

2 CPUs?

Imagine we had 2 CPUs, then we could run two programs at the same time! One way of programming this in only 1 CPU is to keep track of 2 stack pointers and 2 program counters! How to do this is the content of lecture 4.

The C preprocessor

Hardware interfacing

The C execution model

Comming next

Lecture 3 Discuss an example from embedded systems programming. Show a cyclic executive design Motivate the need for concurrent programming. Discuss the mutual exclusion problem. Lecture 4 Show what is needed to implement threads (maybe also mutexes).

Related Documents

Lecture2
June 2020 14
Lecture2
November 2019 20
Lecture2
July 2020 10
Lecture2
November 2019 14
Lecture2
June 2020 11
Lecture2.ppt
November 2019 11