C för enchipsdatorer: Programstruktur och Kompileringsprocess Lektion 3 C för enchipsdatorer: Programstruktur och Kompileringsprocess
Agenda Laboration 1 Kompileringsprocessen (PICC) Interrupt Exempelprogram med flera filer Kompileringsprocessen (PICC) Steg Filer Interrupt Funktionsdefinition Assembler i C-program Olika metoder
Kompilatorns funktion Detekterar syntaktiska and semantiska fel i källfilerna, Producerar ingen exekverbar kod förrän felen är rättade PICC kompilatorn skapar en exekverbar fil (*.hex, *.bin) Av C filer (*.h, *.c) som tillhandahålls
Funktioner i kompilatorn (PICC) När ett program kompileras Flera olika applikationer involverade Kontrolleras av ”command-line driver” (CLD) picl.exe CLD läser programmerarens inställningar för att bestämma vilka av applikationerna som skall exekveras och vad dessa skall ha för inställningar Termen kompilator (compiler) omfattar alla applikationer som är involverade i kompileringsprocessen (dvs. komplett transformering från indata till utdata från kompilatorn) Andra definitioner av kompilatorn kan omfatta stegen fram till linker Kompilatorns applikationer använder olika stöd-filer för att lagra inställningar och information som används under kompileringen (kompileringsprocessen)
Projekt och konfigureringsinställningar CLD integrerad i MPLAB Kan spara och ändra kommandoradsargument via MPLAB build options Kompilatorn läser även en chip info fil, .ini, som anger hur minnet är arrangerat i olika chip Ex: C:\Program Files\HI-TECH Software\PICC-Lite\9.50\datpicc-lite.ini.
Indata till kompilatorn Indata-filer (PICC manual)
Indata-filer C-filer måste ha filändelsen .c (används av kompilatorn för att bestämma filtyp) En header-fil innehåller programrelaterad information, men skapar normalt inte direkt exekverbar kod. Innehåller vanligtvis deklarationer (i motsats till definitioner) av funktioner och datatyper Inkluderas I C filerna av ett preprocessor direktiv #include Ingen namnrestriktion, men konvention med filändelsen .h Inkluderade filer förutsätts ha ej exekverbar kod Skall man inkludera filer med exekverbar kod skall dessa ha en .c filändelse Undvik att inkludera exekverbara filer I andra (ej vanligt, strukturen med ej exekverbara #include filer förstörs)
#include-filer HI-TECH kompilatorn innefattar flera olika .h filer som sparas I ett speciellt bibliotek I distributionen Ex pic1684.h Normalt placeras användarens .h filer I samma bibliotek som källfilerna .c Alternativt kan de läggas I ett bibliotek där sökvägen specificeras med -I (include path) inställningen under build options
Sökväg till #include-filer Ex: utils.h ligger på följande plats
Assembler-filer En assembler-fil innehåller processorspecifika mnemonics för programmet som kompileras Skapade från C-filer Handskrivna specialrutiner Måste vara kompatibla med Hi-Tech assembler som är en del av kompilatorn ”Bör” undvikas för att öka portabiliteten av programmet Måste ha .as som filändelse Kan listas i valfri ordning I kommmandoraden, eller insatta i dialogruta tillsammans med C filerna
Objekt-filer och biblioteks-filer Kompilatorn kan även ta emot förkompilerade objekt-filer Måste ha .obj extension. Kan läggas till I valfri ordning I kommandoraden, eller i MPLAB projektfönster Lägg inte till namn på objekt-filer som kompilerats av källfiler I samma projekt, endast förkompilerade objekt-filer som inte har någon motsvarande källfil Ofta använda programrutiner kan kompileras till en biblioteks-fil Lättare och snabbare att hantera för kompilatorn Kompilatorn accepterar dessa som andra källfiler Filändelsen .lib
C-filer C-filer kräver mest arbete av kompilatorn För varje C-fil produceras en listfil av applikationen CLIST Innehåller C-filerna med radnummer
Stöd-filer Stöd-filer produceras mellan de olika stegen kompileringen
Kompileringssteg Preprocessor Parser Kodgenerator Assembler Linker
Kompilatorn: Filer och applikationer
Preprocessor Steg 1 i kompileringsprocessen, förbereder filerna för kommande uppgifter Inputs C och include-filer (.h) Funktioner Tar bort kommentarer och multipla tomrum (ex. tabbar ) Exekverar preprocessor direktiv I källfilerna (#define, #include) Preprocessor filer Intermediate output filer Utdata från preprocessor ses normalt inte om inte –PRE inställningen är vald, i detta fall kan utdata skrivas till en fil C preprocessade filer (.pre) Output Preprocessor output
Output Preprocessor Output från preprocessor är C-kod Kallas för modul eller översättningsenhet #1 main.c raden indikerar filnamn och radnummer I källfilen Kommentarer och makrodefinition är borta men tomma rader är kvar för att hålla radnummer information intakt
Parser Input Funktion Skapar inga intermediate filer Output Preprocessor output Funktion Scannar koden för att upptäcka fel och ovanliga konstruktioner Skapar inga intermediate filer returnerar syntax and semantiska fel, samt varningar för ovanlig kod Output Parser output
Kodgenerator Inputs Funktioner Intermediate output filer Output Parser output (godkända filer från preprocessor) Chip info-fil (.ini) Funktioner Konverterar output från parsern till assembler ASCII mnemonics Kodoptimering (optional) Intermediate output filer Assemblerkod ASM-fil (.as) Symbolic Debug-fil(.sdb) Output Kodgenerator output
Kodgeneratorns funktion Detta är första steget som är processorspecifikt Alla HI-TECH preprocessors och parsers har samma namn och är I stort sätt identiska medan Kodgeneratorn har ett specifikt processorbaserat namn till exampel CGPIC, eller CG51. Kodgeneratorn använder en uppsättning regler (productions) för att skapa assembler-koden Om ingen matchning/subproduction kan hittas kan inte kodgeneratorn producera någon kod och ett felmeddelande skrivs ut Detta betyder att C koden var giltig men att kodgeneratorn inte hittade några productions som kan matcha uttrycket Vanligtvis är det ungefär 800 productions I en full kodgeneratoor Kodgeneratorn utför även optimering I olika stadier global optimization: Utförs på output från parsern, allokerar bl.a. variabler till register när det är möjligt Assemblerfilerna är de första som refererar till psects, program sections. Kodgeneratorn genererar psect directiv där kod och data skall läggas
Assembler Input Funktion Intermediate output filer Output Kodgenerator output Funktion Konverterar assembler ASCII mnemonics till binär maskinkod Intermediate output filer List-filer (.lst) Output Objekt-filer (.obj)
Assemblerns funktion Assemblern är specifik för varje kompilator och har ett processorspecifikt namn ex. ASPIC or ASXA. Assemblerkoden innehåller även assembler directiv som kommer att exekveras av assemblern Vissa av dessa definerar ROM baserade konstanter andra definerar psects medan andra deklarerar globala syimboler Assemblern kan även föregås av en optimering, kallad peephole optimization. Peephole optimization görs separat för assemblerkod för varje funktion Utdata från assembler är en objekt-fil Formatterad binär-fil som innehåller maskinkod och annan information relaterad till den modul som den genererades ifrån Objektfiler finns I två grundtyper Relokerbara Absoluta Även om båda innehåller binär maskinkod har inte relokerbara objektfiler adresserna specificerade
Output assembler Objektfiler som produceras av assemblern följer ett format som är standard för alla HI-TECH kompilatorer Innehållet är dock maskinspecifikt Om -ASMLIST inställningen var specificerad kommer assemblern att generera en assembler list-fil som innehåller både den ursprungliga C-koden och assembler-koden som genererades för varje rad i C-koden
Kompileringstegen före linker preprocessor, parser, kodgenerering and assembler, utförs fil för fil för varje C-fil som körs Fel i koden rapporteras när de detekteras Om en fil inte kan kompileras beroende på ett fel så kommer kompileringen att stoppas för denna, och istället fortsätta med nästa fil som står i tur Assembler-filer behöver inte lika mycket arbete men de måste assembleras Kompilatorn kommer att skicka varje fil med .as ändelse direkt till assemblatorn, såvida inte inställningen -P (Pre-process assembler files) är använd. Då tillåts preprocessor direktiv användas I assemblerkod Utdata från preprocessorn går i detta fall till assemblern Objekt och biblioteks-filer som skickas till kompilatorn är redan kompilerade och används inte förrän I link-stadiet
Linker Input Funktion Intermediate output filer Output Objekt-filer (.obj) Biblioteks-filer (.lib) Funktion Kombinera alla objekt och biblioteksfiler till en fil Alla objektfliler från kompileringen plus externa och interna objekt och biblioteksfiler Mappar relokerbara objekt till absoluta adresser Intermediate output filer Map-fil (.map), detaljerad information om positionen av psects och addresser till symboler Symbol-fil (.sym), ASCII baserad fil som innehåller information om hela programmmet. Innehåller absoluta adresser eftersom denna fil genereras efter link stadiet Debugging-fil (.cod) Output Executable (.hex, .bin)
Linker output Objekt-filen som produceras av HLINK innehåller all information som behövs för att köra programmet Nu måste det transformeras till ett format som kan skickas till processorn OBJTOHEX producerar filen med formatet som användaren har specificerat. Det finns flera standarformat för detta The Motorola HEX (S record) or Intel HEX Innehåller även checksumma för kunna verifiera att överföringen skett utan fel . Formaten innehåller address information som möjliggör att de områden som inte används kan utelämnas från filen. Kan ge ett mindre fomat då endast de använda adresserna behöver anges I vissa fall kan andra filer produceras CROMWELL, ”reformatter”, exekveras för att producera andra filer. Ex. med PIC kompilatorn läsa in HEX-fil och SYM-file och producera en COD-fil.
OBJTOHEX output
Exempel Linker options
Interrupthantering i C Interrupt kan hanteras utan assemblerkod Funktion kan använda kvalificeraren interrupt som anropas vid hårdvaruinterrupt Hanteras annorlunda jämfört med andra funktioner En interrupt funktion måste deklareras av typen interrupt void och kan inte ha parametrar Kan inte anrropas från c-kod men kan anropa andra funktioner Exempel på interrupt funktion (funktionsnamnet tc_int är oväsentligt) long tick_count; void interrupt tc_int(void) { ++tick_count; } Endast en interruptfunktion i midrange PIC:ar, interruptvektorn pekar på denna funktion PICC Lite kompilatorn avgör vilka register och objekt som behöver sparas In-line assembler i interruptfunktionen kan däremot kräva att register sparas
Assembler i C-kod #asm and #endasm direktiven kan användas för att starta och avsluta ett block av assemblerinstruktioner i C-kod asm() direktivet kan användas för att lägga in en enstaka assemblerinstruktion unsigned char var; void main(void) { var = 1; #asm rlf _var,f #endasm asm("rlf _var,f"); } Se upp med att assemblerkoden inte stör kompilatorgenererad kod, använd -S option för att studera kompilatorgenererad kod Viktigt: #asm and #endasm är syntaktiskt inte del av c-programmet och följer därför inte normala C-flödeskontrollregler Använd inte detta vid villkorsatser, det kan orsaka oväntade beteenden Använd i dessa fall endast asm("") formen som tolkas som ett C-statement och följer C-flödeskontrollregler