Grundläggande C-programmering - För maskinorienterad programmering Ulf Assarsson Läromoment: Datatyper, typedef, #define, struct, arrayer, synlighet Preprocessing, kompilering, länkning IDE,.c- /.h-filer, Inför: Programmering av grafisk LCD-display Kopplat?ll: Arbetsbok kap 5 Lab 2 + Lab 3 Läsanvisningar: Arbetsbok 82-93 Datablad LCD - Grafisk
C Bakgrund Short Code, 1949, 1:st high level language Autocode, early 50 ies. Fortran, IBM, ~57. Lisp, 58. Cobol 60 (Common Business-oriented language. BASIC, 1964. ALGOL 60 (ALGOrithmic Language 1960). Simula, 60:ies. C, ~1969. Prolog, 1972. Ada, ~1975 Pascal, ~1975. ML, 1978. 2
C Bakgrund Maskinnära programmering: Behöver språk med pekare?ll absoluta adresser Basic, Ada 95 (och senare versioner), C, C++, C# (med nyckelordet unsafe), Objec?ve-C, D, COBOL, Fortran. C - 1969 C++ - 1983 (Ada 1995) C# - 2000 D - 2001 3
C Historik B, Bell Labs ~1969 C: Utvecklades först 1969 1973 av Dennis Ritchcie vid AT&T Bell Labs. Högnivå språk med kontakt mot maskinvara. Ef utav de mest använda språken. 4
C respek?ve Assembler Varför C istället för assembler? Färre rader kod, mindre risk för fel, snabbare Varför förstå hur C kompileras?ll assembler? prestandaop?mering och resonera kring prestanda ( tex för datorgrafik, GPU:er, HPC). Hur mycket snabbare är en while-loop än rekursion? Loop-unroll? energikonsump?on säkerhet/robusthet/risker Kunna debugga Kunna mixa C/asm vid drivru?nsprogrammering eller prestandakri?ska förlopp. RTI return from interupt (behövs dock ej för cortex-m4) SIMD: Intel s SSE 5
Översikt C fyra lek?oner Lekt 1: IDE, variabler (dekl. +?lldeln.), typkonverteringar, ASCII, funk?oner, variabelsynlighet, programstruktur, kompilering/länkning, define, typedef, structs pekare,. Lekt 2: Pekare forts, pekare?ll funk?oner, vola?le, portadressering, structs med funk?onspekare Lekt 3: unions, #include-guards, mer källkodstruktur, Kodningskonven?oner: minneshantering, funk?onsanrop, adressrymd, stack frame, Lekt 4: dubbelpekare, mixa C och assembler 6
C Standarder 1978, K&R C (Kernighan & Ritchie) 1989, C89/C90 (ANSI-C) 1999, C99 (Rev. ANSI-standard) 2011, C11 (Rev. ANSI-standard) 7
Hello world! program #include <stdio.h> int main() printf( Hello World!\n"); return 0; 8
C vs Java. Några skillnader: C: saknar klasser. Har dock structs för sammansafa datatyper. struct Course char* name; float credits; int numberofparticipants; ; Booleans är ej egen typ. true/false finns ej. 0 är false. Ef värde!= 0 är true. Därför definierar man osa TRUE/FALSE som 1 resp 0. 1 && 1 = Implementa?onsspecifikt för kompilatorn. 9
Mer C: Type conversion default: convert narrower format to the wider format Synlighet: global synlighet, synlighet i funk?on resp scope. #include <stdio.h> int x; int foo(int x) if( x == 0 ) int x = 4; return x; return x; float a; a = 1.0 / 3; // a == 0.33333343 int main() x = 1; x = foo(0); printf("x is %i", x); return 0; 10
Integrerad utvecklings miljö (IDE) Kör Bygg T ex CodeLite som är gra?s och open-source. (hfp://codelite.org/ ) hfp://www.cse.chalmers.se/edu/course/eda481_6/index.html 11
Från terminalen > gcc o hello.exe main.c > hello.exe Hello World! > Bygg Kör 12
Ef Programs Adressrymd Alla program som körs, har något associerat minne, vilket typiskt är indelat i: Code Segment Data Segment (Holds Global Data) Stack (where the local variables and other temporary informa?on is stored) Heap The Stack grows downwards Stack The Heap grows upwards Heap Data Segment Ökande adresser Code Segment
Variabler #include <stdio.h> int x; int main() char y; x = 32; y = 'a'; x = x + y; Typ Variabelnamn printf("x har nu värdet %i och y har värdet %i som kodar tecknet %c\n", x, (int)y, y); return 0; Utskris: x har nu värdet 129 och y har värdet 97 som kodar tecknet a 14
Deklara?oner och?lldelningar #include <stdio.h> int x; int main() char y; x = 32; y = 'a'; Deklara?oner Tilldelningar x = x + y; printf("x har nu värdet %i och y har värdet %i som kodar tecknet %c\n", x, (int)y, y); return 0; En deklarerad variabel som ännu inte?lldelats ef värde är oini)erad 15
Typkonverteringar #include <stdio.h> int x; int main() char y; Implicit typkonvertering x = 32; y = 'a'; x = x + y; Explicit typkonvertering printf("x har nu värdet %i och y har värdet %i som kodar tecknet %c\n", x, (int)y, y); return 0; Typkonvertering kallas också cast, och man säger af man castar. 16
ASCII Finns det bara en ASCII-tabell? Finns flera olika ASCII extensions (övre 128 värdena), beroende på språk. ISO 8859-1, also called ISO La)n 1, ISO 8859-2 for Eastern European languages, and ISO 8859-5 for Cyrillic languages (Terminaler använder inte nödvändigtvis ASCII-tabellen Console däremot osast.) 17
C89 deklara?oner först #include <stdio.h> int x; int main() x = 32; En?lldelning innan deklara?onerna är EJ?llåtet enligt C89 char y = 'a'; x = x + y; printf("x har nu värdet %i och y har värdet %i som kodar tecknet %c\n", x, (int)y, y); return 0; Fungerar ibland ändå (t ex i CodeLite), men för vår ARM-kompilator måste C99 explicit anges som kompilatorflagga. 18
Enable C99 Sd 19
Funk?oner #include <stdlib.h> int foo(int x, char y) int sum = 0; argument while(y-- > 0) sum += x*y; return sum; Returvärde av returtyp Argumenten är pass-by value. int var1; char var2 = 7; var1 = foo(5, var2); var2 har forwarande värdet 7 eser funk?onsanropet 20
Synlighet/Visibility/Scope Global synlighet (global scope) Filsynlighet (file scope) Lokal synlighet (e.g. func?on scope) 21
Synlighet #include <stdlib.h> char x; int foo() // x är synlig // y är inte synlig char y; 22
Synlighet på funk?onsnivå #include <stdlib.h> char x; int foo(float x) // argumentet x (float) är synligt 23
Synlighet på funk?onsnivå #include <stdlib.h> char x; int foo() int x = 4; return x; 24
Vilken synlighet har högst prioritet? #include <stdio.h> int x; int foo(int x) if( x == 0 ) int x = 4; return x; return x; int main() x = 1; x = foo(0); printf("x is %i", x); return 0; Vad är x? 25
Funk?onsprototyper #include <stdio.h> // funktionsprototyp int foo(int x); int main() printf("x is %i", foo(0)); return 0; int foo(int x) // funktionskropp 26
Typedef alias för typer typedef unsigned int uint32, uint32_t; typedef signed short int int16; typedef unsigned char *ucharptr; typedef int postnr; typedef int gatunr; postnr x = 41501; gatunr y = 3; x = y; // helt OK uint32 a, b = 0, c; int16 d; ucharptr p; // Lurighet: * ingår inte i typdeklarationen typedef char* byteptr, byteptr2; // fel! typedef char* byteptr, byte; // rätt typedef char *byteptr, byte; // tydligare! typedef förenklar/förkortar ufryck, vilket kan öka läsbarheten. typedef unsigned char uint8, ; typ alias/typnamn 27
Array (Fält) #include <stdio.h> char namn1[] = 'E', 'm', 'i', 'l', '\0'; char namn2[] = "Emilia"; char namn3[10]; int main() printf("namn1: %s \n", namn1); printf("namn2: %s \n", namn2); printf("sizeof (namn2): %i \n", sizeof(namn2)); int a[] = 3, 2, 1, 0; int b[5]; float c[6] = 2.0f, 1.0f; int main() a[0] = 5; b[4] = a[2]; c[3] = 3.0f; return 0; return 0; Utskris: namn1: Emil namn2: Emilia sizeof(namn2): 7 28
Structs (sammansafa datatyper) Sv: Poster optional struct StructName typ medlem1; typ medlem2; variabel1, variabel2 ; optional Ekvivalenta skrivsätt: struct Player // Player kan här skippas int age; char* name; player1, player2; Eller: struct Player int age; char* name; ; struct Player player1, player2; Eller: typedef struct tplayer // tplayer kan skippas int age; char* name; Player ; Player player1, player2; 29
Structs (sammansafa datatyper) Initieringar av structs Vanligt förekommande: typedef struct int age; char* name; Player; //Player är nu typalias för denna struct. Fördel: slipper skriva struct Player Player player1 = 15, "Ulf"; Player player2 = 20, "John Doe"; // eller t ex player1.age = 16; player1.name = "Striker"; Structs kan innehålla andra structs: typedef struct int x; int y; Position; typedef struct int age; char* name; Position pos; Player; Player player1 = 15, "Striker, 5, 10; // eller t ex player1.pos.x = 6; player1.pos.y = 11; // player1.pos = 5,10 // går tyvärr ej i C. // Ofullständing initiering OK! Player player1 = 15, "Striker, 5; 30
Structs (sammansafa datatyper) I uppgift 39: typedef struct tpoint unsigned char x; unsigned char y; POINT; #define MAX_POINTS 20 typedef struct tgeometry int numpoints; int sizex; int sizey; POINT px[ MAX_POINTS ]; GEOMETRY, *PGEOMETRY; Skapa och initiera en variabel av typen GEOMETRY: GEOMETRY ball_geometry = 12, 4, 4, // POINT px[20] 0,1, // px[...] 0,2, 1,0, 1,1, 1,2, 1,3, 2,0, 2,1, 2,2, 2,3, 3,1, 3,2 // Här utnyttjar vi ofullständig // initiering (12 av 20) ; 31
Programstruktur // main.c #include <stdio.h> #include "foo.h" int main() printf("x is %i", foo(0)); return 0; // foo.h int foo(int x); // foo.c #include <stdlib.h> int foo(int x) if( x == 0 ) int x = 4; return x; return x; c-fil Inkluderar header-fil header-fil Innehåller funk?onsprototyper c-fil header-filen måste inte ha samma namn som c-filen, men det är enklare så. 32
33
Definieras osa i stdint.h Men för arm-kompilatorn har vi inga färdiga.h-filer. Kan finnas online 34
Från källkod?ll exekverbar 1. Preprocessing 2. Kompilering 3. Länkning 35
Preprocessorn // main.c #include <stdio.h> #include "foo.h" Copy-paste av filer #define MAX_SCORE 100 #define SQUARE(x) (x)*(x) Find-and-replace av strängar int main() printf("högsta möjliga poäng är %i\n", MAX_SCORE); printf("kvadraten av 3 är %i\n", SQUARE(1+2)); printf("x is %i", foo(0)); return 0; Preprocessorn arbetar på källkoden på textnivå. 36
Kompilering Processar en.c-fil i taget: Skapar en objekwil (dvs.o-fil), per.c-fil, som innehåller: Maskinkod för instruk?oner Symboler för addresser För funk?oner/variabler i objekwilen. För funk?oner/variabler i andra objekwiler/bibliotek. 37
38
Build 39
Länkning Säfer samman (flera) objekwiler?ll en exekverbar fil (.exe /.s19 el dyl). Översäfer symbolerna?ll (rela?va) adresser. 40
41
Aritme?ska operatorer Basic assignment Addi?on Subtrac?on Unary plus (integer promo?on) +a Unary minus (addi?ve inverse) -a Mul?plica?on Division Modulo (integer remainder) Increment Decrement Prefix Poswix Prefix Poswix a = b a + b a - b a * b a / b a % b hfp://en.wikipedia.org/wiki/operators_in_c_and_c%2b%2b#arithme?c_operators ++a a++ --a a-- 42
Jämförelseoperatorer Equal to Not equal to Greater than Less than Greater than or equal to a == b a!= b a > b a < b a >= b Less than or equal to a <= b hfp://en.wikipedia.org/wiki/operators_in_c_and_c%2b%2b#comparison_operators.2frela?onal_operators 43
Logiska operatorer Logical nega?on (NOT)!a Logical AND Logical OR a && b a b hfp://en.wikipedia.org/wiki/operators_in_c_and_c%2b%2b#logical_operators 44
Bit opera?oner Bitwise NOT ~a Bitwise AND Bitwise OR Bitwise XOR Bitwise les shis Bitwise right shis a & b a b a ^ b a << b a >> b hfp://en.wikipedia.org/wiki/operators_in_c_and_c%2b%2b#bitwise_operators 45
Sammansafa?lldelsningsoperatorer Operator name Syntax Meaning Addi?on assignment a += b a = a + b Subtrac?on assignment a -= b a = a - b Mul?plica?on assignment a *= b a = a * b Division assignment a /= b a = a / b Modulo assignment a %= b a = a % b Bitwise AND assignment a &= b a = a & b Bitwise OR assignment a = b a = a b Bitwise XOR assignment a ^= b a = a ^ b Bitwise les shis assignment a <<= b a = a << b Bitwise right shis assignment a >>= b a = a >> b hfp://en.wikipedia.org/wiki/operators_in_c_and_c%2b%2b#compound_assignment_operators 46
If-else satser int x = -4; if( x == 0 ) //... if( x ) //... else //... Utvärderar?ll falskt, kör ej. Utvärderas?ll sant, kör, ty ( x!= 0 ) Noll betraktas som falskt. Allt som är skilt från noll betraktas som sant. 47
Loopar int x = 5; int x = 5; while( x!=0 ) x--; while( x ) x--; int x; for( x=5; x; ) x--; Tre ekvivalenta loopar. Om inga måsvingar används så är loopkroppen ef enda ufryck. 48
Kort om pekare?ll portar #define PORT_DISPLAY_BASE 0x40021000 // MD407 port E #define portodrlow ((volatile unsigned char *)(PORT_DISPLAY_BASE+0x14)) #define portodrhigh ((volatile unsigned char *)(PORT_DISPLAY_BASE+0x14+1)) // Skriv 5 till porten *portodrlow = 5; // Förklaring: Innehållet på den här adressen i RAM-minnet sätts lika med 5 * ((volatile unsigned char *)0x40021015 ) = 5; Type-cast av talet 0x40021015 till en pekare till en unsigned byte. Volatile innebär här att kompilatorn inte får optimera bort tilldelningen. char c = * ((volatile unsigned char *)0x40021015 ); // Läsning Mer nästa lek?on 49
Grafisk display uppg. 34-40 + lab #define B_SELECT 4 static void graphic_ctrl_bit_set( unsigned char x ) *portodrlow &= ( ~B_SELECT ); // Clear SELECT bit *portodrlow = ( ~B_SELECT & x );// Man bör nollställa SELECT-biten, ty den // kan vara 1. // *portodrlow = x; // ej tillräckligt! static void graphic_ctrl_bit_clear( unsigned char x ) *portodrlow &= ( ~B_SELECT & ~x); // Clear SELECT and bits x 50
Grafisk display uppg. 34-40 + lab static void graphic_write(unsigned char val, unsigned char controller) *portodrhigh = val; select_controller( controller ); // Add this line! delay_500ns(); graphic_ctrl_bit_set( B_E ); delay_500ns(); graphic_ctrl_bit_clear( B_E ); if( controller & B_CS1 ) select_controller( B_CS1); graphic_wait_ready(); if( controller & B_CS2 ) select_controller( B_CS2); graphic_wait_ready(); sta?c unsigned char graphic_read(unsigned char controller) display_read(controller); // a dummy read return display_read(controller); *portodrhigh = 0; graphic_ctrl_bit_set( B_E ); select_controller( 0 ); 51