RECENSIE RECENSIE Treed binnen in de wereld van parallelle verwerking met de Parallax Propeller ™ Door Dr William Marshall, RS Components Zo nu en dan zien we ineens iets nieuws. De ontwikkeling van microcontrollerchips volgt al jaren hetzelfde pad: óf dezelfde ‘basis-’processor wordt omgeven door steeds meer randapparaten, óf de processor zelf wordt steeds krachtiger gemaakt. Cog 0 Cog 1 Cog 2 Cog 3 Cog 4 Cog 5 Cog 6 Cog 7 Pin-richting Pin-uitvoer I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL I/O-richtingsreg. Videogenerator I/O-uitgangsreg. Teller A + PPL Teller B + PPL 32 32 P31 P15 P30 P14 P29 P13 P28 P12 P27 P11 P26 P10 P25 P9 P24 P8 I\O Pins P23 P7 P22 P6 P21 P20 P5 P4 512 x 32 RAM 512 x 32 RAM 512 x 32 RAM 512 x 32 RAM 512 x 32 RAM 512 x 32 RAM 512 x 32 RAM 512 x 32 RAM P19 P3 P18 P2 Processor Processor Processor Processor Processor Processor Processor Processor P17 P16 P1 P0 32 32 Pin-invoer 32 Systeemteller 32 Databus 16 Adresbus P28 P29 P30 P27 34 35 36 37 VSS VDO P31 38 39 40 P1 P2 P3 P0 41 42 43 44 VSS P4 1 33 P26 P5 2 32 P25 P6 3 31 P24 P7 4 30 VDD P9 10 24 P21 P10 11 23 P20 22 P22 21 P23 25 20 26 9 19 8 P8 18 VDD 17 VSS 16 XI 27 15 28 7 14 29 6 12 5 RESn 12 VSS BOEn XO P19 P17 P18 P16 P15 VSS VDD P14 P11 P13 RESET Resetvertraging (~50 ms) Brown-outdetector BOEn Bus-sequencer Cog 0 8192 x 32 RAM CLKSEL RESn 3 RC-oscillator 12 MHz / 20 MHz SOFTRES 5 PLLENA XI OSCENA OSCMODE 2 Kristaloscillator DC 0 80 MHz(4 - 8 MHz met klok PLL) Klok PLL 1x, 2x, 4x, 8x, 16x,(16x moet 64 128 MHz zijn) Klokselector (MUX) Hub Cog schakelt in Cog 6 Lock-bits (8) SOFTRES PLLENA OSCENA OSCMODE CLKSEL 2 3 Configuratie Register Cog 1 Cog 7 8192 x 32 RAM KLOK Systeemteller KLOK 3 XO P12 Hub Power-updetector (~10ms) VDD Systeemteller Cog 2 RAM, ROM,configuratie, besturing Cog 5 Cog 3 Cog 4 Hub- & Cog-interactie fig. 1 20 eTech - NUMMER 3 I/O Pins Het gemeenschappelijke kenmerk is een enkele processor ondersteund door een gespecialiseerde, toepassingsgerichte logica, die functies heeft zoals Pulse Width Modulation-uitvoer en pulstellerinvoer. De Propeller van Parallax staat voor een grote verandering in de filosofie achter ontwerpen. Dit apparaat bevat acht 32-bits processoren of ‘COG's’ met minimale ondersteunende logica en alleen de meest fundamentele I/O-hardware (fig.1). Een eerste reactie op deze indeling zou kunnen zijn: ‘Geweldig, ik kan dat neurale netwerkproject implementeren waarbij iedere COG in principe hetzelfde programma draait’. Hoewel zuivere parallelle verwerking inderdaad een goede toepassing kan zijn voor de Propeller, geloof ik niet dat dit de belangrijkste drijfveer achter het ontwerp was. Het idee is een elektronica-ontwerper maximale controle te geven over het systeem van randapparatuur in een specifieke toepassing. U kunt nog steeds een enkele COG gebruiken waarop het hoofdprogramma draait, en ondergeschikte taken zoals seriële I/O uitbesteden aan een andere COG wanneer dat wenselijk is. Dit is een fascinerende eigenschap van het apparaat: de mogelijkheid zichzelf te herconfigureren, aangestuurd door het programma, om te voldoen aan de voorwaarden op een bepaald moment en processen te stoppen wanneer ze niet meer nodig zijn, misschien zelfs processor-resources toe te wijzen aan een hele andere taak. De processorklok wordt ook aangestuurd door het programma, zodat het stroomverbruik kan worden gereduceerd wanneer er geen hoge snelheid nodig is bij het implementeren van langzame I/O zoals RS-232. De starterskit-hardware De set bevat een zeer klein demobord volgebouwd met verschillende I/O-verbindingen, waarvan enkele zeer verrassend zijn: VGA-uitvoer naar een monitor, TV-uitvoer, PS/2-toetsenbord en muis. De videouitvoer kan worden verzorgd omdat de centrale resource-ROM van de chip de opzoektabel bevat van een karaktergenerator. De enige ‘conventionele’ I/Opoort is USB, die komt vanaf de on-board FTDI-chip. De UART-functie die dit apparaat bestuurt is natuurlijk volledig in software geïmplementeerd en draait op één van de COG's. Alle communicatie met de IDEsoftware op de PC - Propeller Tool – gebeurt via de USB-poort. Dit is een seriële EEPROM on-board die met de Propeller communiceert via een I2C-bus die, u raadt het al, is geïmplementeerd in software die draait op een COG. Het biedt niet-vluchtig geheugen voor gebruikersprogramma's. Deze I/O-routines worden geladen vanaf de systeem-ROM bij een reset, waardoor programma's kunnen worden gedownload vanaf de PC of vanaf de EEPROM, maar worden afgesloten voordat het programma van de gebruiker wordt uigevoerd. Als uw programma deze I/O-resources nodig heeft, dan moet hij deze laden en COG('s) toewijzen waar nodig. Dit kan eerst een beetje vreemd lijken, maar waarom zou u toestaan dat ongebruikte resources geheugenruimte in beslag nemen terwijl u ze niet nodig heeft? Propeller Tool De IDE in de starterskit heet Propeller Tool en biedt de mogelijkheid voor programmabewerking, compilatie van de hogere programmeertaal Spin en downloaden naar het demobord. U heeft de optie om te programmeren in Spin, assembleertaal of een combinatie van beide. Uiteraard biedt de assembler efficiëntere en snellere verwerking, dus er is sprake van het gebruikelijke compromis tussen snellere ontwikkeling en snellere verwerking. Het bewerkingsvenster is zeer kleurrijk en de automatische toewijzing van verschillende kleuren aan codeblokken helpt bij het begrijpen van de programmastructuur. Er zijn twee opties voor downloaden en uitvoeren: u kunt compileren en uitvoeren in COG RAM of compileren en daarna naar een EEPROM sturen, van waaruit het automatisch wordt geladen in de RAM door de bootloader van het apparaat. De eerste is de beste optie voor ontwikkeling, omdat alleen niet-vluchtig geheugen wordt overgedragen als de code werkt. gebruik van het demobord Om enkele van de belangrijkste eigenschappen van Propeller-programmeren te laten zien, is een taak gemaakt met de snelheidscontrole van een kleine DC-motor met behulp van PWM. Twee drukknoppen zorgen voor de invoer van Speed Up en Speed Down. Het aandrijfvermogen van de I/O-poorten is onvoldoende voor de gebruikte motor, daarom is er een H-Bridge-circuit gebouwd met de helft van een L293D quad driver chip. Deze werd op het proefbord gemonteerd, samen met twee ‘tact’-schakelaars, afstopweerstanden en ontkoppelcondensatoren (zie de afbeelding op pagina 23). U kunt zien dat de D-variant van deze chip is gebruikt, die ingebouwde beveiligingsdiodes heeft voor het aansturen van inductieve belasting. Alleen de poorten 0 tot en met 7 van de mogelijke 32 poorten van de Propeller zijn beschikbaar voor de gebruiker, de andere poorten zijn verbonden met EEPROM-bussen etc. op dit demobord. De Propeller is een +3,3 V-apparaat, hoewel gestabiliseerde voedingen van zowel +3,3 V als +5 V beschikbaar zijn. Dit houdt in dat de logica van de L293D werkt met de +3,3 V-voeding, terwijl de afzonderlijke voedingspin voor de motor is verbonden met de +5 V. Een kleine maar zeer handige eigenschap is de aarde of 0 V-pin die de poolklem van de aansluiting voor de oscilloscoop krijgt. Programmeren in Spin In schema 1 (zie pagina 22) ziet u een mogelijke oplossing voor het programma dat de motor aanstuurt. Het is geen optimale oplossing, maar laat enkele van de belangrijkste eigenschappen van Propeller-programmeren zien. Het doel is twee COG's te gebruiken: één die de PWM-uitvoer aanstuurt met een 'mark/space ratio' die wordt ingesteld met de variabele Ratio, de tweede controleert de invoer van de twee drukknoppen en stelt de waarde van Ratio in. De PWM-frequentie moet 1kHz zijn. De CON-statements stellen twee systeemconstanten in en regelen de kloksnelheid. Wij hebben gekozen voor een 20 MHz-klok zodat de interne PLL-multiplier is ingesteld op 4 op basis van het 5 MHz-kristal dat met het bord wordt meegeleverd. Vervolgens stellen de VAR-statements de algemene variabelen: Ratio zoals hierboven vermeld, Period en Stack die stack-ruimte toewijst voor de tweede COG. De eerste gemeenschappelijke methode, PUB Main, voert de gebruikelijke initialisatietaken uit, inclusief het instellen van de initiële waarde van Ratio gelijk aan 50% PWM. Iedere COG heeft een eenvoudige ‘Count/Capture Unit’ die is gemaakt van enkele registers en wat stukjes logica. Er zijn twee identieke counters, A en B, die beide bestaan uit drie registers, CTR, FRQ en PHS. CTR stelt de operationele modus in, PHS is de accumulator die de huidige waarde bevat en FRQ wordt wanneer nodig toegevoegd aan PHS. Hier wordt counter A gebruikt. Eerst wordt het CTRA-register ingesteld om de PWM-modus en bit 31 van PHSA die is verbonden met uitvoerpoort 0 te selecteren. FRQA wordt ingesteld op 1 zodat PHSA met één wordt verhoogd voor iedere cyclus van de systeemklok. Vervolg op pagina 22 > eTech - NUMMER 3 21 RECENSIE ‘’ ‘’ ‘’ ‘’ RECENSIE ************************************************************** * Simple DC motor speed controller using counters for timing * * PWM mark/space ratio from 0 to 100% * ************************************************************** ‘’Port 0 = PWM output ‘’Port 1 = Speed Up button input ‘’Port 2 = Speed Down button input CON _clkmode = xtal1 + PLL4X _clkfreq = 20_000_000 VAR word Ratio word Period long Stack[9] ‘Ratio = PWM pulse width ‘Period = PWM period ‘Make stack space for COG 1 PUB Main ‘’Initialisation of ports, counters and program start Ratio := 10000 ‘Initial PWM 50% Period := 20000 ‘Set PWM period ctra[30..26] := %00100 ‘Configure Counter A to NCO/PWM mode ctra[5..0] := %00000 ‘Direct Counter APIN to Port 0 frqa := 1 ‘Set counter increment to 1 dira[0..2] := %100 ‘Set Ports 0 = output, 1 & 2 = input cognew(Buttons, @Stack) ‘Start COG 1 running Buttons routine Toggle ‘COG 0 runs PWM generator routine PUB Toggle | Time ‘’COG 0 produces PWM signal with pulse width set by variable Ratio Time := cnt ‘Set base time from System Counter repeat ‘Repeat next 3 lines forever phsa := -Ratio ‘Load negated Pulse width into PHS Time += Period ‘Time = Time + Period waitcnt(Time) ‘Wait for interval set by Time PUB Buttons | Width ‘’COG 1 monitors two pushbuttons to derive value for Ratio repeat ‘Repeat next 8 lines forever Width := Ratio waitpne(%110, %110, 0) ‘Wait for button press if ina[1] == 0 ‘If Speed UP button pressed Width := Width + 1 <# Period ‘then increment Width to max Period else ‘Speed DOWN button pressed Width := Width - 1 #> 0 ‘so decrement Width to min 0 Ratio := Width waitcnt(6000 + cnt) ‘Wait before checking buttons again Schema 1. SPIN-broncode voor het PWM-demonstratieprogramma 22 eTech - NUMMER 3 < Vervolg van pagina 21 Nu komt de eerste interessante instructie: COGNEW. Deze instructie lanceert de tweede COG. Tot dit moment heeft COG 0 alles gedaan, de bootloader geactiveerd en daarna het eerste deel van ons programma. COGNEW vertelt hem de gemeenschappelijke methode-knoppen in de volgende vrije COG te laden, in dit geval COG 1, en activeert hem. Zodra dit is gebeurt activeert het de Toggle-methode en voert deze vanaf dit moment uit. Een eigenschap die bijzonder is voor de Propeller is het delen van de 32 GPIO-poortlijnen door alle processoren. Iedere COG heeft zijn eigen Port Direction-register, waarvan alle uitvoer wordt ge-‘ORed’ met het register van de volgende COG (zie fig.1 op pagina 20). Een COG waarvoor een uitvoerpoort nodig is, moet de juiste bit in zijn Direction-register instellen op een logische 1. Zodra dit is ingestelt zorgt het ervoor dat de bijbehorende uitvoer van het COG I/O-register de I/O-pin aanstuurt. Er moet goed op worden gelet dat de twee COG's niet proberen dezelfde poortlijn te gebruiken voor de uitvoer, omdat het programma dan niet werkt zoals het zou moeten! De poortinvoer is volledig onafhankelijk en iedere COG kan op ieder moment de status van iedere poort lezen. Een COG kan zijn eigen uitvoer controleren en ook zien wat andere COG's doen op poortpinnen die zij hebben ingesteld als uitvoer. De Propeller heeft geen interrupt-systeem, daarom zijn er een aantal Wait-instructies die ervoor zorgen dat de uitvoer van het programma wordt onderbroken tot een bepaalde gebeurtenis plaatsvindt. WAITCNT stelt de uitvoer uit voor een bepaald aantal cycli van de systeemklok door de doelwaarde te vergelijken met de waarde van de systeem-counter CNT. In PUB Toggle wordt PHSA geladen met een negatieve (twee-complement) waarde van Ratio. Dit stelt bit 31 in, of het ‘signaal-bit’ van PHSA naar een logische 1. Als die bit wordt verbonden met poort 0, wordt de PWM-uitvoer ook hoog. PHSA wordt nu automatisch verhoogd met de systeemkloksnelheid door FRQA eraan toe te voegen. Na de Ratio-klokcycli wordt PHSA nul en bit 31 verandert in een logische 0. Dit is het einde van de PWM-puls. Terwijl dit allemaal gebeurt, wordt COG ingesteld in de WAITCNT-statement voor de duur van Period. Natuurlijk blijft PHSA omhoog gaan, maar het einde van de variabele Period wordt bereikt lang voordat PHSA een waarde krijgt die bit 31 weer instelt op hoog. Wanneer WAITCNT afloopt wordt de cyclus herhaald, waarbij PHSA de waarde van –Ratio krijgt. Op deze manier hebben we meer parallelle programmauitvoer toegevoegd, door de counter de pulsduur te laten bepalen, terwijl het COG-programma de periode onafhankelijk instelt. Dit is de manier waarop de PWM-golfvorm op poort 0 wordt gegenereerd door Toggle. De WAITPNE-instructie in de Buttons-methode wacht totdat poort 1 of poort 2 (of beide) een logische 0 worden. Met andere woorden, het wacht totdat er een knop wordt ingedrukt. De charme van de Wait-instructies is dat de COG-uitvoer wordt uitgesteld waardoor het energieverbruik met meer dan 85% wordt verminderd. U kunt zien dat de COG die Buttons uitvoert de meeste tijd ‘slaapt’ en alleen wakker wordt wanneer dat nodig is. De max- (<#) en min- (#>) statements in Buttons leveren de bovenen benedengrenzen van Ratio. Componentenlijst RS stocknummer. 32330 Propeller-starterskit 405-571 L293DNE Quad half-bridge drive 526-868 Tact-drukknopschakelaar 479-1390RE280 DC-motor 238-9709 Versnellen Normaal gesproken zou u verwachten dat programma's die worden uitgevoerd door een on-board interpreter, in dit geval SPIN, langzamer zijn dan die in een interne assembler. De unieke architectuur van de Propeller lost dit snelheidsprobleem tot op zekere hoogte op. De reden hiervoor is dat gebruikers-SPIN-code is opgeslagen in een gedeelde centrale RAM terwijl iedere COG de interpreter uitvoert in zijn eigen lokale geheugen. De hub biedt toegang tot centrale resources in een nauwkeurige tijdsequentie en een bepaalde COG kan worden onderbroken om op zijn beurt te wachten. Machinecode van de assembler wordt opgeslagen en uitgevoerd in het lokale geheugen van de COG wat resulteert in een aanzienlijke verhoging van de bewerkingssnelheid. Om te lezen Programming and Customizing the Multicore Propeller Microcontroller Shane Avery et al ISBN 978-0-07-166450-9 McGraw Hill Meer informatie online... Een volledige versie van deze recensie, samen met SPIN-broncodebestanden, is beschikbaar op www.rsonline.nl/etech of www.rsonline.be/etech eTech - NUMMER 3 23