5)De IPC@CHIP software op het RIOT bord.



Vergelijkbare documenten
4) De hardware.

Settings for the C100BRS4 MAC Address Spoofing with cable Internet.

Handleiding Installatie ADS

Firewall van de Speedtouch 789wl volledig uitschakelen?

EM7680 Firmware Update by Micro SD card

Standard Parts Installatie Solid Edge ST3

RIOT Remote Internet Operated Terminal. Gebruikers handleiding v1.0 7) De I 2 C interface.

RIOT Remote Internet Operated Terminal. Gebruikers handleiding v1.0

MyDHL+ Van Non-Corporate naar Corporate

EM7680 Firmware Update by OTA

FAAC DRIVER. Driver install procedure for FAAC boards. Installatieprocedure voor driver voor FAAC-kaarten.

Opgave Tussentijdse Oefeningen Jaarproject I Reeks 4: Lcd Interface & Files

Hoe te verbinden met NDI Remote Office (NDIRO): Apple OS X How to connect to NDI Remote Office (NDIRO): Apple OS X

Multi user Setup. Firebird database op een windows (server)

Handleiding Zuludesk Parent

L.Net s88sd16-n aansluitingen en programmering.

EM7680 Firmware Update by Micro SD card or USB

Installatie Handleiding AP 1120 op HiPath 3000

Hoe met Windows 8 te verbinden met NDI Remote Office (NDIRO) How to connect With Windows 8 to NDI Remote Office (NDIRO

! GeoNetwork INSPIRE Atom!

EM6250 Firmware update V030507

L.Net s88sd16-n aansluitingen en programmering.

EM7680 Firmware Auto-Update for Kodi 17.2

Getting Started. AOX-319 PBX Versie 2.0

LDAP Server on Yeastar MyPBX & tiptel 31xx/32xx series


EM7580 Firmware Update by Micro SD card

DALISOFT. 33. Configuring DALI ballasts with the TDS20620V2 DALI Tool. Connect the TDS20620V2. Start DALISOFT

EM7680 Firmware Update by Micro SD card or USB stick

Hoofdstuk 7. Computerarchitectuur

Installatie instructies

Configureren van een VPN L2TP/IPSEC verbinding. In combinatie met:

General info on using shopping carts with Ingenico epayments

Configureren van een VPN L2TP/IPSEC verbinding

Handleiding NodeMCU. Handleiding NodeMCU l Pagina 1

Intermax backup exclusion files

CTI SUITE TSP DETAILS

Remote Powercontrol for TCP/IP networks

Activant Prophet 21. Prophet 21 Version 12.0 Upgrade Information

open standaard hypertext markup language internetprotocol transmission control protocol internet relay chat office open xml

Met 4 temperatuur meetingangen voor sensor DS18x20

Technote. EnGenius Senao EOM Mesh Layer 2 configuratie Transparant netwerk

TC_DCM Inleiding Input

Classification of triangles

Chapter 4. eenvoudige webserver opzetten

Handleiding integratie CF iviewer CT-iViewer

Deel 8: stappenmotoren en interrupts

Handleiding NL pagina 2. Manual UK page 6. Network Settings

MyDHL+ ProView activeren in MyDHL+

7 aug Snelstart document Thecus N2100 Y.E.S.box BlackIP Versie 1.0

256 kb Memory in NMS 8250, 8255 and 8280

Inhoud vandaag. Interrupts. Algemeen ARM7 AIC

2019 SUNEXCHANGE USER GUIDE LAST UPDATED

De MySQL C API. Variabelen in C Functies in C Pointers in C

Installeer Apache2: Landstede februari 2009 versie 3 1 Bertil Hoentjen

Procedure Reset tv-toestellen:

Today s class. Digital Logic. Informationsteknologi. Friday, October 19, 2007 Computer Architecture I - Class 8 1

RIOT Remote Internet Operated Terminal. Gebruikers handleiding v1.0 6) De intelligente I/O-controller IOsys.

SI-Profinet. Unidrive M200-M400 en Siemens S PLC (TIA portal)

TaskCentre Web Service Connector: Creëren van requests in Synergy Enterprise

Bescherming van (software) IP bij uitbesteding van productie

Stap 1: Registreer via de link op de G-schijf beschikbaar na inloggen met de teken-account, verzend via Submit. Nadien krijg je een bevestiging op

Het beheren van mijn Tungsten Network Portal account NL 1 Manage my Tungsten Network Portal account EN 14

EM4594 Firmware update

Introductie in flowcharts

1 Installatie van de server... 2

Handleiding Digipass DP310

Toets In2305-ii Embedded Programming Dinsdag 28 November 2006, 15:45-16:30

API...1 Identificatie...1 Opties...2 Acties...3 Webserver...6 Heartbeat...6 Buffer groottes...8

ES1 Project 1: Microcontrollers

Aandachtspunten voor installatie suse in vmware server

Webrelais IPIO-32R-M-v8.0 Compacte modul met 32 Relais Outputs.

Webrelais IPIO-4A8I-M

How to install and use dictionaries on the ICARUS Illumina HD (E652BK)

[BP-ebMS-H-000] Welke versie van Hermes moet er gebruikt worden?

Daylight saving time. Assignment

Versie: A Datum: Pag: 1 van 5

Netwerkprinter Dell 1320C installeren op Ubuntu LTS - Lucid Lynx

SI-Profinet. Unidrive M700 en Siemens S7-300 PLC (Step 7)

MULTIFUNCTIONELE DIGITALE SYSTEMEN. Windows Server 2003, Server 2008 & Scan-to-file

Leeftijdcheck (NL) Age Check (EN)

Mymesh Ethernet Gateway

Deel 1: schriftelijk deel

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE

Debugging in embedded en native systemen met GDB

Arduino CURSUS. door Willy - 09-juni-2017

Denit Backup instellen op een Linux server

HANDLEIDING. Dit document beschrijft de installatie, configuratie en gebruik van de Netduino Plus 2 monitoring oplossing


Datum 15 juni 2006 Versie Exchange Online. Handleiding voor gebruiker Release 1.0

Memory Management. Virtual Memory. Eisen Memory Management. Verdelen geheugen over meerdere processen

Solcon Online Backup. Aan de slag handleiding voor Linux

1. Voor het installeren wordt geadviseerd een backup te maken van uw database en bestanden.

HANDLEIDING - ACTIEVE MOTORKRAAN

De Arduino-microcontroller in de motorvoertuigentechniek (4)

Flexibele oplossing om de eid kaart aan te spreken vanuit.net (en Delphi, Visual Basic, C++ etc)

After that, the digits are written after each other: first the row numbers, followed by the column numbers.

Met 32 ingangen potentiaal vrij Input 1 t/m Input 32

Transcriptie:

5)De IPC@CHIP software op het RIOT bord. Het Operating system in een notedop. Zoals op elk computersysteem moet ook op een IPC@CHIP een operating system (OS) voorhanden zijn, voor het besturen van de verschillende hardwarecomponenten. Wanneer een computer wordt aangeschakeld begint het OS de hardwarecomponenten te initialiseren of in te stellen voor een correcte (samen)werking in het systeem. Om de gebruiker toe te laten dingen te wijzigen in de normale instellingen van het systeem zal het OS hiervoor informatie lezen uit verschillende files, waar de gebruiker dan zijn specifieke instellingen kan aangeven. Bij de IPC@CHIP zijn dit de chip.ini en de autoexec.bat files. In deze laatste file kan de gebruiker bijvoorbeeld aangeven welk user-programma moet opgestart worden nadat de systeem-initialisering afgelopen is. De autoexec.bat en chip.ini files. Deze autoexec.bat en chip.ini files zijn ascii files, en kunnen met een eenvoudige texteditor zoals Windows-Notepad aangemaakt worden. De autoexec.bat file, moet zich net als de chip.ini file in de rootdirectory van het virtuele diskettestation a:\ bevinden, en wordt gelezen na de chip.ini file. Het doel van de chip.ini file is het vrijgeven en de instelling van de verschillende componenten van het OS, zoals vb. de FTP-, HTTP-, Telnet-, en PPP-server. Het belangrijkste doel van de autoexec.bat file is het automatisch opstarten van programma s. De commando s die in deze file worden opgenomen zijn identiek aan diegene die met de hand op de console ingegeven kunnen worden. Wanneer men een programma, na het booten van de IPC@CHIP, automatisch wil laten opstarten, schrijft men met een texteditor de naam van het uit te voeren programma s (vb. test.exe) naar een file autoexec.bat, dit wordt aangegeven in figuur 5.1. Daarna moet deze file op de IPC@CHIP geladen worden, langs de seriële poort of via FTP. Bij het opstarten zal dan de volgende keer het programma test.exe automatisch worden uitgevoerd. Figuur 5.1:De autoexec.bat file. De autoexec.bat file is een batch file, wat door de extentie.bat aangegeven wordt. De naam duidt erop dat in de file de commando s sequentieel achter elkaar worden geschreven om dan door het OS in die volgorde te worden uitgevoerd. Om te testen of alles werkt kunnen deze commando s met de hand in de command interpreter worden ingegeven. Daarna kunnen ze in dezelfde volgorde in de batch-file worden geschreven, en worden opgeladen. Men moet er dan wel rekening mee houden het systeem eerst terug op te starten vooraleer deze door de command interpreter worden uitgevoerd. Versie 1.0 55 [dp] D. Pauwels

De command interpreter COMMAND. Dit is de interface van de IPC@CHIP naar de gebruiker toe om vb. een programma op te starten. De commando interpreter kan bevelen die van de terminal of de autoexec.bat-file komen interpreteren en deze omzetten in een aantal OS-routine oproepen. De beschikbare commando s worden beschreven in een doc-file die hoort bij elke beschikbare versie van het OS. Deze doc-file is na het un-zippen van deze BIOSversie (OS)-ZIP file beschikbaar, en kan met een Webbrowser doorlopen worden. De BIOS versie die actueel in de RIOT systemen wordt gebruikt is SC12V0101, die samen met de documentatie in de bijhorende.zip file is gecomprimeerd. Volgende commando s (Tabel 5.1) staan ter beschikking: Tabel 5.1: Commando's van de command-interpreter Commando Beschrijving Voorbeeld help Commando s aangeven help del Wissen van file s del *.jpg dir Directory opvragen dir *.exe type Uitschrijven van tekstfile type autoexec.bat copy File s copiëren copy chip.ini chip.tst ren Rename file s ren chip.new chip.ini md Make directory md temp cd Change directory cd temp con Console definition con com con ext con com telnet ale Enable/disable ALE pin ale 0 pcs Enable chip select pcs 5 iw Input word iw 500 ow Output word ow 500 1f4e ib Input byte ib 500 ob Output byte ob 500 fa ip IP address define ip 192.168.0.1 ipeth Restart ethernet ipeth ping Ping to address ping 192.168.0.45 netmask Set netmask netmask 255.255.255.0 gateway Set gateway address gateway 192.168.0.0 dhcp Enable/disable dhcp dhcp 0 ftp Enable/disable ftp server ftp 1 tftp Enable/disable tftp server tftp 0 tcpipmem Show reserved TCP/IP stack tcpipmem ipcfg Show IP configuration ipcfg reboot Restart system reboot memopt Enable/disable memory memopt 1 optimalisation batchmode Setup batchmode batchmode 1 Versie 1.0 56 [dp] D. Pauwels

Tabel 5.1: Commando's van de command-interpreter (vervolg). wait Command interpreter sleep wait 1 format a: Format flashdisk A: format a: ver Show bios version ver xtrans File transfer with XMODEM protocol mem Show memorymap mem cgistat Show installed CGI handlers cgistat webstat Show startpage of webserver webstat closetelnet Close telnet session closetelnet xtrans ext s test.exe xtrans com r main.htm Versie 1.0 57 [dp] D. Pauwels

De API s van het OS. De software-ontwerpers van het OS en de BIOS software moeten een grondige kennis bezitten van de werking van de hardware van de computer om deze te kunnen instellen. Wanneer dit niet het het geval zou zijn functioneert een deel van de hardware niet of toch niet naar behoren. Zo moeten ze bijvoorbeeld weten welke locatie van de seriële poort ( UART) moet gelezen worden om na te gaan of een toets is ingedrukt op het keyboard van de aangesloten terminal, of naar welke locatie ze moeten schrijven om op het scherm iets weer te geven. Men wil voorkomen dat elke programmeur al deze systeemkennis nodig heeft om een userprogramma te kunnen schrijven. Daarom stelt het OS en de BIOS een aantal softwareroutines ter beschikking, die door de ontwerpers met verstand van zaken zijn geschreven, om deze specifieke hardware gebonden taken van de programmeur van user-programma s over te nemen. De programmeur van user-software moet nu alleen de documentatie van deze OS of BIOS-routines doornemen om deze te kunnen hergebruiken in zijn software. Hij weet hiermee wat er gebeurt als hij een bepaalde OS of BIOS-routine oproept, hoe en waarom dit gebeurt is voor hem dan van ondergeschikt belang. Deze OS-routines die als software interface het leven van de ontwerper van user-software vergemakkelijken noemt men API s (Application Programmers Interfaces). Zo zijn er op de IPC@CHIP verschillende categoriën te onderscheiden: HARDWARE API Langs de routines van deze interface worden de hardware-pinnen van de IPC@CHIP bestuurd. Zo kunnen er langs deze API de bus-mode en de chipselects worden ingesteld, timers worden gestart, gestopt en gelezen, I/O pinnen worden gelezen en aangestuurd. BIOS API BIOS staat voor Basic Input Output Systemprogram. Hier bevinden zich de routines die zorgen voor standaard input en output. Zoals : Get a character from std in, wait if none available, Check if a character is available from standard input, Get the IP address as a string., enz FOSSIL API De routines van deze API houden zich alleen bezig met het besturen van de beide seriële poorten van de IPC@CHIP. Deze kunnen hier worden aan of uitgeschakeld, wat hun pinnen vrijgeeft voor andere toepassingen, de BAUD-rate en buffer instellingen kunnen hiermee gebeuren. Voorbeelden zijn: Read a byte from the receiver buffer. Wait for a byte to arrive if none is available., Configure the flow control for a port, Enable the RS485 mode, IIC API De besturing voor deze tweedraads bus gebeurt met routines uit deze API. Zo zijn er oa. volgende routines: Initialize the I2C Bus, Send or receive a single character, Report addresses of slave devices, one at a time, EXTERNE DISK API Deze API is enkel van nut indien op de IPC@CHIP een externe harddisk is aangesloten. De benodigde interface-hardware moet echter eerst geïmplementeerd worden, daar de chip hiervoor zelf geen voorzieningen heeft. Dit is echter onmogelijk op het RIOT bord, zodat deze API voor ons van geen belang is. Versie 1.0 58 [dp] D. Pauwels

DOS-API Deze Disk Organisation System-routines zijn de op de BIOS volgende software-layer. De disk wordt op een IPC@CHIP computer in een Flash-ROM als een virtueel diskettestation A:\ geëmuleerd. Hierbij stelt DOS dezelfde functionaliteit ter beschikking als bij een echte disk, maar dan in Flash- ROM. Mogelijke services zijn: Create a new subdirectory, Open an existing file, Create New File Handle, Allocate memory for the process, RTOS API RTOS staat voor Real Time OS, en geeft de mogelijkheid meerdere systeem- en user-programma s gelijktijdig te laten lopen. In deze API vinden we routines die dienen voor de sheduling van de lopende programma s (Tasks). Hierin vinden we oa. volgende services: Create and start a task, Stop and kill specified task, Suspend a task, Create a semaphore, Get tick count of system clock, TCP/IP API De netwerkmogelijkheden van een IPC@CHIP computer zijn gebaseerd op de geïmplementeerde TCP/IP stack. Services die in deze API ter beschikking staan van de gebruiker zijn oa.: open a socket, close a socket, Bind a unnamed socket with an address and port number, get options on socket, ETHERNET API Met deze API komen routines ter beschikking die het transport van data pakketjes over het ethernet controleren. Zoals: Send bytes in provided packet buffer over Ethernet, Install Access Handler, Get the SC12 Ethernet Address, WEB SERVER CGI API Met de routines van deze API kunnen drivers geïnstalleerd worden voor het dynamisch aanmaken van Hypertextpagina s, en kan de rootdirectory en de startpagina van de http:// en ftp:// netwerkservers ingesteld worden. Te gebruiken routines zijn o.a. : Install a CGI function, Remove a CGI function, Set a new main page, Install a Turbo Pascal CGI procedure, Get Web server's root directory, Voor de beschrijving van de werking en het gebruik van de beschikbare API s verwijzen we naar de SC12V010x.ZIP bestanden die ter beschikking staan op de website van BECK. De x staat hier voor het versienummer van de firmware. Hierin zit een.doc file verpakt die de beschrijving bevat van de verschillende API s. Versie 1.0 59 [dp] D. Pauwels

Het toepassen van deze systeem API's vanuit 'C'. Het toepassen van deze API's is gebaseerd op het gebruik van software-interrupts (of ook wel eens system calls genoemd) op het IPC@CHIP systeem. Wat is een software interrupt? Een software interrupt is een mechanisme waarmee men een routine (functie) van het OS of de BIOS software kan uitvoeren zonder dat men moet weten waar deze routines zich bevinden in het geheugen. Men roept deze OS routines immers op via een tussenstap. Namelijk a.d.h.v. een Interrupt Service Routine (ISR) geïnitieerd door een INT instructie op de 80186 processor ( zie instructieset van de 80186 microprocessor) van de IPC@CHIP. Afhankelijk van de meegegeven parameter (getal tussen 0 en 255) bij de INT instructie zal de processor het adres berekenen van de bijhorende vector in een (door het OS ingevulde) vectortabel. Deze vector is niets anders dan het startadres van de ISR routine die men wil uitvoeren. Op deze manier kan de processor uiteindelijk de ISR routine terugvinden die de gebruiker wil uitvoeren. De opgestarte ISR zal dan afhankelijk van de inhoud van de processorregisters een bepaalde taak uitvoeren voor de gebruiker. De gebruiker kan deze taak selecteren door de nodige parameters te schrijven in de registers van de processor voordat de INT instructie wordt uitgevoerd. Samengevat komt het op het volgende neer: de taak die wordt uitgevoerd voor de gebruiker wordt bepaald door het nummer dat meegegeven wordt met de INT instructie én door de waarde van de processorregisters op dat ogenblik. Het voordeel van deze omslachtige manier van werken is, dat de gebruiker om een bepaalde routine uit te voeren, steeds dezelfde sequentie van instructies kan gebruiken in zijn toepassingsprogramma. De ontwerper van het OS of de BIOS software moet er alleen maar voor zorgen dat de vectortabel met de adressen van de ISR's bij elke nieuwe release van het OS of de BIOS software wordt aangepast aan de nieuwe situatie. De toepassingssoftware kan zo telkens de gewenste OS routines blijven aanspreken zonder de nieuwe adressen van de OS routines te moeten kennen. Op deze manier kan toepassingssoftware toch blijven werken met nieuwe releases van het OS dat zo onafhankelijk kan worden aangepast aan nieuwe noden en nieuwe hardware. Versie 1.0 60 [dp] D. Pauwels

Hoe voeren we een software interrupt uit vanuit 'C'? Syntaxmatig kunnen we dit in onze programma's noteren zoals in het volgende code fragment. #include <dos.h> #define PFE_INT 0xa2 // Pin Function Enabler union REGS inregs; union REGS outregs; struct SREGS segregs; /******************************************************************************/ // enable the databus on the IPC@CHIP (ALE signal, PCS1 activates 100H-1FFH addresses) /******************************************************************************/ void enable_databus (void) // enable 8 bit databus inregs.x.ax = 0x8001; //enable ALE, databus inregs.x.dx = 0x00ff; //all 8 bits are enabled int86x (PFE_INT,&inregs,&outregs,&segregs); //enable chip select 1 (PIO4) inregs.h.ah = 0x83; inregs.x.dx = 0x02; //PCS1# (100h-1ffh) int86x (PFE_INT,&inregs,&outregs,&segregs); //software interrupt (OS call) In de dos.h file worden structs,unions macro's en functies gedefiniëerd voor het gebruik met MSDOS. In deze file worden oa. de union REGS en de struct SREGS gedefiniëerd. De union REGS en struct SREGS worden gebruikt om info door te geven naar en van de int86x functie. Ook worden in dos.h de structs BYTEREGS en WORDREGS gedefiniëerd voor het opslaan van byte en woord registers. Om dit beter te begrijpen geven we in figuur 5.1 de registerstructuur weer van de 80186 processor. Figuur 5.2: Register structuur van de 80186 processor. Versie 1.0 61 [dp] D. Pauwels

Zoals uit figuur 5.2 duidelijk wordt heeft de 80186 een aantal registers die op woordbasis en bytebasis kunnen aangesproken worden, nl: AX (AH,AL), DX (DH,DL), CX (CH,CL) en BX (BH,BL). Om deze op een eenvoudige manier vanuit C te kunnen aanspreken worden zoals eerder gezegd in dos.h een aantal decaraties gedaan, nl: struct BYTEREGS unsigned char al; unsigned char ah; unsigned char bl; unsigned char bh; unsigned char cl; unsigned char ch; unsigned char dl; unsigned char dh; ; struct WORDREGS unsigned short ax; unsigned short bx; unsigned short cx; unsigned short dx; unsigned short si; unsigned short di; unsigned short cflag; unsigned short flags; //unsigned char heeft lengte 8 bits //unsigned short heeft lengte 16 bits ; struct SREGS unsigned short es; unsigned short cs; unsigned short ss; unsigned short ds; ; union REGS //overlay van de byte (var. h) en word (var. x) registerstructs ; struct WORDREGS x; struct BYTEREGS h; //hierdoor kan éénzelfde register variabele aangesproken //worden als twee indviduele bytes of als een word Met de declaratie van union REGS inregs in ons programma wordt een variabele inregs gecreëerd die bestaat uit een overlay van een variabele x van het type WORDREGS (met daarin de members ax tot flags) en een variabele h van het type BYTEREGS (met daarin de velden al tot dh). Een member van deze variabele inregs kan daarna op woord of bytebasis worden aangesproken. inregs.h.ah inregs.x.dx =0x83; // hier spreken we de variabele inregs aan op bytebasis (type BYTEREGS). =0x02; // hier spreken we de variabele inregs aan op wordbasis (typewordregs). Hiermee bepalen we welke functie we willen uitgevoerd zien door het OS. Het is juist deze informatie die is beschreven in de documentatie die hoort bij de API's. Versie 1.0 62 [dp] D. Pauwels

Aan de functie int86x worden de adressen doorgegeven van de inregs, outregs en segregs variabelen. int86x (PFE_INT,&inregs,&outregs,&segregs); Met int86x wordt een software interrupt uitgevoerd gespecifiëerd door het argument PFE_INT (in dit geval de waarde A2h zoals aangegeven in de define). Vóór het opstarten van de software interrupt worden de processorregisters door de functie int86x geladen met de waarden uit inregs. De waardes segregs->ds en segregs->es worden ook in de overeenkomstige processorregisters geladen. Ná het beëindigen van de software interrupt wordt door de functie int86x ook de inhoud van processorregisters geladen in outregs. Op de volgende manier worden de verschillende functies uit de API's beschreven in de betreffende documentatie, hier werd als voorbeeld de functie Initialize the I2C Bus genomen uit de IIC API. Interrupt 0xAA service 0x80: Initialize the I2C Bus This function sets the I2C bus clock speed to that specified by the caller. It also configures two of the programmable I/O (PIO) pins for usage as I2C bus data and clock signals. Parameters AH 0x80 AL no longer used CX 0 Comments The user can specify which two PIO are used for I2C clock and data. After calling this initialization function, these two pins will no longer be available as PIO pins unless the PFE Enable function is called for these pins following this function call. Related Topics Select I2C Clock Pin Select I2C Data Pin PFE: Enable Programmable I/O Pins #include <dos.h> #define IIC_INT 0xaa // IIC bus functions union REGS inregs; union REGS outregs; struct SREGS segregs; inregs.h.ah = 0x80; inregs.x.cx = 0x00; int86x (IIC_INT,&inregs,&outregs,&segregs); Op deze manier kunnen we de functie Initialize the I2C Bus uitvoeren, zonder voorkennis over de hiervoor gebruikte hardware, dit is de bedoeling van de API's. Versie 1.0 63 [dp] D. Pauwels

Verwerken van hardware interrupts vanuit 'C'. Bij een software interrupt is het de bedoeling een routine uit het OS uit te voeren die een bepaalde service verleent aan de gebruiker. Bij een hardware interrupt is het meestal de bedoeling een zelf geschreven functie (ISR) uit te voeren wanneer een hardware-onderdeel er aan de hand van een interruptsignaal om vraagt. De ISR wordt dus opgeroepen door een signaal dat asynchroon binnenkomt ten opzichte van de normale programma-uitvoering. De ISR wordt verder opgestart aan de hand van hetzelfde mechanisme als bij een software interrupt. Afhankelijk van het type interrupt zal een vector uit de vectortabel worden opgehaald die aangeeft waar de ISR zich ergens bevindt in het geheugen, en de processor zal deze ISR dan uitvoeren. De programmeur moet er echter op letten dat hij zelf via software deze vector in de vectortabel invult. Dit in tegenstelling met een software interrupt waar het OS er voor zorgt dat de betreffende vector correct in de vectortabel wordt ingevuld. Zoals we uit het schema van de interface van de DPRAM met de IPC@CHIP kunnen afleiden is het mogelijk dat de IPC@CHIP processor vanuit de DPRAM een interruptsignaal binnenkrijgt (/INT0). Dit kan als gevolg van: Het indrukken van een toets op de keyboardinterface van IOsys. Na het verstrijken van de cyclustijd van de IOsys. Na het verwerken van een opdracht van de IPC@CHIP door IOsys. Voor bijkomende informatie verwijzen we naar Hfdstk. 6 en meerbepaald naar het deel 'cyclustijd en interrupt controleregisters van IOsys' van de intelligente I/O controller IOsys. Een voorbeeld voor het verwerken van interrupts op de IPC@CHIP wordt in het volgende C programma gegeven. // Example of using interrupts on the RIOT board v1.0 // // Created by [dp] 23.04.2002 // This program reads the contents of memory bank 0,1,2,3 of the // dual port ram on the RIOT board, and writes it to stdio // every time an external interrupt0 occurs. // Interrupt0 is activated by the dual port ram as a result // of a write access to location 83ffh from the IOsys side. // // Includes #pragma option -1 // create 80186 code #include <stdio.h> #include <dos.h> Versie 1.0 64 [dp] D. Pauwels

***************************************************************************/ // Defines #define PFE_INT 0xA2 #define HAL_INT 0xA1 #define TCP_INT 0xAC #define INTR0 0x0C // External interrupt0 vector number // Variables union REGS inregs; union REGS outregs; struct SREGS segregs; int ok_flag=1; unsigned char getal0,getal1,getal2,getal3; unsigned int address=0x1fe; // Init RIOT v1.0. void enable_databus (void) // Enable 8 bits databus inregs.x.ax = 0x8001; // enable ALE, databus inregs.x.dx = 0x00FF; // all 8 bits are enabled int86(pfe_int, &inregs, &outregs); // Enable programmable chip select1 (poi4) inregs.h.ah = 0x83; inregs.x.dx = 0x02; // PCS1# (100h-1FFh) int86(pfe_int, &inregs, &outregs); void select_bank0 (void) // Reset pio2, pio3 lines inregs.h.ah = 0x82; inregs.h.al = 0x05; // pio2,pio3 both 0 inregs.x.dx = 0x000B; // enable pio2,pio3 int86(pfe_int, &inregs, &outregs); void select_bank1 (void) Versie 1.0 65 [dp] D. Pauwels

// Reset pio3 line inregs.h.ah = 0x82; inregs.h.al = 0x05; // pio3 state 0 inregs.x.dx = 0x0008; // enable pio3 int86(pfe_int, &inregs, &outregs); // Set pio2 line inregs.h.ah = 0x82; inregs.h.al = 0x04; // pio2 state 1 inregs.x.dx = 0x0004; // enable pio2 int86(pfe_int, &inregs, &outregs); void select_bank2 (void) // Set pio3 line inregs.h.ah = 0x82; inregs.h.al = 0x04; // pio3 state 1 inregs.x.dx = 0x0008; // enable pio3 int86(pfe_int, &inregs, &outregs); // Reet pio2 line inregs.h.ah = 0x82; inregs.h.al = 0x05; // pio2 state 0 inregs.x.dx = 0x0004; // enable pio2 int86(pfe_int, &inregs, &outregs); void select_bank3 (void) // Set pio2, pio3 lines inregs.h.ah = 0x82; inregs.h.al = 0x04; // pio2,pio3 both 1 inregs.x.dx = 0x000B; int86(pfe_int, &inregs, &outregs); // enable pio2,pio3 // Read databus on specified address unsigned char read_databus (unsigned int ram_address) unsigned char value; // read data bus inregs.h.ah = 0x80; inregs.x.di = ram_address; // address = user parameter inregs.x.bx = 0xFFFF; // wand=0xffff inregs.x.cx = 0x0000; // wxor=0x0000 int86x(hal_int, &inregs, &outregs, &segregs); value = outregs.h.al; return value; Versie 1.0 66 [dp] D. Pauwels

// Write databus to specified address void write_databus (unsigned char value,unsigned int ram_address) // write data bus inregs.h.ah = 0x81; inregs.x.di = ram_address; // address = user parameter inregs.h.dh = 0; inregs.h.dl = value; inregs.x.bx = 0xFF; // wand=8 bits databus inregs.x.cx = 0x0000; // wxor=0x0000 int86x(hal_int, &inregs, &outregs, &segregs); //************************************************************************** // Following routines are the interrupt enable and mode setting routines //************************************************************************** void enable_int0 (void) inregs.h.ah = 0x84; inregs.x.dx = 0x0001; int86 (PFE_INT,&inregs,&outregs); void pos_edgeint0 (void) inregs.h.ah = 0x86; inregs.x.dx = 0x0001; int86 (PFE_INT,&inregs,&outregs); // Enable interrupt0 // Rising edge sensitive interrupt0 //************************************************************************** // This is the interrupt service routine (ISR), it sets the ok_flag for the main function. //************************************************************************** void interrupt int0handler () // Declare this function as an ISR! ok_flag=1; select_bank3(); getal3=read_databus (0x1fe); // read location 1fe and reset int condition // Give specific int0 EOI to the PIC (SC12 i/o base address ff00h) see 80186 USERS MAN. outport (0xff22,INTR0); Versie 1.0 67 [dp] D. Pauwels

//************************************************************************** // Main loop /*************************************************************************** void main (void) enable_databus (); ok_flag=1; setvect (INTR0,int0handler); enable_int0 (); pos_edgeint0 (); // Put INT0 interrupt entry (address of int0handler) // in the vector table. // enable this type of interrupt // set the sensivity to rising edge while(1) while (ok_flag==1) // This flag gets set only when INT0 is encountered ok_flag=0; printf("\r\n BANK0 BANK1 BANK2 BANK3"); for (address=0x1fe; address<=0x1ff; address++) // Read RIOT dual port ram on address 100h-1ffh at different banks select_bank0(); getal0=read_databus (address); select_bank1(); getal1=read_databus (address); select_bank2(); getal2=read_databus (address); select_bank3(); getal3=read_databus (address); // By reading this bank on location // 1feh, the interrupt condition is // removed in the dp ram printf("\r\naddress:%02xh %02Xh %02Xh %02Xh %02Xh", address,getal0,getal1,getal2,getal3); In de hardware API vinden we functies terug om welbepaalde interrupts aan te schakelen, en hun mode in te stellen (niveau- of flankgevoelig). De functie enable_int0 () zal hier de INT0 pin activeren, en de functie pos_edgeint0 () zal een stijgende flank gevoeligheid instellen. Deze functies worden uitgevoerd in het initialisatiedeel van de main() functie. Versie 1.0 68 [dp] D. Pauwels

Vooraleer we ook interrupts daadwerkelijk kunnen verwerken moeten we in de vectortabel van de processor op de plaats die hoort bij de INT0 interrupt ook het adres plaatsen van de interruptserviceroutine (ISR) die hierbij hoort. Dit wordt gedaan met de setvect (INTR0,int0handler) functie in de main () functie. Met #define INTR0 0x0C // External interrupt0 vector number definiëren we het interrupttype aan dat we willen gebruiken. Zie tabel 5.2 voor de verschillende types. De functie int0handler () wordt dan als interruptserviceroutine (ISR) aangegeven door void interrupt int0handler (). In deze interrupthandler moet men er dan voor zorgen dat het End Of Interrupt (EOI) register van de interruptcontroller die in de 80186 CPU van de IPC@CHIP aanwezig is wordt geschreven met een code die aangeeft dat de interrupthandler is beëindigd. Dit kan door de functie outport (0xff22,INTR0). Hierdoor wordt de betreffende bit in het In Service (IS) register voor deze interruptbron uitgeschakeld, waardoor er een volgende interrupt van dit type kan worden gedetecteerd. Doet men dit niet dan zal alleen de eerste interrupt van dit type worden afgehandeld, en wordt daarna dit interrupttype geblokeerd omdat de CPU denkt dat de vorige ISR van dit type nog niet is afgewerkt. Het adres 0xff22 dat gebruikt wordt is dit van het EOI register. Zoals uit de 'Memory en I/O map' van de IPC@CHIP blijkt zitten de interne CPU registers gemapt vanaf het adres 0xff00. De users manual van de 80186 CPU geeft aan dat het EOI register met een offset van 0x22 bytes t.o.v. dit adres is verschoven, zodoende komt men aan 0xff22. De nodige informatie hierrond kan men terugvinden in de 80186 users manual bij de Interrupt Control Unit. Tabel 5.2: 80186 CPU interrupt types. Versie 1.0 69 [dp] D. Pauwels

CGI verwerking op de IPC@CHIP. De HTTP netwerkserver van de SC12 IPC@CHIP heeft de mogelijkheid om Common Gateway Interface (CGI) programma's te verwerken. Het gaat hier om een interface tussen een Webserver en een programma dat wordt gestart. Dit programma noemt men een CGI proramma of CGI script. Figuur 5.3 geeft een situering van deze CGI. CGI programma's kunnen interactieve, dynamische websites genereren, en kunnen ook als verbinding (Gateway) tussen de Webserver en een extern toepassingsprogramma fungeren. De CGI functies bij de IPC@CHIP verschillen een weinig met de normale CGI functies op een PC of andere computer. De CGI functies zijn normaal uitvoerbare programma's die worden opgestart. Bij de IPC@CHIP zijn het CGI functies in een EXE-programma. Meestal verzendt een HTTP server statische (vaste onveranderlijke) HTML pagina's. Deze zijn bij de server normaal geordend volgens een WEB-ROOT-hierarchie. De HTML pagina's kunnen zo van buitenaf door een tweede computer, de client, waarop een browser draait, opgevraagd worden. Vraagt de client van de server een HTML pagina op zonder daarbij te vermelden welke pagina, dan zal de server zijn START pagina versturen. De naam van deze startpagina in de WEB-ROOThierarchie is typisch INDEX.HTM of MAIN.HTM. Van hieruit kunnen via LINKS dan andere pagina's ( met eigen naam.htm ) opgevraagd worden. Wanneer de server een CGI interface bezit dan kan hij dynamisch, zelf samengestelde, HTML pagina's verzenden. Dit opent interessante perspectieven wanneer de server over actuele gegevens kan beschikken die bij het normale opvragen van een HTML pagina nog niet voorhanden zijn. Een eenvoudig voorbeeld hiervan is de bezoekerteller (Counter) die vele Homepages verzenden. Bij een CGI interface wordt deze pagina door een programma aangemaakt wanneer de client erom vraagt, en dit programma voegt de actuele waarde van de teller ( of vb. actuele meetgegevens) in, in de HTML pagina. Ook in de omgekeerde richting functioneert CGI. Het is mogelijk dat de Web-server met CGI programma's een toepassing bestuurt aan de hand van parameters (datastrings) die van een browser afkomstig zijn. CLIENT (PC) IPC@CHIP RTOS CGI-API Webbrowser Intranet Internet Webserver + CGI handling CGI function Application program I/0 Application Figuur 5.3: Situering van CGI. Versie 1.0 70 [dp] D. Pauwels

Vanuit de fabrikant Beck wordt voor de programmering van CGI functies een CGI-API ter beschikking gesteld. Aan de hand van deze CGI-API kunnen CGI functies in DOS toepassingsprogramma's aangegeven worden, die uitgevoerd worden wanneer de Webserver een aanvraag voor een HTML pagina met de geldige parameters binnenkrijgt. Om een CGI-API functie uit te voeren moet bij de software interrupt de waarde 0xAB meegegeven worden. De waarde in AH geeft aan welke functie de software interrupt moet uitvoeren. De beschikbare API functie worden aangegeven in tabel 5.3. Tabel 5.3: Beschikbare CGI-API functies (@CHIP-RTOS V1.04). Interrupt number/ Function (AH value) CGI-API function 0xAB Function 0x01 CGI INSTALL, install a cgi function. 0xAB Function 0x02 CGI REMOVE, remove a cgi function. 0xAB Function 0x03 CGI SETMAIN, set a new mainpage. 0xAB Function 0x04 CGI SETROOTDIR, set Webserver's root directory. 0xAB Function 0x05 CGI GETROOTDIR, get Webserver's root directory. 0xAB Function 0x06 CGI GETMAIN, get mainpage name. 0xAB Function 0x07 CGI GETFORMITEM, split a formular into name and value. 0xAB Function 0x08 CGI FINDNEXTITEM, return the address off the next formular tag. 0xAB Function 0x09 CGI INSTALL PAS, install Turbo Pascal CGI procedure. Als voorbeeld gebruiken we de CGI INSTALL functie. De op de IPC@CHIP geïmplementeerde Webserver heeft toegang tot een interne CGI tabel. Elke tabelentry omvat de URL van de dynamisch aan te maken HTML pagina, de verwachtte HTTP methode ( GET, HEAD of POST ) en een pointer naar de uit te voeren cgi functie van het usersprogramma. De volgende structuur CGI_Entry uit de Beck headerfile cgi.h geeft de betreffende datatypes aan: Typedef struct tag_cgi_table char * PathPtr; CGI_Entry; int method; void *CgiFuncPtr; // naam van de pagina, URL // HTTP methode: get,head of post // pointer naar de CGI functie die de dynamische pagina // aanmaakt in het toepassingsprogramma Versie 1.0 71 [dp] D. Pauwels

De volgende stappen moeten in een programma worden ondernomen om CGI verwerking op te starten (zie Figuur 5.4): Declaratie van een variabele van het type CGI_entry. Een variabele vb. 'example' met deze structuur kunnen we op volgende manier in een programma declareren. #include "cgi.h" CGI_Entry example; Installatie van de CGI functie. De members van deze variabele kunnen dan als volgt worden gedefinieerd. example.pathptr = HtmlPageName; // HtmlPageName bevat hier vb. "riot" example.method = 1; // CGI Http GET (zie cgi.h) example.cgifuncptr = CGI_example_func; // uit te voeren functie bij browserrequest met //"riot" als paginanaam Een CGI INSTALL functie oproepen kan op volgende manier. inregs.h.ah =0x01; inregs.x.dx =FP_SEG(&example); inregs.x.si =FP_OFF(&example); int86 (0xAB,&inregs,&outregs); Het systeem krijgt zo een copie van de variabele example in zijn CGI tabel. Hierin zit de HtmlPageName (vb."riot"), dit is de paginanaam die de CGI verwerking opstart als ze door een browser wordt aangevraagd met de "GET" methode (zie Http protocol GET). Verder zit hierin ook een pointer naar de CGI functie die moet worden opgestart (CGI_example_func). CGI functie aangeven in het userprogramma. De CGI functie kan op volgende manier worden aangegeven: void huge_pascal CGI_example_func (rpcgiptr CgiRequest) De functienaam CGI_example_func kan men net zoals de variabelenaam CgiRequest zelf kiezen. Indien de Webserver een aanvraag binnenkrijgt met de geschikte parameters (zie hierboven) zal deze de functie CGI_example_func opstarten aan de hand van de gegevens in zijn entry 'example' in de CGI tabel. Hierbij wordt een pointer doorgegeven aan de functie CGI_example_func. Het is een pointer naar een structure CgiRequest, van het type rpcgiptr, (voor info over deze struct zie cgi.h). Hierin zit alle info van de browser request en responce. De functie CGI_example_func zal dan dynamisch een tekststring in de variabele DynamicHtmlPage aanmaken. Dit gebeurt vb. op volgende wijze: strcpy (DynamicHtmlPage,Pagehead); //vaste header invullen sprintf (tmpbuffer,"blablabla %ld",variable);//tijdelijke buffer opvullen met dynamische info strcat (DynamicHtmlPage,tmpbuffer); //buffer in pagina plakken strcat (DynamicHtmlPage,Page_end); //vast einde invullen Versie 1.0 72 [dp] D. Pauwels

Wanneer de dynamische Webpagina op deze manier is aangemaakt in een char buffer (in dit geval DynamicHtmlPage) moet deze aan de webserver worden doorgegeven. Dit kan worden gedaan door een aantal members van de structure CgiRequest met de gewenste informatie te initialiseren. Dit kan op volgende manier: CgiRequest -> fhttpresponse= CgiHttpok; // Http 200 ok, request has succeeded CgiRequest ->fresponsebufferptr=dynamichtmlpage; // pointer naar char buffer doorgeven CgiRequest ->fresponsebufferlength=strlen(dynamichtmlpage); //lengte van pagina De Webserver zal nu deze pagina doorgeven aan de browser die erom vroeg. WEB Http://192.168.200.8/riot WEBSERVER met CGI Geheugen Userprogramma Cgirequest Void huge_pascal CGI_example_func (rpcgiptr Cgirequest) fresponsebufferptr aanmaken DynamicHtmlPage(); Cgirequest->fHttpresponse=CGIHttpOk Cgirequest->fResponseBufferPtr=DynamicHtmlPage Cgirequest->fResponseBufferlength=strlen(DynamicHtmlPage) DynamicHtmlPage Tabel met CGI TAGS example.pathptr= riot example example.method= GET example.cgifuncptr=cgi_example_func Figuur 5.4: Opstarten van een CGI functie. Versie 1.0 73 [dp] D. Pauwels

Het volgende voorbeeld zal in dit verband veel duidelijk maken. /**************************************************************************** * Example of using the CGI on the RIOT board v1.0 * * Created by [dp] 23.04.2002 * Based on an example of BECK IPC GmbH * * BECK IPC GmbH * Garbenheimerstr. 38 * D-35578 Wetzlar * * Phone : (49)-6441-905-240 * Fax : (49)-6441-905-245 * * --------------------------------------------------------------------------- Function : This program demonstrates the usage of the implemented CGI-Interface of IPC@CHIP in a dos program. The programmer could use this program as an example for building own cgi functions. Compiler : Borland C 3.0 Memorymodel : Large Note: Before testing this example, the directory "web" and the file "main.htm" should exist at the IPC@CHIP. This could be done with FTP or via the serial port. Description: At the start of the program, we set the current root directory of the webserver to the directory "web" and set a new mainpage name "main.htm". This is only to demonstrate this features, it's not important for the working of the program. After doing that, the webserver searches for all requested files at this directory. A browserrequest with the '/ ' e.g. http://192.168.205.4/ is (from now on) answered from the server with the new mainpagefile "main.htm" at the root directory "web". Furthermore we install a cgi function, which produces a dynamic htmlpage in the memory. This page has the name "DynamicHtmlPage". The name of the installed cgi function is "CGI_example_func". The expected http method is "GET". If a browserrequest e.g. http://192.168.205.4/riot comes in, the web server calls this function. At the mainloop of our program, we read the temperature that is measured by the IOsys chip. An analog temp. Sensor LM35 (10mV/Kelvin) is connected to the analog input 0 of IOsys. This analog value is converted to a 10 bit digital value by IOsys, and can be read by the IPC@CHIP. The called function builds a string, which contains a small html page with the actual value of our temperature. During runtime of the program, the page "riot" can be loaded from a browser. After two minutes the program ends. A browserrequest after the end of the program returns "Object not found,..." Important: At the end of the program we must remove the installed cgi function from webservers CGI table. *****************************************************************************/ Versie 1.0 74 [dp] D. Pauwels

/****************************************************************************/ /* includes /****************************************************************************/ #include <DOS.H> #include <STDIO.H> #include <STRING.H> /****************************************************************************/ /* API includes: This can be as simple as: #include "CGI.H" /* but for illustration purpose the file is included in integral form here /****************************************************************************/ #ifndef _CGI_H #define _CGI_H /*****************************************************************************/ //CGI defines /*****************************************************************************/ //Cgi HTTP requests #define CgiHttpGet 1 /* Cgi request is HTTP GET */ #define CgiHttpHead 2 /* Cgi request is HTTP HEAD */ #define CgiHttpPost 3 /* Cgi request is HTTP POST */ //Cgi HTTP responses #define CgiHttpOk 0 /* Cgi returns HTTP 200 Ok */ #define CgiHttpOkStatic 1 /* Cgi returns HTTP 200 Ok - Static Object */ #define CgiHttpRedirect 2 /* Cgi returns HTTP 302 Moved Temp */ #define CgiHttpNotModified 3 /* Cgi returns HTTP 304 Not Modified */ #define CgiHttpUnauthorized 4 /* Cgi returns HTTP 401 Unauthorized */ #define CgiHttpNotFound 5 /* Cgi returns HTTP 404 Not Found */ #define CgiHttpOKNoDoc 6 /* Cgi returns HTTP 204 No document follows*/ //CGI constants for content types,fdatatype #define CGIDataTypeHtml 0 /* CGI returns text/html */ #define CGIDataTypeImageGif 1 /* image/gif */ #define CGIDataTypeApplet 2 /* application/octet-stream */ #define CGIDataTypeText 3 /* text/plain */ #define CGIDataTypeImageJpeg 4 /* image/jpeg */ #define CGIDataTypeImagePict 5 /* image/pict */ #define CGIDataTypeImageTiff 6 /* image/tiff */ #define CGIDataTypeImagePng 7 /* image/png */ #define CGIDataTypeForm 8 /* application/x-www-form-urlencoded */ #define CGIDataTypeIpp 9 /* application/ipp */ #define CGIDataTypeCss 10 /* text/css */ #define CGIDataTypeXml 11 /* text/xml */ #define CGIDataTypeWav 12 /* audio/wav */ Versie 1.0 75 [dp] D. Pauwels

#define CGIDataTypePdf 13 /* application/pdf */ #define CGIDataTypeJavaArchive 14 /* application/java-archive */ #define CGIDataTypeOctet 15 /* application/octet-stream */ #define CGIDataTypeVndWapWml 16 /* text/vnd.wap.wml */ #define CGIDataTypeVndWapWbmp 17 /* image/vnd.wap.wbmp */ #define CGIDataTypeVndWapWmlc 18 /* application/vnd.wap.wmlc */ #define CGIDataTypeVndWapWmlscript 19 /* text/vnd.wap.wmlscript */ #define CGIDataTypeVndWapWmlscriptc 20 /* text/vnd.wap.wmlscriptc */ /*****************************************************************************/ //Cgi API calls /*****************************************************************************/ #define CGI_INSTALL 1 /* Install a cgi function */ #define CGI_REMOVE 2 /* Delete a cgi function */ #define CGI_SETMAIN 3 /* Set new main page name */ #define CGI_SETROOTDIR 4 /* Set webservers root directory */ #define CGI_GETROOTDIR 5 /* Get webservers root directory */ #define CGI_GETMAIN 6 /* Get name of main page*/ #define CGI_GETFORMITEM 7 /* Split argumentbuf into formular name and value*/ #define CGI_FINDNEXTITEM 8 /* Find next formitem, if one */ #define CGI_INSTALL_PAS 9 /* Install a Turbo Pascal cgi procedure */ /*****************************************************************************/ //CGI API general Errorcodes /*****************************************************************************/ #define CGI_NOT_SUPPORTED -2 #define CGI_ERROR -1 #define CGI_ENOERROR 0 /*****************************************************************************/ //CGI API special Errorcodes, returned at the ax-register /*****************************************************************************/ #define CGI_INVALID_METHOD -1 #define CGI_INVALID_NAME -2 #define CGI_INVALID_DIR -3 #define CGI_NO_FREE_ENTRY -4 #define CGI_NOT_FOUND -5 #define PFE_INT 0xA2 #define HAL_INT 0xA1 // Pin Function Enable sw INT // Hardware Abstraction Layer sw INT Versie 1.0 76 [dp] D. Pauwels

/*****************************************************************************/ //types /*****************************************************************************/ typedef struct tag_cgi_table char *PathPtr; //name of the page int method; //httpmethod: get or post void *CgiFuncPtr; //ptr to callback function of this page CGI_Entry; /* the called cgi function gets as a parmeter a pointer of the following structure, which contains the needed http-request data and response data */ typedef struct //Request fields, read only!!!! unsigned char fconnectionid; // internal use only int fhttprequest; // internal use only char * fpathptr; // URL char * fhostptr; // Host: char * frefererptr; // (at time not supported) char * fagentptr; // (at time not supported) char * flanguageptr; // (at time not supported) unsigned long fbrowserdate; // Date: (internal) char * fargumentbufferptr; // Pointer at argument buffer long fargumentbufferlength; // length of argument buffer, -1 buffer empty char * fusernameptr; // Username from Authorization char * fpasswordptr; // Password from Authorization long * fremoteipptr; // Pointer to RemoteIP in wrong byte order //, do not modify //Response fields, int fresponsestate; // internal, do not modify int fhttpresponse; // response msg mostly CgiHttpOK int fdatatype; // content type mostly text/html char * fresponsebufferptr; // pointer to created dynamic html page long fresponsebufferlength; // length of the created page unsigned long fobjectdate; // internal, do not modify unsigned int fhostindex; // internal, do not modify rpcgi, *rpcgiptr; /*****************************************************************************/ Versie 1.0 77 [dp] D. Pauwels

/*************************************************************************/ //defines /*************************************************************************/ //needed interrupt vectors #define TCP_INT 0xAC #define CGIVECT 0xAB #define MAIN_LOOPS 120L /* our program run MAIN_LOOPS seconds*/ /****************************************************************************/ //needed registerstructs for CGI interrupt calls /****************************************************************************/ static union REGS inregs; static union REGS outregs; static struct SREGS segregs; // Make sure that the lower priority tasks like the webserver get some time to // execute their code,... otherwise no concurrent webserver! void api_sleep (int ms) inregs.x.ax=0x0900; inregs.x.bx=ms; int86x(tcp_int,&inregs,&outregs,&segregs); static float volt1,volt=0,voltcgi=0; /****************************************************************************/ // we set the name "main.htm" as main page name // this means: if a browserrequest e.g. http://192.168.205.4/ // occurs, the webserver returns the file "main.htm" /****************************************************************************/ char * MainpageName = "main.htm"; /****************************************************************************/ // we set the default directory as root directory /****************************************************************************/ char * WebRootDirectory = "web"; /*************************************************************************** the name of the (dynamic) page for the browserrequest e.g. http://192.168.200.5/riot ****************************************************************************/ char * HtmlPageName = "riot"; /*************************************************************************** //our cgi entry webserver ***************************************************************************/ CGI_Entry example; // example is a struct of te CGI_Entry type Versie 1.0 78 [dp] D. Pauwels

// Init RIOT v1.0. void enable_databus (void) // Enable 8 bits databus inregs.x.ax = 0x8001; // enable ALE, databus inregs.x.dx = 0x00FF; // all 8 bits are enabled int86(pfe_int, &inregs, &outregs); // Enable programmable chip select1 (poi4) inregs.h.ah = 0x83; inregs.x.dx = 0x02; // PCS1# (100h-1FFh) int86(pfe_int, &inregs, &outregs); void select_bank0 (void) // Reset pio2, pio3 lines inregs.h.ah = 0x82; inregs.h.al = 0x05; // pio2,pio3 both 0 inregs.x.dx = 0x000C; // enable pio2,pio3 int86(pfe_int, &inregs, &outregs); void select_bank1 (void) // Reset pio3 line inregs.h.ah = 0x82; inregs.h.al = 0x05; // pio3 state 0 inregs.x.dx = 0x0008; // enable pio3 int86(pfe_int, &inregs, &outregs); // Set pio2 line inregs.h.ah = 0x82; inregs.h.al = 0x04; // pio2 state 1 inregs.x.dx = 0x0004; // enable pio2 int86(pfe_int, &inregs, &outregs); void select_bank2 (void) // Set pio3 line inregs.h.ah = 0x82; inregs.h.al = 0x04; // pio3 state 1 inregs.x.dx = 0x0008; // enable pio3 int86(pfe_int, &inregs, &outregs); Versie 1.0 79 [dp] D. Pauwels

// Reset pio2 line inregs.h.ah = 0x82; inregs.h.al = 0x05; // pio2 state 0 inregs.x.dx = 0x0004; // enable pio2 int86(pfe_int, &inregs, &outregs); void select_bank3 (void) // Set pio2, pio3 lines inregs.h.ah = 0x82; inregs.h.al = 0x04; // pio2,pio3 both 1 inregs.x.dx = 0x000C; // enable pio2,pio3 int86(pfe_int, &inregs, &outregs); // Read databus on specified address ( inportb (address);) unsigned char read_databus (unsigned int ram_address) unsigned char value; // read data bus inregs.h.ah = 0x80; inregs.x.di = ram_address; inregs.x.bx = 0xFFFF; // address = user parameter // wand=0xffff // wxor=0x0000 inregs.x.cx = 0x0000; int86x(hal_int, &inregs, &outregs, &segregs); value = outregs.h.al; return value; // Write databus to specified address ( outportb (portaddress,value);) void write_databus (unsigned char value,unsigned int ram_address) // write data bus inregs.h.ah = 0x81; inregs.x.di = ram_address; // address = user parameter inregs.h.dh = 0; inregs.h.dl = value; inregs.x.bx = 0xFF; // wand=8 bits databus inregs.x.cx = 0x0000; // wxor=0x0000 int86x(hal_int, &inregs, &outregs, &segregs); Versie 1.0 80 [dp] D. Pauwels

RIOT Remote Internet Operated Terminal. /*************************************************************************** Predefine head and tail of our page ***************************************************************************/ char * PageHead = "<HTML><HEAD><TITLE>CGI on the riot MGM/[dp] board</title></head>" "<META http-equiv=\"refresh\" content=\"1\">"; char * PageMiddle =// "<BODY BGCOLOR=\"#A0A0A0\">" this line is included dynamicaly! // with the color changing as a function of temp, see the CGI_example_func "<BR><BR>" "<CENTER>" "<H1> Dynamic Web page on the MGM/[dp] RIOT board </H1>" "<H1> Temperature in our office </H1>" "<HR size=0>" "<FONT FACE=\"Courier\" SIZE=+2>"; char * PageEnd = "</FONT>" "<HR size=0>" "<p align=center><small><em> &copy MGM[dp], 2002 </EM>" "</BODY>" "</HTML>"; /*************************************************************************** The cgi function stores the dynamic HTML page in this buffer ***************************************************************************/ char DynamicHtmlPage[512]; Versie 1.0 81 [dp] D. Pauwels

/**************************************************************************** CGI function, the webserver executes this function, if a browser request e.g. http://192.168.200.8/riot comes in. Whit this function we build a new html page in memory, including the current temperature value of the main loop. At the end of this function we tell the webserver the address of our buffer and its length. The webserver sends this buffer back to the browser ****************************************************************************/ void huge pascal CGI_example_func(rpCgiPtr CgiRequest) char tmpbuffer[80],tmpbuffer1[20]; char *red="a0",*green="a0",*blue="a0"; /**********************************/ //building the page /**********************************/ //insert the head of the page strcpy(dynamichtmlpage,pagehead); // change the color as a function of the measured temperature if (voltcgi<14.0) red="00";green="2e";blue="e2"; if ((voltcgi<15.0) && (voltcgi>=14.0))red="00";green="2e";blue="e2"; if ((voltcgi<16.0) && (voltcgi>=15.0))red="06";green="00";blue="e2"; if ((voltcgi<17.0) && (voltcgi>=16.0))red="33";green="00";blue="e2"; if ((voltcgi<18.0) && (voltcgi>=17.0))red="6b";green="00";blue="e2"; if ((voltcgi<19.0) && (voltcgi>=18.0))red="9b";green="01";blue="d7"; if ((voltcgi<20.0) && (voltcgi>=19.0))red="ab";green="02";blue="ca"; if ((voltcgi<21.0) && (voltcgi>=20.0))red="bd";green="03";blue="bd"; if ((voltcgi<22.0) && (voltcgi>=21.0))red="bd";green="03";blue="8f"; if ((voltcgi<23.0) && (voltcgi>=22.0))red="ca";green="02";blue="7f"; if ((voltcgi<24.0) && (voltcgi>=23.0))red="ca";green="02";blue="64"; if ((voltcgi<25.0) && (voltcgi>=24.0))red="ca";green="02";blue="58"; if ((voltcgi<26.0) && (voltcgi>=25.0))red="dc";green="02";blue="3c"; if ((voltcgi<27.0) && (voltcgi>=26.0))red="fa";green="00";blue="2d"; if (voltcgi>=27.0) red="ff";green="00";blue="00"; sprintf (tmpbuffer1,"<body BGCOLOR=\"#%2s%2s%2s\">",red,green,blue); strcat(dynamichtmlpage,tmpbuffer1); // Add color info dynamicaly strcat(dynamichtmlpage,pagemiddle); //get main loop temperature sprintf(tmpbuffer,"<br>is currently: %2.1f gr.celcius<br>",voltcgi); strcat(dynamichtmlpage,tmpbuffer); //append the predefined tail strcat(dynamichtmlpage,pageend); Versie 1.0 82 [dp] D. Pauwels

/**********************************/ //give it to the webserver /**********************************/ CgiRequest->fHttpResponse = CgiHttpOk; CgiRequest->fResponseBufferPtr = DynamicHtmlPage; CgiRequest->fResponseBufferLength = strlen(dynamichtmlpage); /****************************************************************************/ int main(void) printf("\r\nstarting CGI example program\r\n\r\n"); /********************************/ //Set mainpage name /********************************/ inregs.h.ah = CGI_SETMAIN; inregs.x.dx = FP_SEG(MainpageName); // "main.htm" inregs.x.si = FP_OFF(MainpageName); int86(cgivect,&inregs,&outregs); if(outregs.x.dx == (unsigned int)cgi_error) printf("\r\nsetting mainpage %s failed\r\n",mainpagename); /********************************/ //Set webservers rootdirectory /********************************/ inregs.h.ah = CGI_SETROOTDIR; inregs.x.dx = FP_SEG(WebRootDirectory); // "Web" inregs.x.si = FP_OFF(WebRootDirectory); int86(cgivect,&inregs,&outregs); if(outregs.x.dx == (unsigned int)cgi_error) printf("\r\nsetting root directory %s failed\r\n",webrootdirectory); /********************************/ //Get mainpage name /********************************/ inregs.h.ah = CGI_GETMAIN; int86x(cgivect,&inregs,&outregs,&segregs); printf("\r\nmainpage : %s",(char *)MK_FP(segregs.es,outregs.x.di)); Versie 1.0 83 [dp] D. Pauwels