© Harry Broeders.
In dit practicum maken we gebruik van het real-time OS QNX Neutrino. Dit real-time OS is speciaal ontworpen om gebruikt te worden voor embedded systemen. Wij gebruiken het OS gewoon op PC's (lekker goedkoop) maar je moet je voorstellen dat de ontwikkelde software uiteindelijk als een embedded applicatie moet draaien. QNX Neutrino en de bijbehorende ontwikkelomgeving QNX Momentics zijn gratis te downloaden en ook thuis prima te gebruiken. Ik raad je sterk aan om zelf ook thuis met QNX aan de slag te gaan!
QNX is IEEE POSIX 1003.1 compatible. IEEE POSIX 1003.1 is een standaard voor UNIX systemen. QNX implementeert ook de real-time faciliteiten uit deze standaard, de meeste andere UNIX systemen (inclusief Linux) implementeren deze real-time faciliteiten niet. Er zijn wel enkele real-time versies van Linux beschikbaar maar ook deze zijn (tenminste degene die bij mij bekend zijn) niet POSIX compatible. Een ander bekend POSIX compatible RTOS is VxWorks.
In lokaal 428 (en ook in 213) is op elke PC QNX Neutrino beschikbaar. Je kunt inloggen als gebuiker root met paswoord root. Alle files die je daar opslaat blijven echter niet bewaard! Je kunt je files via scp (secure copy) opslaan op je H:\ drive. Dit wordt verderop uitgelegd.
Doordat QNX POSIX compatible is kun alle commando's die je bij het Linux practicum hebt geleerd toepassen. Een goede inleiding in het gebruik van UNIX (= Linux = QNX) kun je vinden op: http://wks.uts.ohio-state.edu/unix_course/intro-1.html. Je kunt onder QNX meerdere virtuele terminals openen. In een terminal window:
man
(manual) commando echter niet (wel
een vergelijkbaar commando use
).
Opdracht 1a.
Log in op een QNX systeem in lokaal 428 of 213 als gebruiker root
met paswoord root. Open een virtual terminal en probeer een paar van
de bekende Linux commando's. Maak indien nodig gebruik van de helpfiles.
Maak een directory mkdir eswe1 cd eswe1 echo "Hallo" >hallo.txt ls cat hallo.txt cd .. ls
Je kunt nu in een keer dit directory naar je scp -r eswe1 EDU-jouwnaam@ssh-gw.hhs.nl:
Voor The authenticity of host 'ssh-gw.hhs.nl (145.52.89.10)' can't be established. RSA key fingerprint is 49:de:1a:c4:c0:42:d3:7e:6f:7b:85:1e:74:94:4f:87. Are you sure you want to continue connecting (yes/no)? Dit is een onderdeel van het SSH protocol en bedoeld om te controlleren of je echt met de juiste server praat. Meer info vind je hier: http://winscp.net/eng/docs/ssh#verifying_the_host_key. Beantwoord deze vraag met yes. Vervolgens wordt om je paswoord gevraagd.
Ook vanaf thuis kun je jouw
Zoek je nog een VCP (Vrij Credit Point) opdracht? Ik zoek nog iemand die wil uitzoeken of er een grafische sftp client voor QNX beschikbaar is. Of die anders een eenvoudige grafische applicatie kan schrijven om, met 1 druk op de knop, je files van een QNX machine op te slaan op je H:\ drive (en weer te terug te zetten).
Verwijder nu het rm -r eswe1 ls scp -r EDU-jouwnaam@ssh-gw.hhs.nl:eswe1 . ls cat eswe1/hallo.txt Aan het eind van elk practicum moet je dus zelf je files opslaan en aan het begin van het volgende practicum kun je die files dan weer terugzetten. Tip: QNX kent net zoals Windows en Linux "command completion" (commado's en filenames worden automatisch afgemaakt) alleen gebruikt QNX hiervoor niet de TAB toets maar de ESC toets. Ik heb nog niet geprobeerd om de files vanuit QNX op een USB stick op te slaan. Zie: http://www.qnx.com/developers/docs/6.3.2/neutrino/user_guide/hardware.html#USB |
De ontwikkeltools van QNX (Momentics) zijn gebaseerd op de bekende GNU tools http://www.gnu.org. Bijna alles wat je leert over QNX kun je dus ook toepassen op Linux of elk ander UNIX systeem.
QNX heeft ook veel grafische programma's. Deze programma's kun je via de Launch button (waarschijnlijk heeft Microsoft de Start geregistreerd ;-) of via de rechter knoppenbalk opstarten. Enkele handige sneltoetsen:
QNX heeft ook een grafische File Manager:
De webbrowser van QNX heet Voyager. In plaats van Voyager kun je ook gebruik maken van de Mozilla browser.
Voor het ontwikkelen van software gebruiken wij het programma Workspace. Dit programma staat op de 3th party CD van QNX. Het bestaat uit een code editor, html browser en een koppeling met sh, make, gdb en ctags. De kleuren moet je even aan wennen (of aanpassen via Edit, Preferences menu).
Als een C programma gewijzigd wordt dan moet dit programma uiteraard opnieuw
gecompileerd worden. Dit kan wel eens even duren als het C programma uit
een groot aantal regels bestaat. Dit probleem kan opgelost worden door het
C programma niet in 1 source file te plaatsen maar te verdelen over meerdere
source files. Deze source files kunnen dan separaat gecompileerd worden m.b.v.
het commando gcc -c source-filename
. De op deze wijze verkregen
z.g. object files zijn vanzelfsprekend niet "executable" omdat b.v. de adressen
van gebruikte variabelen die in een andere source file gedefinieerd zijn
(z.g. external variables) nog moeten worden ingevuld. Deze object files kunnen
echter wel m.b.v. een z.g. linker (ld
) samengevoegd worden tot
1 executable programma. Het commando gcc
zal automatisch de
linker ld
aanroepen als de, als argumenten, meegegeven files
object files zijn (herkenbaar aan de extensie ".o
"). Als er
nu wijziging aangebracht wordt in 1 van de source files van het programma
dan is het dus niet meer nodig dat het gehele programma gecompileerd wordt.
Er kan in dit geval volstaan worden met het separaat compileren van de gewijzigde
source file en het opnieuw linken van alle object files. Deze manier van
werken levert dus een aanzienlijke tijdsbesparing op bij de ontwikkeling
en het testen van een "groot" C programma. De wet van behoud van ellende
zorgt er echter voor dat deze manier van werken ook een aantal vragen of
problemen oproept:
Het gebruik van z.g. "header files" lost het eerste probleem op en het gebruik
van de UNIX utility make
vormt een antwoord op de tweede vraag.
M.b.v. de compiler directive #include "file_name.h"
kunnen z.g.
"header" files in een source programma opgenomen worden. De compiler (om
precies te zijn de pre-processor) zal de regel waarop deze directive staat
vervangen door de inhoud van de opgegeven header file. Het is gebruikelijk
om header files de extensie ".h
" te geven. Als er in verschillende
source files b.v. gebruik gemaakt wordt van hetzelfde type, dan kan de
betreffende type definitie in een header file worden opgenomen. Deze header
file moet dan in alle source files die gebruik maken van dit type "included"
worden. Als nu dit gemeenschappelijk gebruikte type gewijzigd moet worden
dan kan volstaan worden met het wijzigen van de header file en het opnieuw
compileren van de source files die gebruik maken van dit type.
Er bestaat bij veel "beginnende" C programmeurs verwarring over het gebruik van include files bij het gemeenschappelijk gebruik van variabelen en functies.
Stel dat een C programma verdeeld is over 3 source files en dat in al deze
source files gebruik gemaakt wordt van de globale variabele
globe
van het type long
. Het is nu
niet goed om een header file aan te maken waarin de definitie:
long globe;
is opgenomen en deze file in de 3 source files te "includen".
Dit werkt niet omdat bij het compileren van elke source file de variabele
globe
wordt gedefinieerd (in de object file wordt aangegeven
dat er in het datasegment van het programma een variabele van het type
long
met als naam globe
moet worden opgenomen die
ook toegankelijk is voor andere object files). Als geprobeerd wordt om deze
3 object files te linken dan zal de linker een foutmelding geven omdat de
variabele globe
drie maal gedefinieerd is. (Om helemaal
correct te zijn: Als geprobeerd wordt om deze 3 object files te linken dan
zal de linker de fout herkennen en verbeteren. De linker zal de eerste definitie
normaal verwerken en alle volgende identieke definities (die dus eigenlijk
fout zijn) verwerken als declaraties. Dit gedrag heeft in het verleden voor
veel problemen gezorgd bij het debuggen. Het lijkt namelijk alsof een bepaalde
variabele in een bepaalde file gedefinieerd (en dus ook gealloceerd) wordt
terwijl deze variabele in werkelijkheid ergens anders gedefinieerd is. De
opvolger van C, de programmeertaal C++, genereert wel een foutmelding als
een variabele meerdere malen globaal gedefinieerd wordt. De gcc compiler
heeft een speciale linker optie -Wl,-warn-common
. Als deze optie
wordt opgegeven dan wordt een warning gegeven als een variabele meerdere
keren gedefinieerd is.)
De juiste manier van werken is als volgt:
In 1 van de drie source files moet de variabele globe
als volgt
worden gedefinieerd:
long globe;
Er moet een header file worden aangemaakt waarin de volgende declaratie is opgenomen:
extern long globe;
D.w.z. dat de variabele globe
in een andere file is gedefinieerd
en dat het adres van deze variabele pas tijdens het linken kan worden ingevuld.
Deze header file moet dan in de twee overige files "included" worden.
Voor het gemeenschappelijk gebruik van zelf geschreven functies geldt hetzelfde als voor het gemeenschappelijk gebruik van variabelen. Bij het gebruik van standaard functies heerst nogal eens verwarring over de functie van de header file:
Als gebruik gemaakt wordt van een standaard functie dan is het vaak nodig
om een standaard header file te "includen". Als b.v. gebruik gemaakt wordt
van de standaard functie sin()
moet aan de compiler duidelijk
gemaakt worden wat het return type van deze functie is. Dit kan op twee manieren:
sin
zelf te declareren:double sin();
#include <math.h>
<
en >
gebruikt worden i.p.v.
"
en "
om aan te geven dat de file math.h in het
standaard include directory moet worden gezocht. (Meestal is dit
/usr/include
.)double sin();
De C code van de functie sin
staat dus vanzelfsprekend
niet in de header file math.h. De source code van de functie
sin
is vaak zelfs niet op het systeem aanwezig. De source code
van de gebruikte GNU libraries (open-source) zijn wel beschikbaar. Misschien
is de functie sin
wel helemaal niet in C geschreven! De declaratie
geeft alleen maar aan dat de functie vanuit C aan te roepen is. De object
code van de functie sin
bevindt zich in de math library (libm.a).
Bij het linken moet er dus voor gezorgd worden dat deze object code wordt
meegelinkt. M.b.v. de optie -lm
kan opgegeven worden dat bij
het linken de math library (libm.a) moet worden doorzocht en dat de gebruikte
object modules moeten worden opgenomen in de uiteindelijke executable file.
(Er is 1 library die bij het linken automatisch altijd wordt doorzocht. Dit
is de z.g. "standard library" die o.a. de object code van alle functies die
in stdio.h zijn gedeclareerd bevat.)
In nevenstaand
figuur is een overzicht gegeven van de verschillende stappen die doorlopen
moeten worden om een C programma dat verdeeld is over 2 source files te vertalen.
Mogelijke commando's:
van..c.naar..out | gcc_p1.c_p2.c
|
doorzoek alleen standard library |
_ |
gcc_p1.c_p2.c_-lm |
doorzoek standard en math library |
van..c.naar..o | gcc_-c_p1.c
|
maak p1.o |
van..c.naar..s | gcc_-S_p2.c
|
maak p2.s |
van..s.naar..out | gcc_p1.s_p2.s
|
alleen standard library |
van..s.naar..o | gcc_-c_p1.s
|
maak p1.o |
van..o.naar..out | gcc_p1.o_p2.o
|
alleen standard library |
combinatie | gcc_p1.c_p2.o_-lm |
Maak eerst p1.o m.b.v. de pre-processor, de compiler en de assembler. Doorzoek de standard library en de math library en link de benodigde object modules tezamen met p1.o en p2.o tot de executable file a.out. |
Een overzicht van de verschillende opties waarmee je kunt bepalen welke acties
de gcc
compiler neemt kun je in de QNX help files vinden.
De UNIX utility make kan voorkomen dat, nadat er in verschillende source files wijzigingen aangebracht zijn, vergeten wordt om een gewijzigde source file te compileren. Een beschrijving van deze utility is hier beschikbaar. Lees in ieder geval dit hoofdstuk. (Het hele hoofdstuk!)
Opdracht 1b.
Bij de beoordeling wordt gevraagd om:
|