LEU240 Mikrodatorsystem Att placera program i FLASHrespektive
|
|
- Lisbeth Britt Fredriksson
- för 9 år sedan
- Visningar:
Transkript
1 Institutionen data- och informationsteknik Att placera program i FLASHrespektive RAM-minne Följande resonemang gäller för processorn MC9S12DG256B. Vi kommer i görligaste mån att skriva våra program i C men med några få inslag av in line-assembler. Vi skall studera hur vi kan använda XCC-miljön för att bygga upp applikationer där vi använder de minnen som finns inbyggda i processorn för att lagra vår applikation. Dessa minnen är då RAM- och ROM-minne (FLASH-minne). Vi skall se hur vi via initieringsfiler och länkarskript kan få våra applikationer att använda önskade delar av processorns minne. Vi kommer för våra applikationer att ha en tom processor utan fördefinierat programinnehåll, dvs vi lämnar MC12-miljön där vi hade en inbyggd debugger, ett rudimentärt operativsystem. Då vi vill åstadkomma fristående, självförsörjande program så uppkommer behovet att placera dessa program i minne som inte töms då strömmen stängs av, dvs i ROM vilket i vårt fall är FLASH-minne. Programmen skall dessutom gärna starta upp av sig själva då vi slår på strömmen eller trycker på Reset, dvs det behövs en resetvektor. Låt oss starta med att på samma sätt som i MC12 placera program i RAM-minne varefter vi, steg för steg, allt eftersom inför nödvändiga tillägg för att först skapa en FLASH-applikation och sedan en RAM-applikation med relokerade avbrottsvektorer. Nödvändig hantering varierar lite med hur vårt program är uppbyggt och vi kan dela upp det hela i nio steg 1. program i RAM-minne som bara innehåller lokala variabler 2. program i RAM-minne som innehåller oinitierade globala variabler 3. program i RAM-minne som innehåller initierade globala variabler 4. program i FLASH-minne som bara innehåller lokala variabler 5. program i FLASH-minne som innehåller oinitierade globala variabler 6. program i FLASH-minne som innehåller initierade globala variabler 7. program i FLASH-minne som innehåller initierade globala variabler med kopiering till RAM 8. program i FLASH-minne med avbrott (interrupt) 9. program i RAM-minne med relokerade avbrottsvektorer för avbrott Då uppstarten vid strömpåslag eller Reset är en form av avbrott, reset-adressen ligger ju in en avbrottsvektor, så kan vi i de sju första fallen inte få helt fristående applikationer utan de måste köras via en POD (BDM-laddare) så att vi kan sätta PC-räknaren till programmets startadress och starta programmet från denna adress. Vi använder också vår POD för att ladda CHALMERS TEKNISKA HÖGSKOLA Institutionen för data- och informationsteknik Sida 1 Avdelningen för datorteknik Besöksadress: Rännvägen Göteborg
2 ner program till aktuellt minne. I fall 1, 2, 3 och 9 så har vi programmet i flyktigt minne, dvs programmet finns inte i datorn vid uppstart så här måste vi använda en POD varje gång vi slår på strömmen både för att ladda ner program och sedan behövs den också för att starta programmen, förutom i fall nio där start kan ske via den relokerade resetvektorn. Den nionde varianten kräver att vi förutom vår applikation i RAM-minne också placerar en applikation i FLASH-minne som relokerar avbrottsvektorerna till RAM-minne. Detta blir då två separata applikationer där relokeringsprogrammet i FLASH-minne kan ligga kvar permanent och användas av alla senare program placerade i RAM och som innehåller avbrott. Vi skapar en förenklad version av den relokering som sker i MC12:s debugger. Skillnaden är att i MC12 får vi utskrift till terminal om vi använder en oinitierad avbrottsvektor. Förutsättningen för detta är att det finns en möjlighet att skriva till terminal via SCI-interface. Det måste alltså finnas en initierad serieport och en utskriftsrutin vilket saknas i vårt system. För att illustrera hanteringen så använder vi oss av ett mycket enkelt program som bara gör PortB till en utgång och togglar ett ben i porten för att generera en fyrkantvåg. I de första sju fallen använder vi en fördröjning för att skapa periodtiden för hög respektive låg signal ut från PortB medan vi i de två sista fallen övergår till att generera periodtiden via avbrott från realtidsklockan. Fördröjning och avbrottstid är inte anpassade för att ge lika lång periodtid i de olika fallen. För att våra program skall hanteras på rätt sätt så måste vi ge direktiv till länkaren så att den länkar ihop de olika programdelarna till ett enda program och placerar olika typer av data på rätt ställen i minnet. Vi kan göra detta genom att göra menyvalet Project/Settings i XCCmiljön och ange direktiven under Linker/Options. Detta skulle dock betyda att vi för varje projekt skulle behöva mata in aktuella inställningar. Vi kan i stället välja att använda en skriptfil för att ge konfigureringen av länkaren och då kan vi ju återanvända denna skriptfil för olika projekt och vi gör några varianter på denna fil som passar för de olika applikationstyperna. Låt oss innan vi gå vidare titta på hur en sådan skriptfil kan vara uppbyggd. Skriptfil till länkaren Låt oss se på skriptfilen default.lsc (lsc = linker script) som är default länkarskript i utbildningsvarianten av XCC, filen finns i Bilaga 1. Denna fil är avsedd för labdatorn MC12 med sin inbyggda debugger där vi i normalfallet laddar program i RAM-minne. MC12 använder sig av processorn MC9S12DG256B som har tillgängligt RAM-minne i intervallet 0x1000 0x3FFF och det är då detta minnesutrymme som skriptfilen allokerar. Låt oss först rensa bort alla kommentarer så att vi ser filens verkliga innehåll. Vi gör samtidigt ett par editeringar för att öka läsbarheten. Vi får Kod 1 -M entry( start ) group( c, const_group ) abs group( r, test_group) init, sida 2
3 text, rodata, data, bss group( r, interrupt_vectors ) vectors layout 0x1000,0x3C80 <= test_group, 0x3F80,0x3FFF <= interrupt_vectors Kod 1 Vi ser att filen innehåller fyra olika strukturer, ett M-direktiv, en entry-deklaration, några gruppindelningar och en layout-struktur. Innehållet beskrivs ingående i XCC:s hjälpsystem men vi ger en kort beskrivning här. -M-direktivet gör att det vid länkningen kommer att skapas en map-fil (map = memory map) med samma namn som den genererade laddfilen men med ändelsen.map. map-fil innehåller information var programavsnitt, konstanter och variabler har placerats i de tillgängliga minnena. Laddfilen har samma namn som projektet men detta namn är efterföljt av _Debug eller _Final beroende på vilken typ av fil vi väljer att generera. Skillnaden mellan dessa filer är att debugvarianten innehåller information som en debugger kan använda sig av. Denna information gör det möjligt att stega sig fram i koden och sätta brytpunkter och samtidigt ger den oss möjlighet att i debugarbetet använda våra symboliska namn, våra lablar men samtidigt blir programfilen större än vad finalvarianten blir. Det naturliga är att generera en debugvariant av laddfilen under programutvecklingen för att till slut skapa en finalvariant för nedladdning när det hela är klart. Vi kan enkelt välja att generera en map-fil med annat namn om vi så önskar genom att ge ett filnamn efter -M-direktivet. Vi kommer att se exempel på map-filer längre fram i texten. Via group-direktivet så lägger vi in olika datasegment i grupper som vi sedan via layoutdirektivet placerar i olika minnesareor. Varje grupp kan innehålla ett eller flera segment och då vi anger flera segment i samma grupp så kommer dessa segment att placeras direkt efter varandra, i den ordning de är angivna, i den aktuella minnesarean. Vi har sex olika typer av segment abs init text rodata i detta segment placeras alla konstanter. Detta segment skall inte ges någon minnesadress då konstanterna kommer att assembleras in i själva programkoden och inte lagras separat i processorns minne detta segment skall placeras först och här kommer vår startup-fil med sina initieringar att placeras standardsegment för programkoden standardsegment för konstant initierad data (read only) sida 3
4 data bss standardsegment för initierad data standardsegment för oinitierad data Med hjälp av layout-direktivet anger vi då sedan start- och slutadress för de minnesareor där vi vill placera de olika grupperna. Vi ser i skriptfilen default.lsc att alla standardsegment utom abs är samlade i gruppen test_group och att gruppen sedan är placerad i minnesområdet 0x1000-0x3C80, vilket är den större delen av adressområdet för MC12:s RAM-minne. Att segmentet abs ligger för sig själv i en egen grupp beror på att det inte skall placeras i någon minnesarea och det finns då inte heller med i layout delen av filen. Dessutom har vi gjort en grupp kallad interrupt_vectors innehållande ett segment som kallas vectors. Detta är inget standardsegment utan segmentet har deklarerats i vår programkod via ett så kallat #pragma-direktiv. #pragma-direktiv används för att skapa nya namn till våra minnessegment som sedan kan placeras i önskade minnesareor via ovanstående skriptfil. Vi har syntaxen #pragma TEXT DATA BSS <segment_namn> där vi då ger ett segment av typen text, data eller bss ett nytt namn. Observera att <segment_namn> inte får vara längre än 16 tecken. Mer om detta senare. I den defaulta filen används detta för att placera de till RAM relokerade avbrottsvektorerna längst upp i RAMminnet. I debuggerkoden till MC12 har vi alltså placerat de ommappade avbrottsvektorerna i ett segment kallat vectors som är deklarerat via ett #pragma-direktiv. Detta segment är sedan placerat längst upp i RAM-minnet så att de ommappade avbrottsvektorerna får samma adresser som de verkliga avbrottsvektorerna bortsett från att det första hexadecimala F:et i deras verkliga adresser har ersatts med en 3:a, till exempel är IRQ-avbrottets avbrottsvektor ommappad från 0xFFF2 till 0x3FF2. Vi återkommer till detta lite längre fram då vi beskriver hur vi gör för att mappa om avbrottsvektorerna till RAM. Vad gäller övriga adresser i RAM-minnet så är adresserna under 0x1000 reserverade för processorns minnesmappade registeruppsättning samt som I/O-area för labmoduler medan intervallet 0x3C81 0x3F7F används av debuggern. Låt oss också titta på systemets startup-fil. Systemets startup-fil Till systemet finns en default startup-fil _startup.s12 som skall placeras i startup-segmentet och därmed hamna först i programmet. Denna fil ligger med i installationen av XCC och sätter bland annat upp systemets stackpekare och initierar systemets C-bibliotek. I normalfallet kommer filen automatiskt att inkluderas i våra program. I övrigt förlitar sig startup-filen på initieringar som finns i debuggern, bland annat initiering av processorns klockkrets med PLL samt initiering av en serieport för kommunikation med systemet. I denna seriekommunikationsdel finns de enkla funktionerna outchar, tstchar och inchar som används för att enkelt läsa och skriva tecken via serieporten men dessa funktioner är inte kompletta utan anropar i sin tur outchar- och tstcharfunktioner som finns i debuggern. sida 4
5 Detta betyder att när vi skall köra systemet utan debugger så måste vi själva initiera klockkretsen och behöver vi en serieport så får vi själva initiera denna och vi får skriva våra egna outchar-, tstchar- och inchar-rutiner. Startup-filen innehåller dessutom en del funktioner som är nödvändiga om vi skall använda oss av dynamisk minnesallokering. Vi kommer inte att göra detta varför vi lämnar dessa delar därhän. Filen _startup.s12 finns i Bilaga 2 och vi kommer här att kortfattat beskriva dess funktion. Filen inleds med ett antal konstantdeklarationer som då är placerade i abs-segmentet. Här deklareras bland annat ett antal konstanter som används för att sätta upp stacken. Efter detta övergår vi till det första kodsegmentet där en applikation skall startas efter omstart. Segmentet kallas init och detta ligger som vi minns före text-segmentet i den grupp vi deklarerade i länkarens skriptfil. I startup-segmentet ligger labeln start till vilken systemets resetvektor refererar, dvs det här hit programmet går vid reset. Efter detta sätter vi initialvärdet på stackpekaren till TOS (Top Of Stack), en konstant som tidigare är deklarerad som 0x3C80 vilket är den högsta fria adressen i processorns RAMminne. Adresserna ovanför 0x3C80 används som vi såg dels av debuggern och är dels reserverade för de ommappade avbrottsvektorerna. När detta är klart så hoppar vi till en subrutin som initierar en serieport för simulatorn. En test av minnesinnehållet på adress 0x001B som innehåller komponentinformation för den aktuella enheten gör att vi kan avgöra om vi kör i hårdvara eller i simulator. Kör vi i hårdvara så initieras ingen serieport utan då används debuggerns initiering av serieporten och vi vill inte störa denna initiering. Rutinen initierar serieportens baudrateregister men då simulatorn inte kör i realtid så kan hastigheten sättas till vad som helst. Efter detta är initieringen klar och vi gör ett hopp till labeln _main som då skall ge hopp till huvudfunktionen main(void) i vår C-applikation eller till labeln _main om vi har en applikation med huvudprogrammet i assembler. Vi skall se senare att funktionsnamn i C vid kompileringen omvandlas till lablar i assemblerkod och att dessa lablar är lika med funktionsnamnet men i labeln kommer namnet att föregås av en understrykning (_). Utöver detta innehåller startup-filen de ovan nämnda assemblerrutinerna för att läsa in tecken från serieporten, testa om tecken finns på serieporten samt skriva tecken till densamma. Vi ser att dessa rutiner hoppar till adresser strax över 0xC000 vilket är den FLASH-minnesadress där vår debugger startar. Vi ser att rutinerna innehåller absoluta hopp till debuggern och inte subrutinanrop. Det beror på att rutinerna i debuggern redan innehåller RTS och dessa ger återhopp då vi lämnar rutinerna. Nödvändiga förändringar i systemets startup-fil Då vi nu saknar debugger så måste vi se till att kontrollera att processorn går upp med önskad klockfrekvens, i detta fall 8 MHz, samt att PLL:n låser, dvs går igång med rätt frekvens och vi får komplettera startup-filen med detta. Vi väljer att konfigurera systemet så att processorns systemlocka får samma frekvens som oscillatorn har, dvs 8 MHz. Vi gör detta via CRG-enheten (Clock and Reset Generator) genom att i CRG-registret CLKSEL välja att generera systemklockan från PLL-klockan och systemklockan kommer då att få halva PLL-klockans frekvens, dvs vi skall ha PLL-klocksfrekvensen 16 MHz. Alternativet är att generera systemklockan direkt från oscillatorns klocka och dess frekvensfrekvens men då skulle systemklockan få halva oscillatorklockfrekvensen, dvs 4 MHz. sida 5
6 PLL-klockans frekvens ges av värdena i registren SYNR (CRG Synthesizer Register) och REFDV (CRG Reference Divider Register) enligt PLLCLK SYNR 1 2 OSCCLK REFDV 1 Vi ser att PLL-klockan får önskad frekvens (dubbla den önskade systemklockfrekvensen) om vi sätter både SYNR och REFDV till noll. Innan vi låter PLL-klockan styra systemklockan så måste vi se till att PLL:ns VCO har låst på rätt frekvens och detta indikeras av en etta (1) i bit tre (3) i CRG:ns flaggregister (CRGFLG). Vi får Kod 2 devinit: #define SYNRVal 0 #define REFDVVal 0 ; Setup clock references LDAB #SYNRVal ; STAB SYNR LDAB #REFDVVal; STAB REFDV BRCLR CRGFLG,#LOCK,. ; vänta på låst PLL BSET CLKSEL,#PLLSEL ; generera systemklocka från PLL. RTS Kod 2 De symboliska namnen bygger på h-filen HS12_DG.h varför denna fil måste inkluderas i programmet. Denna fil kan alltså användas både i assembler och C. Skall vi använda en serieport så måste även denna initieras. Det gör vi enklast genom att modifiera startup-filens serieportsinitiering för simulatorn genom att ta bort testen för hårdvara samt initiera serieporten för baudraten 9,6 kbaud och dessutom aktivera porten för både sändning och mottagning men inte aktivera några avbrott från serieporten. Denna initiering lämnas till laboranterna själva. Vi tar också bort anropet av serieportsrutiner i debuggern och lämnar dem tills vidare som tomma rutiner innehållande bara ett RTS. Behöver vi serieporten så får vi fylla rutinerna med innehåll senare. Vi har den modifierade startupfilen _startup_mod.s12 i Bilaga 3. I kommande avsnitt kommer vi att införa några förändringar i startup-filen för att anpassa den till våra applikationer. Vi inför dessa förändringar då de blir aktuella. Dessa applikationer kommer inte att använda någon serieport. Låt oss nu se på våra programvarianter som skall placeras i vår mikrokontroller utan debugger. Program i RAM-minne som bara innehåller lokala variabler Vi skriver ett enkelt program för den applikation vi beskrev tidigare, dvs vi togglar Port B med jämna mellanrum, Kod 3 sida 6
7 #include "..\HS12_DG.h" #include "..\reg_macro.h" void main(void) char temp; short i,j; REG8(DDRB)=0xFF; temp=0; while(1) REG8(PORTB)=temp; temp=!temp; for (i=0;i<10;i++) for (j=0;j<10000;j++); Kod 3 Koden till filen local_noirq_ram.c återges också i Bilaga 4. I den inkluderade h-filen HS12_DG.h deklareras adresserna till HC12:s olika register och även de individuella bitarna i dessa register med samma namn som de har i HC12-manualerna. I h-filen reg_macro.h deklareras funktioner för att via pekare adressera dessa register från program skrivna i C. Dessa h-filer ligger ett steg högre upp i katalogstrukturen (..\) för att lätt kunna användas av flera applikationer i parallella mappar. Vi ser att programmet bara innehåller lokala variabler, en lokal variabel (temp) för att hantera det värde vi skickar till Port B och två lokala variabler (i och j) för att skapa en nästlad fördröjningsfunktion. För lokala variabler kommer det inte att allokeras något minne utan för dessa variabler bereds i stället plats på stacken. Vi kan se detta om vi vid kompileringen använder konfigureringsswitchen S i Project/Settings (se nedan) som gör att vi behåller den assemblerfil som genereras som mellanformat då C-filen kompileras. Så snart vi har variabler i vårt program, dvs data som vi skall kunna både läsa och skriva så måste dessa vara placerade i minnesareor där vi kan både läsa och skriva. Vi måste alltså placera dem i RAM-minne. Eftersom vi här bara använder stacken för våra variabler så är det stacken som måste placeras i RAM. Vi måste också se till att ha en stack uppsatt då vi börjar använda subrutiner eftersom vid anrop av dessa så lagras återhoppsadressen på stacken. Applikationen använder sig faktiskt av subrutiner, trots att det inte finns några i vårt program, eftersom vi anropar sådana i startup-filen, dvs även av detta skäl behöver via ha en stack uppsatt redan från första början då startup-filen är det första som länkas in i applikationen. Då stacken växer nedåt, mot lägre adress, så bör vi då placera stackens startadress TOS (Top Of Stack) högst upp i RAM-minnet för att utnyttja detta minne som bäst, dvs på RAM-minnets högsta adress. Som vi minns är den högsta RAM-adressen 0x3FFF för processorn MC9S12DG256B och vi kan placera TOS på denna adress då vi än så länge saknar relokerade avbrottsvektorer. Vi gör denna lilla ändring i vår startup-fil. I vårt fortsatta labsystem MC12S som är en ren processor utan debugger finns inte någon serieport ansluten vilket betyder att vi dessutom skall utelämna initieringen av serieporten i startup-filen och göra initieringen av serieporten om vi skulle behöva denna. Vi kan naturligtvis också utelämna rutinerna som använder serieporten dvs outchar, tstchar och sida 7
8 inchar. Vi får en startup-fil enligt Bilaga 5. Vi kallar filen _startup_noirq_ram.s12. Lägg märke till att användande av denna fil i stället för defaultfilen kräver en förändring i XCC:s Project/Settings-fönster. Vi återkommer strax till detta. Låt oss nu övergå till länkarskriptet. Då vår kod varken har konstanter eller initierade eller oinitierade variabler kan vi tycka att det skulle räcka med att skapa ett text-segment för själva programkoden medan de övriga segmenten utelämnas. XCC-miljön förutsätter dock att de andra segmenten finns med, även om de är tomma, så vi får ändå ta med dem. Då dessa segment inte används så spelar det ingen roll var vi placerar dem men låt oss placera dem på ett sätt som är lämpligt för följande applikationer med globala variabler. Då vi inte har några relokerade avbrottsvektorer så kan denna grupp utelämnas. Vi får Kod 4 Kod 4 -M group( c, const_group ) abs group( r, ram_group) init, text, rodata, data, bss layout 0x1000,0x3FFF <= ram_group Filen, noirq_ram_script.lsc, finns i Bilaga 6 med kommentarer. Låt oss nu se på hur vi konfigurerar XCC för detta genom Project/Settings-fönstret. Vi får Figur 1. sida 8
9 Figur 1: Project/Settings för program i RAM-minne Vi har kompletterat med switchen S under Options i C Compiler-rutan. Detta gör att vi kommer att behålla assemblerfilen som skapas vid C-kompileringen så att vi kan titta i denna fil om vi vill. Utan denna switch kommer filen automatiskt att raderas. Filen får samma namn som C-filen men med ändelsen.s och hamnar i underbiblioteket debug eller final beroende på vilken typ av applikation vi gör. Switchen L under Options i Assembler-rutan gör att det kommer att genereras en listfil då assemblerfiler assembleras. Vi får dock tyvärr inga listfiler från assemblerfiler som C- kompilatorn har översatt till assembler. I Target-rutan klickar vi bort Use standard startup så att vi använder den lokala _startup_noirq_ram.s12-filen i stället för den defaulta _startup.s12. Då denna fil inte automatiskt kommer att inkluderas i vårt projekt så får vi inte glömma att lägga till filen manuellt. Till sist har vi lagt in vår nya skriptfil noirq_ram_script.lsc i Linker-rutan. Här är filen placerad ett steg upp i biblioteksstrukturen (..\) för att enkelt kunna användas även av andra applikationer i arbetsarean (workspace). Den resulterande konfigurationen visas i mapfilen local_noirq_ram_debug.map som finns i Bilaga 7. Filen visar inom vilket minnesområde vår grupp av segment, ram_group, har hamnat samt var de enskilda segmenten finns. Vi ser också på vilka adresser de länkardefinierade konstanterna som inleder och avslutar de olika segmenten, till exempel text start respektive text end, finns. Här ser vi också storleken på respektive segment. Vi kan se att det finns innehåll i både bss- och rodata-segment trots att vår egen applikation saknar detta. Innehållet kommer från initieringen av C-biblioteket. Slutligen kan vi se på vilka adresser våra globala symboler inklusive programlablar, till exempel _main, ligger. Det framgår också från vilka filer lablarna kommer. Filnamnen anges sida 9
10 som de assemblerade objektsfilerna med ändelse.o12 oberoende om de härstammar från C- eller assemblerfiler. Låt oss nu lägga in oinitierade globala variabler. Program i RAM-minne som innehåller oinitierade globala variabler Vi gör en liten men viktig förändring i programkoden för vår applikation Kod 5 #include "..\HS12_DG.h" #include "..\reg_macro.h" char temp; void main(void) short i,j; REG8(DDRB)=0xFF; temp=0; while(1) REG8(PORTB)=temp; temp=!temp; for (i=0;i<10;i++) for (j=0;j<10000;j++); Kod 5 Koden, global_noirq_ram.c, återges också i Bilaga 8. Vi ser att det enda vi har gjort är att flytta ut deklarationen av variabeln temp ur funktionen main(), dvs vi har definierat om variabeln som global så att den kan nås av alla delar av vårt program. Det betyder att variabeln temp inte längre kan hanteras via stacken utan den måste få en egen plats i minnet och då vi skall kunna skriva till variabeln så måste den vara placerad i RAM-minne. Då det är en oinitierad variabel så kommer den att placeras i bss-segmentet men då hela vår applikation ligger i RAM-minne så är detta ingen komplikation utan bsssegmentet ligger redan i rätt minnestyp. Vi behöver alltså inte ändra i länkarskript eller statupfil då vi inför globala variabler i en RAM-minnesapplikation. Den resulterande mapfilen global_noirq_ram_debug.map återges i Bilaga 9. Om vi jämför denna fil med den tidigare mapfilen då vi bara hade lokala variabler så ser vi att text-segmentet har blivit något mindre beroende på att vi har variabeln på en minnesposition och slipper pusha och poppa från stack. Samtidigt har bss-segmentet blivit större eftersom vår oinitierade variabel hamnar där och vi kan se på vilken adress variabeln _temp ligger. Låt oss se vad som händer om vi i stället har en initierad variabel. sida 10
11 Program i RAM-minne som innehåller initierade globala variabler Vi gör återigen en liten men viktig förändring i programkoden för vår applikation Kod 6 #include "..\HS12_DG.h" #include "..\reg_macro.h" char temp=0; void main(void) short i,j; REG8(DDRB)=0xFF; while(1) REG8(PORTB)=temp; temp=!temp; for (i=0;i<10;i++) for (j=0;j<10000;j++); Kod 6 Koden, global_init_noirq_ram.c, återges också i Bilaga 10. Vi ser att vi har flyttat ut nollställningen av variabeln temp och gjort denna i form av en initiering av variabeln då den deklareras. Variablen skall nu placeras i segmentet för initierad data, dvs data-segmentet. Även data-segmentet finns med i vårt startskript så vi behöver inte göra några ändringar. Den resulterande mapfilen global_init_noirq_ram_debug.map återges i Bilaga 11. Om vi jämför denna fil med föregående mapfil så ser vi att text-segmentet återigen har blivit något mindre beroende på att vi nu inte nollställer temp i programkod utan via initiering. Samtidigt har bss-segmenet återfått samma storlek som då vi hade bara lokala variabler, dvs variabeln temp har försvunnit därifrån men i stället har vi fått innehåll i data-segmentet och vi kan se på vilken adress i segmentet som variabeln temp ligger. Program i FLASH-minne som bara innehåller lokala variabler Låt oss återgå till vår enkla applikation med bara lokala variabler, Kod 3, men nu placera applikationen i FLASH-minne. Vi måste göra ett litet tillägg i vår programkod och får Kod 7 sida 11
12 #include "..\HS12_DG.h" #include "..\reg_macro.h" void main(void) char temp; short i,j; REG8(DDRB)=0xFF; temp=0; while(1) REG8(PORTB)=temp; temp=!temp; for (i=0;i<10;i++) for (j=0;j<10000;j++); #pragma DATA UNSEC_address unsigned short unlock = 0xFFFE; Kod 7 Koden till filen local_noirq_flash.c återges också i Bilaga 12. Som synes har vi kompletterat C-filen med ett #pragma-direktiv. Detta direktiv används tillsammans med direktiv i länkarskriptet (se nedan) för att skriva till specifika adresser i FLASH-minne. unlock är bara ett godtyckligt namn som vi aldrig kommer att använda oss av men konstanten måste ha ett namn. Vi använder direktivet för att skriva 0xFE till adress 0xFF0F i FLASH-minne. Egentligen skriver vi en word (två byte), 0xFFFE, till adress 0xFF0E. Detta bara för att länkaren inte gillar att placera data på udda adresser så vi får använda en wordbaserad adress. Vi gör skrivningen för att ta bort den säkerhetsbyte som ligger på adress 0xFF0F som ett skydd mot läsning från FLASH-minnet. Detta skydd är till för att en användare av ett färdigprogrammerat chip inte skall kunna läsa av (stjäla) den inprogrammerade programkoden. Vi ser att programmet som tidigare bara innehåller lokala variabler. För lokala variabler kommer det, som vi minns, inte att allokeras minne utan för dessa görs det plats på stacken och då stacken måste vara skrivbar så måste denna placeras i RAM-minne. Vi kan som tidigare placera stackens startadress TOS (Top Of Stack) högst upp i RAM-minnet för att utnyttja detta minne som bäst, dvs på RAM-minnets högsta adress 0x3FFF. Vi kan behålla vår tidigare startupfil _startup_noirq_ram.s12, Bilaga 5. Låt oss nu övergå till länkarskriptet. Då vår kod varken har konstanter eller initierade eller oinitierade variabler så räcker det egentligen men att skapa ett text-segment för själva programkoden medan de övriga segmenten kan utelämnas men som vi nämnt tidigare så förutsätter XCC att de andra segmenten finns med, även om de är tomma, så vi får ändå lägga med dem. Då initieringen av C-biblioteket använder även dessa segment så placerar vi dom på ett sätt som är lämpligt för följande applikationer med globala variabler. sida 12
13 Observera att vi också har lagt in en grupp (unsec_group) för det värde (0xFFFE) vi skriver till adress 0xFF0E för att göra FLASH-minnet läsbart. Då vi inte har några reallokerade avbrottsvektorer så kan denna grupp utelämnas, däremot finns ju alltid utrymmet för de verkliga avbrottsvektorerna längst upp i FLASH-minnet (från adress 0xFF80) så vi får inte använda den delen av FLASH-minnet i allokeringen. För enkelhetens skull så låter vi flash_group sluta direkt nedanför unsec_group. Vi får Kod 8 Kod 8 -M group( c, const_group ) abs group( r, ram_group) bss group( r, FLASH-_group) startupseg, text, rodata, data, group( r, unsec_group) UNSEC_address layout 0x1000,0x3FFF <= ram_group, 0xC000,0xFF0D <= flash_group, 0xFF0E,0xFF0F <= unsec_group Filen, noirq_flash_script.lsc, finns också i Bilaga 13 med kommentarer. Vi konfigurerar XCC via Project/Settings-fönstret på samma sätt som tidigare, men får naturligtvis byta till rätt länkarskript. Lägg märke till att vi åter skall ha en egen startup-fil och inte stardardfilen. Vi får Figur 2. sida 13
14 Figur 2: Project/Settings för program i FLASH-minne Den resulterande mapfilen local_noirq_flash_debug.map återges i Bilaga 14. Här ser vi hur ett antal av våra segment nu har hamnat i FLASH-minne. Segmentet för oinitierade variabler, bss-segmentet finns dock kvar i RAM-minnet och har samma storlek som tidigare. Dessa variabler måste ju vara skrivbara. Lägg märke till att detta segment ligger först i den användbara delen av RAM-minnet (från adress 0x1000) då vi inte har några andra programdelar i detta minne. Vi har också har fått en ny grupp, unsec_group, i FLASH-minnet för skrivningen som öppnar FLASH-minnet för läsning. Vi ser också att konstanten _unlock som vi skriver för att öppna FLASH-minnet för läsning ligger bland våra globala symboler. Låt oss nu lägga in oinitierade globala variabler. Program i FLASH-minne som innehåller oinitierade globala variabler Vi gör samma förändring i programkoden som tidigare, dvs vi flyttar ut variabeln temp ur main-funktionen och gör variabeln global och får Kod 9 #include "..\HS12_DG.h" #include "..\reg_macro.h" char temp; void main(void) short i,j; sida 14
15 REG8(DDRB)=0xFF; temp=0; while(1) REG8(PORTB)=temp; temp=!temp; for (i=0;i<10;i++) for (j=0;j<10000;j++); #pragma DATA UNSEC_address unsigned short dummy = 0xFFFE; Kod 9 Koden, global_noirq_flash.c, återges också i Bilaga 15. Variabeln temp har nu blivit global och kan inte längre hanteras via stacken utan den måste få en egen plats i minnet och då vi skall kunna skriva till variabeln så måste den vara placerad i RAM-minne. Då det är en oinitierad variabel så kommer den att placeras i bss-segmentet och det var därför som vi redan i filen noirq_flash_script.lsc (Kod 8) placerade detta segment i RAM-minne. Lägg märke till att vi har kvar vår skrivning till adress 0xFF0E för att göra FLASH-minnet läsbart. Eftersom vi införde detta redan i konfigureringen för programmet i FLASH-minne med bara lokala variabler så kan vi använda samma konfigurering även här och inställningarna i Figur 2 gäller fortfarande. Den resulterande mapfilen global_noirq_flash_debug.map återges i Bilaga 16. Vi kan se att bss-segmentet i RAM-minnet har vuxit för att rymma variabeln temp. Vi kan naturligtvis också se adressen till den oinitierade variabeln temp i bss-segmentet. Vi kommer inte att gå in på konstanter men låt oss ändå nämna vad som kommer att hända om vi har sådana i vårt FLASH-program. Konstanter skall aldrig ändras utan bara läsas och kommer dessutom att kompileras in i själva koden och inte ta plats i minnet så de är inga problem. Även konstant initierade variabler, deklarerade via const-direktivet, tillhör själva programmet och då de aldrig skall ändras så kommer länkaren inte att göra plats för dessa i RAMminne utan de placeras i FLASH-minnet och kommer att hamna i rodata-segmentet. Denna typ av data kan till exempel vara uppslagstabeller av olika slag. Låt oss åter göra vår variabel initierad. Program i FLASH-minne som innehåller initierade globala variabler Vi gör samma förändring i programkoden som tidigare, dvs vi flyttar ut nollställningen av variabeln temp ur main-funktionen och gör den i form av en initiering och får Kod 10 #include "..\HS12_DG.h" #include "..\reg_macro.h" char temp=0; sida 15
16 void main(void) short i,j; REG8(DDRB)=0xFF; while(1) REG8(PORTB)=temp; temp=!temp; for (i=0;i<10;i++) for (j=0;j<10000;j++); #pragma DATA UNSEC_address unsigned short dummy = 0xFFFE; Kod 10 Koden, global_init_noirq_flash.c, återges också i Bilaga 17. Variabeln temp har nu flyttats över från bss-segmentet i RAM-minne till data-segmentet i FLASH-minne. Vi ser detta i map-filen global_init_noirq_flash_debug.map i Bilaga 18. Om vi tänker efter så inser vi att detta inte är så bra då vi i vårt program måste kunna skriva till variabeln och vi kan inte skriva till FLASH-minne. Vi kan då undra om variabeln inte kunde ha legat i RAM-minne i stället men variabeln skall ju inte bara ha en plats i minnet utan den skall ju vara initierad till ett startvärde och detta värde är en del av vår programkod som ligger i FLASH-minne. Resultatet är att variabeln måste kopieras över från FLASH-minne till skrivbart RAM-minne efter att vi har placerat programmet i FLASH-minne. Vi får då skriva programkod för detta och vi kan inse att det för program i FLASH-minne är enklast att undvika detta genom att använda oinitierade variabler och initiera dessa via programkod i stället. I XCC finns det dock ett sätt att automatisera detta. Program i FLASH-minne som innehåller initierade globala variabler med kopiering till RAM Vi behåller samma programkod som i föregående fall (Kod 10, Bilaga 17) men gör en förändring i projektkonfigureringen. Vi lägger till flaggan P för länkaren, Figur 3. sida 16
17 Figur 3: Project/Settings för program i FLASH-minne med kopiering av initierade variabler til RAMminne Denna flagga gör att systemet automatiskt kommer att köra en programslinga som ligger i C- biblioteket och som kopierar initierade variabler från FLASH- till RAM-minne i vår applikation samt allokerar plats för de kopierade variablerna i RAM-minne. I programmet kommer adresser också att ändras så att vårt program kommer att referera till de kopierade variablerna i det relokerade data-segmentet i RAM-minne och inte till de verkliga variablerna i datasegmentet i FLASH-minne. Vi får map-filen global_init_p_noirq_flash_debug.map i Bilaga 19 där vi kan se att vi har fått ett nytt segment i RAM-minne allokerat för att rymma det kopierade data-segmentet. Program i FLASH-minne som innehåller avbrott Låt oss nu försöka göra om programmet så att det använder avbrott. Vi tar bort fördröjningen och använder i stället avbrott från realtidsklockan (RTI) för att styra periodtiden hos fyrkantvågen. Vi måste nu införa en avbrottsrutin och denna ska vara deklarerad med det inledande direktivet interrupt (inleds av dubbla understrykningar, ) vilket ger en något annorlunda assemblerkod jämfört med en vanlig subrutin. Skillnaden består i att vid en vanlig subrutin så lagras bara återhoppsadressen på stacken och vid återhopp via RTS så återläses denna adress. Vid avbrott däremot placeras alla processorns register på stacken och vid återhopp från avbrottsrutinen via RTI så skall alla dessa register återläsas i omvänd ordning. Ordet interrupt anger då för kompilatorn att rutinen skall avslutas med RTI och inte RTS då den översätts till assembler. Detta räcker nu inte för att vår applikation skall fungera. Hur skall processorn veta att den skall hoppa till den avbrottsrutin som vi kallar Irq_RTI då RTI-avbrottet kommer? sida 17
18 Vår processor HCS12 har vid avbrott samma typ av funktion som vi har sett tidigare för andra processorer. Vid avbrottet så går processorn till den adress i avbrottsvektortabellen som hör till det aktuella avbrottet och hämtar där adressen till den avbrottsrutin som skall utföras varefter hopp sker till denna adress. I HCS12 ligger avbrottsvektorerna längt upp i minnet, från adress 0xFFFF och en bit nedåt. Vektorernas lägsta adress är 0xFF8C men utrymmet ner till 0xFF80 är reserverat varför vi kan se detta som den aktuella minnesarean. Denna del av minnet består av FLASH-minne som visserligen går att programmera men antalet programmeringscykler är begränsat (cirka 10000) och det skulle dessutom vara praktiskt att även kunna utnyttja avbrott i program som placeras i RAM-minne. För att göra detta så måste vi ta till en del knep som vi skall se på senare. Vi börjar med att placera avbrottsapplikationen i FLASH-minne. Eftersom vi inte kommer att göra några ändringar i RAM-minnet så kan vi behålla den tidigare startupfilen _startup_noirq_ram.s12, Bilaga 4. Då avbrottet genereras så kommer processorn att gå till den adress i avbrottsvektortabellen som tillhör det aktuella avbrottet (här RTI-avbrott som finns på adress 0xFFF0) och där läsa adressen till den rutin som den skall hoppa till. Vi måste alltså på något sätt se till att adressen till avbrottsrutinen Irq_RTI hamnar på denna adress i avbrottsvektortabellen. Även Resetvektorn ligger i denna tabell så vi kan på samma gång ordna så att processorn startar upp som den skall vid strömpåslag eller reset. Vid uppstart eller reset så skall den gå till labeln start (OBS två understrykningar) som ligger i filen _startup_noirq_ram.s12. Vi kan inte låta programmet initiera avbrottsvektorerna genom att till aktuell adress i avbrottstabellen skriva adressen till den rutin till vilken vi skall hoppa eftersom FLASH-minnet inte är skrivbart från vårt program. Vårt program skall nu innehålla en huvudrutin, en initieringsrutin för RTI-avbrottet, en avbrottsrutin och i vår första lösning två separata data-segment som placerar adresserna till våra två avbrottsrutiner på tillhörande avbrottsvektorers adresser. Vi använder en snarlik metod till den som vi tidigare använde för att göra göra FLASH-minnet läsbart för att skriva in adresserna till våra avbrottsrutiner i avbrottsvektorerna. Då de två avbrott vi använder oss av inte ligger på efterföljande adresser i avbrottsvektortabellen så får vi använda två nya #pragma-direktiv som innehåller pekare till våra avbrottsrutiner. Lägg också märke till att det tidigare #pragma-direktivet för att göra FLASH-minnet läsbart finns kvar. I huvudprogrammet anropar vi bara rutinen för initiering av RTI-avbrottet varefter vi lägger oss i en oändlig loop och väntar på avbrott. Kom ihåg att start ligger i startup-filen så funktionen måste deklareras som extern i vår C-fil. I koden skrivs den som _start som av kompilatorn kommer att tolkas som namnet på en C-rutin som i assembler översättas till labeln start. I avbrottsinitieringen RTI_Init sätter vi tiden mellan avbrott till via registret RTICTL. Vi kommer att få en fyrkantvåg med frekvensen 3,81 Hz, kom ihåg att det krävs två på varandra följande avbrott för att generera en period hos fyrkantvågen, ett avbrott för positiv halvperiod och ett avbrott för negativ halvperiod. Genom att ett-ställa bit 7 i registret CRGINT så tillåter vi RTI-avbrott. Till sist använder vi inline-assembler för att ge assemblerdirektivet CLI så att vi överhuvudtaget tillåter något bortmaskningsbart avbrott. I avbrottsrutinen Irq_RTI togglar vi PortB. Vi skriver dessutom en etta (1) till bit 7 i registret CRGFLG för att bekräfta avbrottet och därmed undvika ett nytt avbrott då vi återvänder från avbrottsrutinen. sida 18 systemklockan
19 Programmet blir naturligtvis lite mer komplicerat. Vi får Kod11 #include "..\HS12_DG.h" #include "..\reg_macro.h" char temp; void RTI_Init(void); extern void _start(void); interrupt void Irq_RTI(void); void main(void) REG8(DDRB)=0xFF; temp=0; RTI_Init(); while(1); void RTI_Init(void) REG8(RTICTL)=RTR6 RTR5 RTR4 RTR3 RTR2 RTR1 RTR0; REG8(CRGINT)=RTIE; asm(" CLI"); //0x7F //0x80 interrupt void Irq_RTI(void) REG8(PORTB)=temp; temp=!temp; REG8(CRGFLG)=REG8(CRGFLG) RTIF; //0x80 #pragma DATA UNSEC_address unsigned short unlock = 0xFFFE; #pragma DATA RTI_address interrupt void (*irq_rti[])() = Irq_RTI ; #pragma DATA RESET_address sida 19
20 interrupt void (*irq_reset[])() = _start ; Kod 11 Vi har använt oss av konstanter deklarerade i filen HS12_DG.h för att öka kodens läsbarhet. Koden, single_irq_flash.c, återges också i Bilaga 20. Då vi använder segment i skriptfilen för att sätta upp de aktuella avbrottsvektorerna så måste vi ta med dessa segment i skriptfilen. Vi får Kod 12 -M group( c, const_group ) abs group( r, ram_group) bss group( r, FLASH-_group) startupseg, text, cdata, data, group( r, unsec_group) UNSEC_address group( r, RTI_IRQ_vector ) RTI_address group( r, RESET_IRQ_vector ) RESET_address layout sida 20
21 0x1000,0x3FFF <= ram_group, 0xC000,0xFEFF <= flash_group, 0xFF0E,0xFF0F <= unsec_group, 0xFFF0,0xFFF1 <= RTI_IRQ_vector, 0xFFFE,0xFFFF <= RESET_IRQ_vector Kod 12 Filen, single_irq_flash_script.lsc, finns också i Bilaga 21 med kommentarer. Länkningen ger mapfilen single_irq_flash_debug.map enligt Bilaga 22. Vi ser att vi jämfört med tidigare mapfiler har fått med segment för avbrottsvektorerna för RTI- och RESET-avbrott. Vi ser också att i dessa segment ligger pekarna till anropslablarna för våra avbrottsrutiner. Mer generell lösning för program i FLASH-minne som innehåller avbrott Låt oss göra en lösning som är lite mer generell och som vi enkelt kan anpassa då vi använder andra avbrott. Vi fyller hela avbrottsvektortabellen med anropslablar till avbrottsrutiner men vi skriver inte alla dessa rutiner utan skriver bara rutiner för de avbrott vi skall använda medan vi omdirigerar övriga, oanvända avbrott till en tom, generell avbrottsrutin, Generic_Handler som inte gör någonting. Vi får avbrottsvektortabellen Kod 13 #pragma DATA vectors interrupt void (*irqvecs[])() = // FF80-FF8B is reserved (short *) 0xFFFF, (short *) 0xFFFF, (short *) 0xFFFF, (short *) 0xFFFF, (short *) 0xFFFF, (short *) 0xFFFF, Irq_PWMEShutdown, Irq_PortPInt, Irq_MSCAN4Tx, Irq_MSCAN4Rx, Irq_MSCAN4Errs, Irq_MSCAN4WakeUp, // FF98-FF9F is reserved (short *) 0xFFFF, (short *) 0xFFFF, (short *) 0xFFFF, (short *) 0xFFFF, // Byteflight FFA0 Irq_BFGen, sida 21
22 Irq_BFSync, Irq_BFRec, Irq_BFRx, // CAN1 FFA8 Irq_MSCAN1Tx, Irq_MSCAN1Rx, Irq_MSCAN1Errs, Irq_MSCAN1WakeUp, // CAN0 FFB0 Irq_MSCAN0Tx, Irq_MSCAN0Rx, Irq_MSCAN0Errs, Irq_MSCAN0WakeUp, // NV memory... Irq_Flash, Irq_EEPROM, // FFBC Irq_SPI2, Irq_SPI1, Irq_IICBus, Irq_BDLC, Irq_SCMEVect, Irq_CRGLock, Irq_PACCBOv, Irq_ModDnCtr, Irq_PortHInt, Irq_PortJInt, Irq_ATD1, Irq_ATD0, Irq_SCI1, Irq_SCI0, Irq_SPI0, Irq_PACCAEdge, Irq_PACCAOv, Irq_TimerOv, Irq_TimerCh7, Irq_TimerCh6, Irq_TimerCh5, Irq_TimerCh4, Irq_TimerCh3, Irq_TimerCh2, Irq_TimerCh1, Irq_TimerCh0, Irq_RTI, Irq_IRQ, Irq_XIRQ, Irq_SWI, Irq_Illop, Irq_COPFail, sida 22
23 ; Irq_ClockFail, _start Kod 13 Här har vi nu via direktivet #pragma DATA vectors deklarerat ett minnessegment med namnet vectors med pekare till avbrottsrutinerna och vi skall då strax se till att detta segment placeras i minnet på sådant sätt att avbrottsvektorerna hamnar på rätt adresser. Listan är nu gjord så att alla avbrottsvektorer är placerade i den ordning de förekommer i minneskartan och därmed hamnar på rätt adresser om vi placerar listan med start vi korrekt adress. Vi har dessutom sett till att fylla ut de reserverade positioner som finns i tabellen för att inte störa efterföljande vektorers offset. För att ta hand om oinitierade avbrott placerar vi en definitionslista före denna tabell, en lista som omdirigerar alla oanvända avbrott till default-rutinen Generic_Handler, en rutin som inte gör något men som vi också lägger in i koden. Denna default-rutin kommer dock i de flesta fall inte att ta hand om oinitierade avbrott på ett bra sätt eftersom de flesta avbrott måste bekräftas för att inte omedelbart uppträda igen. Det är denna rutin som i MC12 innehåller skrivning till terminal av ett meddelande som anger att vi har använt ett oinitierat avbrott. Vi får Kod 14 #define Irq_PWMEShutdown Generic_Handler #define Irq_PortPInt Generic_Handler #define Irq_MSCAN4Tx Generic_Handler #define Irq_MSCAN4Rx Generic_Handler #define Irq_MSCAN4Errs Generic_Handler #define Irq_MSCAN4WakeUp Generic_Handler #define Irq_BFGen Generic_Handler #define Irq_BFSync Generic_Handler #define Irq_BFRec Generic_Handler #define Irq_BFRx Generic_Handler #define Irq_MSCAN1Tx Generic_Handler #define Irq_MSCAN1Rx Generic_Handler #define Irq_MSCAN1Errs Generic_Handler #define Irq_MSCAN1WakeUp Generic_Handler #define Irq_MSCAN0Tx Generic_Handler #define Irq_MSCAN0Rx Generic_Handler #define Irq_MSCAN0Errs Generic_Handler #define Irq_MSCAN0WakeUp Generic_Handler #define Irq_Flash Generic_Handler #define Irq_EEPROM Generic_Handler #define Irq_SPI2 Generic_Handler #define Irq_SPI1 Generic_Handler #define Irq_IICBus Generic_Handler #define Irq_BDLC Generic_Handler #define Irq_SCMEVect Generic_Handler #define Irq_CRGLock Generic_Handler #define Irq_PACCBOv Generic_Handler #define Irq_ModDnCtr Generic_Handler sida 23
24 #define Irq_PortHInt Generic_Handler #define Irq_PortJInt Generic_Handler #define Irq_ATD1 Generic_Handler #define Irq_ATD0 Generic_Handler #define Irq_SCI1 Generic_Handler #define Irq_SCI0 Generic_Handler #define Irq_SPI0 Generic_Handler #define Irq_PACCAEdge Generic_Handler #define Irq_PACCAOv Generic_Handler #define Irq_TimerOv Generic_Handler #define Irq_TimerCh7 Generic_Handler #define Irq_TimerCh6 Generic_Handler #define Irq_TimerCh5 Generic_Handler #define Irq_TimerCh4 Generic_Handler #define Irq_TimerCh3 Generic_Handler #define Irq_TimerCh2 Generic_Handler #define Irq_TimerCh1 Generic_Handler #define Irq_TimerCh0 Generic_Handler //#define Irq_RTI Generic_Handler #define Irq_IRQ Generic_Handler #define Irq_XIRQ Generic_Handler #define Irq_SWI Generic_Handler #define Irq_Illop Generic_Handler #define Irq_COPFail Generic_Handler #define Irq_ClockFail Generic_Handler interrupt void Generic_Handler(void) // do nothing here... Kod 14 Lägg märke till att vi i #define-listan har anmärkt bort omdirigeringen av Irq_RTI. Eftersom vi skall använda detta avbrott så skall vi ju här i stället gå till den verkliga avbrottsrutin som vi har skrivit ovan. För att detta skall fungera så måste vi se till att vår avbrottsrutin har samma namn som finns angivet i avbrottstabellen, dvs här Irq_RTI. Lägg också märke till att vi behåller hopp till labeln start vid Reset och inte skriver över denna med #define-listan så resetvektorn finns inte med i denna lista utan listan slutar omedelbart före denna adress. Vi behåller skrivningen till FLASH-minnet för att göra detta minne läsbart som vi hade i föregående program men vår totala avbrottsvektortabell gör att vi skall ta bort skrivningen till de enskilda avbrottsvektorerna via #pragma-direktiv. Hela programmet, general_irq_flash.c, presenteras i Bilaga 23. Vi måste nu dessutom se till att datasegmentet vectors hamnar på rätt ställe i minnet, dvs på avbrottsvektorernas plats. Vi måste göra förändringar i skriptfilen till länkaren. Låt oss nu kalla filen general_irq_flash_script.lsc. Vi får alltså skapa en grupp som innehåller detta segment och placera den på rätt ställe i layouten. Vi får Kod 15 sida 24
25 -M Kod 15 group( c, const_group ) abs group( r, ram_group) bss group( r, flash_group) startupseg, text, cdata, data, group( r, unsec_group) UNSEC_address group( r, interrupt_vectors ) vectors layout 0x1000,0x3FFF <= ram_group, 0xC000,0xFEFF <= flash_group, 0xFF0E,0xFF0F <= unsec_group, 0xFF80,0xFFFF <= interrupt_vectors Den kompletta kommenterade skriptfilen, general_irq_flash_script.lsc, finns i Bilaga 24. Konfigureringen blir som i Figur 1 med den skillnaden att vi får byta till skriptfilen general_irq_flash_script.lsc för länkaren. Den resulterande mapfilen, general_irq_flash_debug.map, visas i Bilaga 25. Jämför vi med föregående mapfil så har de två segmenten innehållande avbrottsvektorerna för RTI- och RESET-avbrott försvunnit och ersatts av ett segment för vår kompletta avbrottsvektortabell. Vi ser också att vår avbrottsvektortabell i sig inte ger upphov till några globala symboler utan de enda avbrottssymboler som finns med är namnet på de avbrottsrutiner som används, dvs _Generic_Handler och _Irq_RTI. sida 25
26 Program i RAM-minne som innehåller avbrott Vi skall nu hitta en metod att låta program som ligger i RAM-minne använda avbrott trots att våra avbrottsvektorer ligger i FLASH-minne och inte direkt kan ingå i våra RAM-baserade program. Vi måste hitta en metod att dirigera om, relokera, avbrottsvektorerna så att vi kan nå dem via adresser i RAM-minne i stället för att adressera dem direkt i FLASH-minne. Det finns ingen möjlighet att konfigurera processorn att titta efter avbrottsvektorerna på några andra positioner i minnet än de positioner där de verkligen ligger utan vad vi får göra är att skriva ett program som gör att ett avbrott medför att programmet efter att ha läst aktuell avbrottsvektor hoppar till en adress i RAM-minnet. Detta kan vi bara göra genom ett program som placeras i FLASH-minnet vilket betyder vi kommer inte undan att programmera FLASH-minne men om vi skriver vårt program generellt, för alla olika avbrott, så räcker det att ladda ner detta program till FLASH-minne en enda gång varefter vi sedan kan använda detta program tillsammans med alla våra RAM-baserade applikationer. Lägg märke till att denna relokering är ett projekt för sig, en fristående applikation i FLASH-minne, även om den som vi skall se nedan saknar huvudprogram, och den är alltså inte direkt kopplad till den applikation vi sedan avser att placera i RAM-minne. Program för att relokera avbrottsvektorer till RAM-minne Vi måste alltså först skapa ett program i FLASH-minne som gör att vi vid avbrott får ett hopp till aktuell avbrottsrutin i RAM-minne. Detta program i FLASH-minne skall aldrig köras separat utan bara innehålla dessa stödrutiner för relokering av avbrottsvektorerna. Det betyder att vi inte skall göra något komplett program utan bara lägga ner en avbrottsvekortabell samt de rutiner som behövs för relokeringen till FLASH-minne och det innebär att vi skriver inget huvudprogram main() och har inte heller med någon startup-rutin, dvs vi tar inte med någon startup-fil bland projektets filer. Funktionen hos vårt FLASH-program får då för varje typ av avbrott bli sådan att vi på aktuell plats i den verkliga avbrottstabellen inte skriver adressen till aktuell avbrottsrutin, den rutinen finns ju i RAM-minne och vi vet ju faktiskt i nuläget inte dess startadress, utan i avbrottsvektortabellen skriver vi i stället adressen till en rutin i FLASH-minne som skall se till att vi går till rätt adress i RAM-minnet vid avbrottet och där hitta aktuell avbrottsrutin. Denna relokeringsrutin utformas då lämpligen inte så att vi hoppar till en specifik adress i RAM-minnet där vår avbrottsrutin finns eftersom detta skulle kräva att vi allokerar en fix del av RAM-minnet för varje typ av avbrott. Vi skulle få ett mycket oflexibelt program eftersom det skulle leda till att vi reserverar ett fixt antal minnesadresser för varje avbrottsrutin vilket betyder att en lång avbrottsrutin kanske inte får plats samtidigt som en kort rutin eller ingen rutin leder till tomma minnespositioner. Vi skall i stället utnyttja en instruktion som gör att vi går till en fast adress i RAM-minnet för varje avbrott och från den adressen läser adressen till den aktuella avbrottsrutinen, ungefär på samma sätt som vi vid avbrottet går till en fast adress i FLASH-minne (i avbrottsvektortabellen) och där läser adressen till avbrottsrutinen. Vi använder en form av pekare. Det är alltså bara dessa positioner i RAM-minnet för avbrottsrutinadresser som alltid behöver vara med i vår applikation. Den rutin i FLASH-minne som aktuell avbrottsvektor skall peka på skall då ha följande utseende Kod 16 sida 26
Programallokering. Programtyper. Att placera program i flashrespektive. Program i FLASH-minne. Program i RAM-minne
Programallokering Att placera program i flashrespektive RAM-minne Program i FLASH-minne Bara lokala variabler Globala oinitierade variabler Globala initierade variabler Program med avbrott Program i RAM-minne
LEU240 Mikrodatorsystem
Institutionen för data- och informationsteknik 2011-10-11 LEU240 Mikrodatorsystem Vi har tidigare i olika sammanhang sett att det är önskvärt att kunna använda ett högnivåspråk som C för att skriva program
Att använda pekare i. C-kod
Att använda pekare i C-kod (Bör användas av de som känner sig lite hemma med C-programmering!) Rev 1, 2005-11-23 av Ted Wolfram www.wolfram.se Syfte: Man kan tycka att det är komplicerat att använda pekare
A-del motsvarande KS1
MÄLARDALENS HÖGSKOLA Institutionen för elektroteknik Tentamen Mikrodatorteknik CT3760 Datum 2005-10-28 Tid 08.30 12.30 Svar till A- och B-del A-del motsvarande KS1 Uppgift A1. Vad blir resultatet då instruktionen
Elektroteknik MF1016 föreläsning 9 MF1017 föreläsning 7 Mikrodatorteknik
Elektroteknik MF1016 föreläsning 9 MF1017 föreläsning 7 - Inbyggda system - Analog till digital signal - Utvecklingssystem, målsystem - Labutrustningen - Uppbyggnad av mikrokontroller - Masinkod, assemblerkod
Datorsystem Laboration 2: Minnesmappade bussar
Datorsystem Laboration 2: Minnesmappade bussar Senast uppdaterad: 14 oktober 2012 Version 1.2 Student: Lärare: Underskrift: Underskrift: Datum: Datorsystem Laboration 2 1 Innehåll 1 Inledning 2 1.1 Introduktion..................................
Digital- och datorteknik
Digital- och datorteknik Föreläsning #17 Biträdande professor Jan Jonsson Institutionen för data- och informationsteknik Chalmers tekniska högskola Tallriksmodellen Stackoperationer Element kan endast
Datorteknik. Tomas Nordström. Föreläsning 6. För utveckling av verksamhet, produkter och livskvalitet.
Datorteknik Tomas Nordström Föreläsning 6 För utveckling av verksamhet, produkter och livskvalitet. Föreläsning 6 Vad händer vid uppstart SoC och Kringkretsar, PIO Programmering i Assembler Lab2 genomgång
Kontrollskrivning Mikrodatorteknik CDT209 2007-09-20 S2-704
Kontrollskrivning Mikrodatorteknik CDT209 2007-09-20 S2-704 Svar Svar till uppgifterna lämnas på separat papper. En poäng per uppgift. Max 30 poäng. Bonuspoäng beräknas enligt följande tabell: 6-10 poäng
Digital- och datorteknik
Digital- och datorteknik Föreläsning #18 Biträdande professor Jan Jonsson Institutionen för data- och informationsteknik Chalmers tekniska högskola Assemblerprogrammering Assemblatorer vs kompilatorer
Digital- och datorteknik
Digital- och datorteknik Föreläsning #8 Biträdande professor Jan Jonsson Institutionen för data- och informationsteknik Chalmers tekniska högskola Assemblatorer vs kompilatorer En assemblator är ett program
Effektpedal för elgitarr
EITF11 - Digitala Projekt Effektpedal för elgitarr Handledare: Bertil Lindvall Ivan Rimac (I05) Jimmy Lundberg (I08) 2011-05-10 Contents Bakgrund... 3 Kravspecifikation... 3 Kravspecifikation Effektpedal...
F5: Högnivåprogrammering
F5: Högnivåprogrammering Parameteröverföring Koppling mellan låg- och högnivåprogrammering Lokala variabler Heapen Datatyper 1 Subrutin, parameteröverföring: 1(3) Via register genom värde Skicka data via
F5: Högnivåprogrammering
1 F5: Högnivåprogrammering Parameteröverföring Koppling mellan låg- och högnivåprogrammering Lokala variabler Heapen Datatyper 1 Subrutin, parameteröverföring: 1(3) Via register genom värde Skicka data
Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe
Kodningskonventioner Viktor Kämpe Varför kodningskonventioner? Förståelse för Skillnaden mellan lokala/globala variabler. Funktionsargument. Returvärde. Möjliggör Mix av assembler och C. Kodningskonventioner/VK
Ansvarig lärare: Olof Andersson, Telefon 021-101314 (besöker skrivsalen)
MÄLRLENS HÖGSKOL Institutionen för elektroteknik Tentamen Mikrodatorteknik T3760 atum 2005-10-28 Tid 08.30 12.30 nsvarig lärare: Olof ndersson, Telefon 021-101314 (besöker skrivsalen) Om du klarat samtliga
Övningar Dag 2 En första klass
Kurs i C++ Sid 1 (5) Övningar Dag 2 En första klass Denna övning går ut på att steg för steg bygga upp en klass och skapa objekt. Vi kommer att utgå från en sammansatt datatyp i en struct och parallellt
Programmeringsteknik med C och Matlab
Programmeringsteknik med C och Matlab Kapitel 2: C-programmeringens grunder Henrik Björklund Umeå universitet Björklund (UmU) Programmeringsteknik 1 / 32 Mer organisatoriskt Imorgon: Datorintro i lab Logga
Föreläsning 6: Introduktion av listor
Föreläsning 6: Introduktion av listor Med hjälp av pekare kan man bygga upp datastrukturer på olika sätt. Bland annat kan man bygga upp listor bestående av någon typ av data. Begreppet lista bör förklaras.
Stack och subrutiner Programmeringskonventionen
Stack och subrutiner Programmeringskonventionen Du ska förstå hur en instruktion behandlas i processorn Du ska känna till några fler instruktioner Du ska veta hur maskinkoden för ett program byggs upp
Systemkonstruktion LABORATION REALTIDSPROGRAMMERING
Systemkonstruktion LABORATION REALTIDSPROGRAMMERING Laborationsansvariga: Anders Arvidsson, Björn Lundblad Utskriftsdatum: 2002-10-31 Laboranter: 1 Syfte Denna laboration syftar till att öva användningen
Mål. Datorteknik. Repetition av avbrott. Innehåll. Mätning och styrning. Datorer för mätning och styrning. timer. Datorsystem A/D. Analog insignal D/A
Mål Datorteknik Föreläsning 5 Att du ska förstå hur avbrott används för - Mätning - Styrning - Stöd för körning av fle processer Att du ska förstå begreppet tråd Att du ska veta hur odelba resurser kan
Provmoment: Ladokkod: Tentamen ges för: Tentamen TE111B El3. Namn: Personnummer: Tentamensdatum: 20120410 Tid: 14:00-18:00.
Mikrodatorteknik Provmoment: Ladokkod: Tentamen ges för: Tentamen TE111B El3 7,5 högskolepoäng Namn: Personnummer: Tentamensdatum: 20120410 Tid: 14:00-18:00 Hjälpmedel: Totalt antal poäng på tentamen:
Föreläsningsanteckningar 3. Mikroprogrammering II
Föreläsningsanteckningar 3. Mikroprogrammering II Olle Seger 2012 Anders Nilsson 2016 1 Inledning Datorn, som vi byggde i förra föreläsningen, har en stor brist. Den saknar I/O. I denna föreläsning kompletterar
Flera processer. Minneshantering. Trashing kan uppstå ändå. Ersätta globalt
Flera processer Minneshantering Operativsystem lektion 6 Potentiellt problem: Den sida som plockas bort behöver inte vara den sida som används minst!! Det kan finnas andra processer som inte körs eller
AVR 3 - datorteknik. Avbrott. Digitala system 15 hp. Förberedelser
Namn: Laborationen godkänd: Digitala system 15 hp AVR 3 - datorteknik LTH Ingenjörshögskolan vid Campus Helsingborg Avbrott. Syften med den här laborationen är att introducera avbrott. Avbrott som uppkommer
Introduktion till arv
Introduktion till arv 6 INTRODUKTION TILL ARV Arv Generell-Speciell Arv för att utnyttja det vi redan gjort Återanvändning Basklass Härledd klass Varför arv? Inför en subklass för att uttrycka specialisering
BDM12 Användarbeskrivning. Introduktion
Versioner/ändringar 1.0 2003-07 1.01 BUGFIX: FLASH unsecure algoritm 1.02 Fördröjning vid flash-prog. Statusutskrift under programmeringen. Programmeringsalgoritmen hanterar nu även 'bankade' minnet. Översättning
Systemkonstruktion SERIEKOMMUNIKATION
Systemkonstruktion SERIEKOMMUNIKATION Laborationsansvariga: Anders Arvidsson Utskriftsdatum: 2005-04-26 Syfte Laborationen syftar till att ge studenten tillfälle att närmare bekanta sig med RS-232-protokollet,
Övningsuppgifterna i kapitel F avser FLIS-processorn, vars instruktioner och motsvarande koder definieras i INSTRUKTIONSLISTA FÖR FLISP.
Övningsuppgifter Övningsuppgifterna i kapitel F avser FLIS-processorn, vars instruktioner och motsvarande koder definieras i INSTRUKTIONSLISTA FÖR FLISP. F.2 Ett antal på varandra följande minnesord har
CPU. Carry/Borrow IX. Programräknare
Laboration:. Jämförelser mellan assembler och C. CPU ACCA ACCD ACCB 8-bitars ackumulatorer eller 16- bitars ackumulator CCR 1 1 1 SXH I NZVC Flaggregister Carry/Borrow IX IY PC Indexregister X Indexregister
Maskinorienterad programmering
Externa avbrott Anslutning av extern avbrottsvippa, programmering med konfigurering och hantering av externa avbrott. Introduktion till time-sharing, enkel task-switch. Ur innehållet: NVIC och EXTI (SYSCFG)
Laboration 4: Knappstuds Drivrutiner för att eliminera störningar.
ATMega16 Laborationer av Kjell 2 Rev:5 Datum: 29.09.2010 Page 1 of 7 Laboration 4: Knappstuds Drivrutiner för att eliminera störningar. Inledning: Laborationskortet EasyAVR6 har bland annat tryckknappar
TSIU50 Mikrodatorprojekt. LAB1 AVR-introduktion och logikanalysator
1 2 TSIU50 Mikrodatorprojekt LAB1 AVR-introduktion och logikanalysator Michael Josefsson Januari 2007 Detta häftes syfte är att tjäna som en snabb introduktion till utvecklingsmiljön AVRStudio och den
Lathund. C för inbyggda system
Lathund C för inbyggda system Revision 1 2000-09-21 Anders Arvidsson Jonny Martinsson Synpunkter välkomnas! Innehållsförteckning 1 Introduktion...3 1.1 Assembler kontra C...3 1.2 Kodexempel...3 1.3 MPLAB...4
Övning1 Datorteknik, HH vt12 - Talsystem, logik, minne, instruktioner, assembler
Övning1 Datorteknik, HH vt12 - Talsystem, logik, minne, instruktioner, assembler Talsystem Talsystem - binära tal F1.1) 2 n stycken tal från 0 till 2 n 1 F1.2) 9 bitar (512 kombinationer) Talsystem - 2-
Maskinorienterad programmering
Undantagshantering och interna avbrott ARM Cortex-M4 exceptions, programmering av undantagshantering Ur innehållet: Faults Software traps Avbrott från interna enheter, Systick Läsanvisningar: Arbetsbok
Tillämpad digital signalbehandling Signalprocessorn Statiska moduler och buffrar
Institutionen för data- och elektroteknik 2004-02-22 Inledning En statisk modul bevaras i programminnet mellan bootsidor genom att länkaren ser till att den hamnar i en del av programminnet som inte skrivs
7) Beskriv tre sätt att överföra parametrar mellan huvudprogram och subrutin.
1(5) Övningstentamen i Mikrodatorer och assemblerprogrammering, ELGA05 Hjälpmedel: Bifogad lista med memokoder för MC68xxx. Samtliga programmeringsuppgifter ska innehålla flödesschema med förklaringar
Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson
Grundläggande C-programmering del 2 Pekare och Arrayer Ulf Assarsson Läromoment: Pekare Absolutadressering (portar): typedef, volatile, #define Arrayer av pekare, arrayer av arrayer Hemuppgifter: v2. Föregående
Enkla datatyper minne
Enkla datatyper minne 143.56 sant Sonja A falskt 18 1999-10-29 Bertil Gralvik, KTH Ingenjörsskolan 1 Addera två tal Algoritmen Summera tal Mata in två tal Beräkna Skriv ut resultat Mata in tal 1 Mata in
7 Mamut Client Manager
7 Mamut Client Manager Tilläggsprodukten Mamut Client Manager består av programmen Client Start och Client Update. Med hjälp av Mamut Client Manager kan du från ett fönster öppna, uppdatera och administrera
19. Skriva ut statistik
19. Skiva ut statistik version 2006-05-10 19.1 19. Skriva ut statistik Den här dokumentationen beskriver hur man skriver ut statistik från SPFs medlemsregister via Internet. Observera att bilderna är exempel
#include <pic.h> #include <sys.h> char LEFT,RIGHT,MOTORHASTIGHET;
Att avlusa en rad Assembler tar lika lång tid som att avlusa en rad C. Att skriva i C gör att man är utlämnad till kompilatorns sätt att göra assembler koden. Assembler ger fullständig kontroll över tider.
Programmering, grundkurs, 8.0 hp, Elektro, KTH, hösten 2010
Föreläsning 6 Kapitel 5 5.1 switch-satsen Vi ser på ett par exempel ur boken: int a; srand(time(0)); a=rand()%6+1; if(a==1) printf("hej Du glade\n"); else if(a==2) printf("god dag\n"); else if(a==3) printf("är
EDA480/EDA485 - Maskinorienterad programmering, tentamen 2006-xx-xx 1(7)
EDA480/EDA485 - Maskinorienterad programmering, tentamen 2006-xx-xx 1(7) 1. Motivation ROM. 8kbyte 2 3 2 10 byte 13 Adressbitar [A12,A0] direkt till ROM-kapsel. RWM. 32kbyte 2 5 2 10 byte 15 Adressbitar
Realtidsprogrammering. En introduktion Implementering (med exempel från PIC)
Realtidsprogrammering En introduktion Implementering (med exempel från PIC) Utan timing Periodtid varierar beroende på funktionernas exekveringstid. Specificera endast maxtid ( Worst case) och eventuellt
Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson
Grundläggande C-programmering del 2 Pekare och Arrayer Ulf Assarsson Läromoment: Pekare Absolutadressering (portar): typedef, volatile, #define Arrayer av pekare, arrayer av arrayer Hemuppgifter: v2. Föregående
Digital- och datorteknik
Digital- och datorteknik Föreläsning #19 Biträdande professor Jan Jonsson Institutionen för data- och informationsteknik Chalmers tekniska högskola Normaltillstånd vs undantagstillstånd I normaltillstånd
Inledande programmering med C# (1DV402) 27+15=42 1 (22)
27+15=42 1 (22) Variabler Upphovsrätt för detta verk Detta verk är framtaget i anslutning till kursen Inledande programmering med C# vid Linnéuniversitetet. Du får använda detta verk så här: Allt innehåll
AVRStudio på tre minuter. Micke Josefsson, 2005
AVRStudio på tre minuter Micke Josefsson, 2005 Mycket kort intro till AVRStudio Utvecklingsmiljön AVRStudio innehåller en editor för att mata in programmet, en simulator för att under kontrollerade former
HF0010. Introduktionskurs i datateknik 1,5 hp
HF0010 Introduktionskurs i datateknik 1,5 hp Välkommna - till KTH, Haninge, Datateknik, kursen och till första steget mot att bli programmerare! Er lärare och kursansvarig: Nicklas Brandefelt, bfelt@kth.se
Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp
Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp Dataingenjörsprogrammet, elektroingenjörsprogrammet och medicinsk teknik KTH Skolan för Teknik och Hälsa Redovisning: Se Kurs-PM om hur redovisningen
1 Funktioner och procedurell abstraktion
1 Funktioner och procedurell abstraktion Det som gör programkonstruktion hanterlig och övergripbar och överhuvudtaget genomförbar är möjligheten att dela upp program i olika avsnitt, i underprogram. Vår
Lösningar till tentamen i EIT070 Datorteknik
Lösningar till tentamen i EIT070 Datorteknik Institutionen för Elektro- och informationsteknik, LTH Torsdagen den 13 mars 2014, klockan 14:00 19:00 i MA:10. Tillåtna hjälpmedel: på tentan utdelad formelsamling,
Föreläsning 3.1: Datastrukturer, en översikt
Föreläsning.: Datastrukturer, en översikt Hittills har vi i kursen lagt mycket fokus på algoritmiskt tänkande. Vi har inte egentligen ägna så mycket uppmärksamhet åt det andra som datorprogram också består,
Lösningar till tentamen i EIT070 Datorteknik
Lösningar till tentamen i EIT070 Datorteknik Institutionen för Elektro- och informationsteknik, LTH Onsdagen den 13 mars 2013, klockan 14:00 19:00 i Vic 2 A-D, 3 A-C. Tillåtna hjälpmedel: på tentan utdelad
Digital- och datorteknik
Digital- och datorteknik Föreläsning #21 Biträdande professor Jan Jonsson Institutionen för data- och informationsteknik Chalmers tekniska högskola Teknologier och hierarkier Minnestyper Vi har hittills
CE_O6. Parallell in/utmatning (I/O). Förberedelser till laboration nios2io.
IS1200 Exempelsamling till övning CE_O6, 2015 CE_O6. Parallell in/utmatning (I/O). Förberedelser till laboration nios2io. 6.1. Läs in data från IN-port (skjutomkopplare TOGGLES18) Skriv en subrutin, Get_Data
Datorteknik 2 (AVR 2)
Namn: Laborationen godkänd: Digitala system 15 hp Datorteknik 2 (AVR 2) LTH Ingenjörshögskolan vid Campus Helsingborg Enkel in- och utmatning. Drivrutiner. Bithantering. I denna laboration ska vi förbättra
Beskrivning av porthantering i mikroprocessorn SAM3U som används på vårt labkort SAM3U- EK.
Tomas Nordström Högskolan i Halmstad Dokumentversion 0.1, 2012-04- 01 Beskrivning av porthantering i mikroprocessorn SAM3U som används på vårt labkort SAM3U- EK. Informationen till detta kompendium är
www.telefrang.se Telefrang Smoke Control System Installationsmanual för Midi- och MaxiSmoke 2008-02-18 Sida 1 av 12
Telefrang Smoke Control System Installationsmanual för Midi- och MaxiSmoke MaxiSmoke MidiSmoke File: D:\Projekt\SMOKE CONTROL\MIDI SMOKE\Man\Midisystem_inst_man_V01.odt 2008-02-18 Sida 1 av 12 1. Installation
Grunderna i stegkodsprogrammering
Kapitel 1 Grunderna i stegkodsprogrammering Följande bilaga innehåller grunderna i stegkodsprogrammering i den form som används under kursen. Vi kommer att kort diskutera olika datatyper, villkor, operationer
Kapitel 22: Överföring av variabler och uppgradering 365. I fönstret VAR-LINK visas en lista med definierade variabler, Flashprogram
Kapitel 22: Överföring av variabler och uppgradering 22 Länka två enheter... 366 Överföra variabler, Flash-program och mappar... 367 Överföra variabler under från ett program... 371 Uppgradera programkod
Att komma igång med FirstClass (FC)!
Att komma igång med FirstClass (FC)! Vi har tillgång till FC genom vårt samarbete med folkhögskolor och därigenom med Folkbildningsnätet. FC kan användas på en dator på två sätt (dessutom kan du använda
Dataminne I/O Stack 0x005D 0x3D SP low byte 0x005E 0x3E SP high byte
CT3760 Mikrodatorteknik Föreläsning 4 Tisdag 2005-09-06 Stacken I datasammmanhang är en stack ett minnesområde. Det är processorn som använder stacken. För att skapa en stack anger man en adress i stackpekarregistret.
Lathund. C för inbyggda system
Lathund C för inbyggda system Revision 2 2001-04-13 Anders Arvidsson Jonny Martinsson Synpunkter välkomnas! Innehållsförteckning 1 Introduktion... 3 1.1 Assembler kontra C... 3 1.2 Kodexempel... 3 1.3
Komma igång med E-Line RIO
Supportdokument Komma igång med E-Line RIO Synpunkter, felaktigheter, önskemål etc. för dokumentet meddelas Fil: Malthe_Suppo_Ladda upp filer från.docx Innehållsförteckning 1. Allmänt... 2 2. Systen setup...
Minnen delas in i två huvudgrupper, permanenta och icke permanenta. Non-volatile and volatile.
CT3760 Mikrodatorteknik Föreläsning 2 Tisdag 2005-08-30 Minnestyper. Atmega 16 innehåller följande minnestyper: SRAM för dataminne FLASH för programminne EEPROM för parametrar och konstanter. Minnen delas
Övningsuppgifter STYRNING - i Mikrodatorteknik för U2 2010
STYRNING - i Mikrodatorteknik för U2 2010 1. Uppgift M10 (5p) aug-09 Skriv ett program i PIC-assembler som - gör PortB till utport - ettställer bit 0, 3 och 4 i PortB - nollställer bit 5 och 6 i PortB
Digital- och datorteknik
Digital- och datorteknik Föreläsning #17 Biträdande professor Jan Jonsson Institutionen för data- och informationsteknik Chalmers tekniska högskola F-36 FLEX- och FLIS-datorn Ext-8 Tallriksmodellen Stackoperationer
Maskinorienterad programmering
Undantagshantering och interna avbrott ARM Cortex-M4 exceptions, programmering av undantagshantering Ur innehållet: Faults Software traps Avbrott från interna enheter, Systick Läsanvisningar: Arbetsbok
Växtviskaren EITF11 Digitala projekt VT15, I12
Växtviskaren EITF11DigitalaprojektVT15,I12 NathalieLiljebrunn,EbbaRiismark,AnnaNorelius LundsTekniskaHögskola Institutionenförelektro ochinformationsteknik Handledare:BertilLindvall,AndreasJohansson 2015
LABORATIONSINSTRUKTION
Högskolan Dalarna Institutionen för Elektroteknik LABORATION LABORATIONSINSTRUKTION LOG/iC, PLD, kombinatorik, sekvensnät KURS Digitalteknik LAB NR 6 INNEHÅLL. Inledning 2. Prioritetskodare 3. Elektronisk
mikroicd Avbuggare Handbok
mikroicd Handbok Avbuggare mikroicd avbuggare är ett mycket effektivt verktyg för realtid felsökning på hårdvara nivå. Den gör att du kan övervaka program variabelvärden, Speciella Funktion Register (SFR)
Laboration 2 i Datorteknik- Assemblerprogrammering II
Högskolan i Halmstad 1 (8) - Assemblerprogrammering II Målet med laborationen är att få begrepp om Subrutiner. in/utparametrar. Lokala variabler Maska in bitar till ett register Konstruktion av subrutiner
KARMATIC PROFILER 2000 Manual
KARMATIC PROFILER 2000 Manual Beskrivning Karmatic 2000.2 Instrument för rundhetsmätning av kommutator och släpringar. Mätnoggrannhet / repeterbarhet : 1,5 m förutom yttre störningar t.ex. vibrationer.
Manual. Användargränssnitt
Manual Användargränssnitt 0 Innehållsförteckning ANVÄNDARGRÄNSSNITT... 1 1. MENYNAVIGERING... 1 2. BACKA-KNAPP... 2 3. GLOBALA FUNKTIONER... 3 4. PERIOD... 4 Avrundning... 4 5. FLERA FLIKAR SAMTIDIGT...
Till assemblersystemet Zuper 80 Assembler krävs en SPECTRAVIDEO 328/318+minst 16K ram extra.
ZZZZZ 888 000 A Z 8 8 0 0 A A ZZ 8 8 0 0 A A ZZ u u pppp eee r rrr 888 0 0 AAAAA ZZ u u p p e e rr --- 8 8 0 0 A A ZZ u u p p e ee r 8 8 0 0 A A Z u u p p e r 8 8 0 0 A A ZZZZZ uuuu pppp eeee r 888 000
I denna laboration undersöker vi hur aritmetiska beräkningar utförs. Vi tittar på olika variabeltyper: 8-bitars, 16-bitars, 32-bitars och flyttal.
Laboration:. Jämförelser mellan assembler och C. I denna laboration undersöker vi hur aritmetiska beräkningar utförs. Vi tittar på olika variabeltyper: 8-bitars, 16-bitars, 32-bitars och flyttal. Förberedelser:
Microprocessor / Microcontroller. Industrial Electrical Engineering and Automation
Microprocessor / Microcontroller Varför? Billiga Innehåller bara det nödvändigaste Kräver få kringkomponenter Enkla att programmera PIC16F887 PIC16F887 In- och utgångar Pinnar på PIC16F887 Exempel: pinne
FÄLTMÄTINSTRUKTION TESTO 174H
1(8) 1. Allmänt Dataloggern Testo 174H mäter fukt och temperatur samt daggpunkt. Den används för att lagra och läsa ut separata mätvärden samt hela mätsekvenser. Värdena registreras, sparas och överförs
Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.
Institutionen för Datavetenskap Göteborgs universitet HT2009 DIT011 Vem är vem på kursen Objektorienterad programvaruutveckling GU (DIT011) Kursansvarig : Katarina Blom, tel 772 10 60 Rum: 6126 (E-huset)
Föreläsning 2: Avlusning och antilustekniker
2D1458, Problemlösning och programmering under press Föreläsning 2: Avlusning och antilustekniker Datum: 2007-09-11 Skribent(er): Emil Hesslow, Stefan Pettersson Föreläsare: Per Austrin Föreläsningen handlade
F8: Undantagshantering
F8: Undantagshantering Undantagshantering i 68 Vad är ett undantag? Typer av undantag Att skriva undantagsrutiner Undantagshantering, vad och varför? Exempel: Ett system ska mäta temperatur var :e sekund
General Purpose registers ALU I T H S V N Z C SREG. Antag att vi behöver skriva in talet 25 till register R18
F3 Föreläsning i Mikrodatorteknink 2006-08-29 Kärnan i microcontrollern består av ett antal register och en ALU. Till detta kommer också ett antal portar. Det finns 64 st portar. Några är anslutna mot
Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??
Programmera i C Varför programmera i C när det finns språk som Simula och Pascal?? C är ett språk på relativt låg nivå vilket gör det möjligt att konstruera effektiva kompilatorer, samt att komma nära
CE_O3. Nios II. Inför lab nios2time
IS1200 Exempelsamling till övning CE_O3, 2015 CE_O3. Nios II. Inför lab nios2time 3.1. Logiska operationer (se uppgift 1.2 c) Repetera (eller lär dig) innebörden av de logiska operationerna "bitvis AND",
Manual. Abelko M-Bus Device Creator (MBDC)
Manual Abelko M-Bus Device Creator (MBDC) Syfte Syftet med "M-Bus Device Creator (MBDC)" är att tillåta Abelko's IMSE WebMaster Pro (WMPro) att kommunicera med mätutrustning som använder sig av M-Bus standarden.
Start-Up Customization Applikation för TI-83 Plus
TI Start-Up Customization Applikation för TI-83 Plus Komma igång Börja här Hur Anpassa Start-Up med en bild Anpassa Start-Up med ett program Anpassa Start-Up med en applikation Stänga av Start-Up Customization
*Pekarvärden *Pekarvariabler & *
*Pekarvärden *Pekarvariabler & * Motivering Pekare är ett fundamentalt koncept i C (och C++) Multipla returvärden från funktioner. Arrayer hanteras via pekare Dynamiskt minne (kommer i slutet av kursen)
Figur 1 Skalprogrammets meny
Institutionen för data- och elektroteknik 2004-04-14 Att köra mjukvaran till signalprocessorn 1 Inledning Bland programvarorna till signalprocessorn är systembyggare, assemblator, länkare, PROM-Splitter
Tentamen med lösningsförslag
Institutionen för data- och informationsteknik CHALMERS TEKNISKA HÖGSKOLA Tentamen med lösningsförslag EDA482 (EDA481) Maskinorienterad programmering D EDA487 (EDA486) Maskinorienterad programmering Z
Avbrottshantering. Övningsuppgifter
Avbrottshantering Övningsuppgifter 2013 Besvara kortfattat följande frågor rörande CPU12. Redogör för vad som händer vid RESET och varför detta sker. Förklara kortfattat vad som händer vid ett IRQ avbrott
Programmering av inbyggda system 2013/2014
Programmering av inbyggda system 2013/2014 CPU12 Reference Guide Stencil: Assemblerprogrammering.pdf Ur innehållet: Räknarkretsar ( TIMERS ) Pulsbreddsmodulering ( PM ) Analog-/Digital- omvandling ( AD
IS1500 Lösningar övning CE_O7 2014. CE_O7. Programmerad in/utmatning. Serieport. Förberedelser till nios2io.
IS1500 ösningar övning CE_O7 2014 CE_O7. Programmerad in/utmatning. Serieport. Förberedelser till nios2io. 6.1. Vad är seriell kommunikation? a) Vad är skillnaden mellan seriell och parallell kommunikation?
Laborationer i kursmomentet Datoranvändning E1. Laboration nr 5: Mer om FrameMaker
Sid 1 Laborationer i kursmomentet Datoranvändning E1 http://www.etek.chalmers.se/~hallgren/eda/ : Mer om FrameMaker 1996, 1997 Magnus Bondesson 1998 och 99-09-22 Thomas Hallgren 1 Introduktion I Laboration
Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp
Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp Dataingenjörsprogrammet, elektroingenjörsprogrammet och medicinsk teknik KTH Skolan för Teknik och Hälsa Redovisning: Se Kurs-PM om hur redovisningen
Installationsanvisning för kursens programvara på egen dator
Installationsanvisning för kursens programvara på egen dator Två program, Java och DrJava, skall installeras på datorn. DrJava är en så kallad utvecklingsmiljö, ett program som underlättar att programmera
Institutionen för datavetenskap 2014/15
LUNDS TEKNISKA HÖGSKOLA Datorer och datoranvändning Institutionen för datavetenskap 2014/15 ME en dator 1 Inledning ME är en påhittad dator, men den har likheter med riktiga datorer: det finns ett maskinspråk