Toon posts:

Outp in Linux

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0Henk 'm!

  • Joseph
  • Registratie: April 2008
  • Laatst online: 01:36
Waarschijnlijk is dit een kleinigheid, maar ik kan het (hier) iig niet vinden.

Ik ben bezig wat te experimenteren in C#. Ik heb er een handboek bij. Maar helaas lijkt die meer Windows, of zelfs DOS orienterend te zijn.

Mijn vraag is simpel. Het boek draagt een groot stuk code aan. Ik wist een heleboel errors te fixen naar een error. Hij begrijpt de statement outp(); namelijk niet. Het hele programma werkt, nadat ik de functie eruit had gesloopt. Het is namelijk een functie voor de PC speaker.

Het gaat om deze code.
C#: beep.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
beep()
{
    unsigned freq = 280, time = 300000;
    long t1, t2, ii;
    
    outp( 0x43, 0xb6 );
    outp( 0x42, freq );
    outp( 0x42, freq >> 8 );
    outp( 0x61, 0x4f );
    
    for( ii = 1; ii < time; ii++ );
        outp( 0x61, 0x4d );
        
}


Ik denk dat ik de Linux variant van outp() nodig heb. Maar ik had ergens gelezen dat deze statement uitgefaseerd was.

Heeft iemand de clue?

Acties:
  • 0Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 22:20
Dit is C/C++-code, geen C#. Het enige dat ik over outp() vond was dit:
http://www.daniweb.com/so...opment/cpp/threads/240245

Daarnaast, welke header files heb je ge-include, aangezien ik outp() niet bepaald vond bij mij.

[Voor 16% gewijzigd door Styxxy op 31-05-2011 19:07]


Acties:
  • 0Henk 'm!

  • Joseph
  • Registratie: April 2008
  • Laatst online: 01:36
Volgens mij is die functie uitgefaseerd. Ik denk dat ik gebruik moet maken van de Linux API's, om de hardware aan te spreken.

Alleen ik kan weinig vinden over API's van de Linux kernel. Waarschijnlijk gebruik ik te complexe zoektermen. Heeft iemand pointers? :)

Acties:
  • 0Henk 'm!

  • Ventieldopje
  • Registratie: December 2005
  • Laatst online: 00:12

Ventieldopje

I'm not your pal, mate!

Is dit misschien wat je zoekt?

http://linux.die.net/man/2/outb aangezien outp inderdaad uitgefaseerd is ;)

Voorbeeld code: http://www.faqs.org/docs/...-Port-Programming.html#s9

[Voor 28% gewijzigd door Ventieldopje op 31-05-2011 19:31]

www.maartendeboer.net
1D X | 5Ds | Zeiss Milvus 25, 50, 85 f/1.4 | Zeiss Otus 55 f/1.4 | Canon 200 f/1.8 | Canon 200 f/2 | Canon 300 f/2.8


Acties:
  • 0Henk 'm!

  • Joseph
  • Registratie: April 2008
  • Laatst online: 01:36
Die code kijk ik net naar. Hierbij moet je voor elk commando specifiek toegang geven tot een hardware adres.
Als ik nu dit wil doen:
C#: beep.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
beep()
{
    unsigned freq = 280, time = 300000;
    long t1, t2, ii;
    
        ioperm();
    outp( 0x43, 0xb6 );
    outp( 0x42, freq );
    outp( 0x42, freq >> 8 );
    outp( 0x61, 0x4f );
    
    for( ii = 1; ii < time; ii++ );
        outp( 0x61, 0x4d );
        
}

Hiermee gebruik ik ioperm om de onderstaande set opdracht te permitten. Alleen dat gaat niet. Heeft iemand een idee?

Acties:
  • 0Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 00:16

Reptile209

- gers -

Wel even de juiste parameters specificeren hè :). Zie een stuk hoger op dezelfde pagina:
[...]The syntax is ioperm(from, num, turn_on), where from is the first port number to give access to, and num the number of consecutive ports to give access to. For example, ioperm(0x300, 5, 1) would give access to ports 0x300 through 0x304 (a total of 5 ports). The last argument is a Boolean value specifying whether to give access to the program to the ports (true (1)) or to remove access (false (0)). You can call ioperm() multiple times to enable multiple non-consecutive ports. See the ioperm(2) manual page for details on the syntax. [...]

[Voor 4% gewijzigd door Reptile209 op 31-05-2011 21:07]

Ik verafschuw wat u zegt, maar ik zal uw recht om het te zeggen met mijn leven verdedigen. - Voltaire


  • yade
  • Registratie: Mei 2002
  • Laatst online: 17-05 22:48
Dit is absoluut geen C# code, en die for loop doet volgens mij ook niets dankzij die puntkomma.

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 30-05 08:49
Die for loop is een uiterst professionele (ahum) delay, zie ook freq en time. En inderdaad lijkt me dit geen c# maar C++.
Ik weet niet wat voor boek je hebt maar ik zou naar een ander boek opzoek gaan.

@yade:
Oh oeps iets te snel er van uigegaan dat dit dezelfde soort code was die ik recent nog tegen kwam voor een μc.

[Voor 41% gewijzigd door jmzeeman op 03-06-2011 09:38]


  • yade
  • Registratie: Mei 2002
  • Laatst online: 17-05 22:48
Het inspringen suggereert dat er wat anders bedoeld wordt.

Acties:
  • 0Henk 'm!

  • Gimmeabrake
  • Registratie: December 2008
  • Laatst online: 23-05 09:56
Ik heb de ballen verstand van C, maar het lijkt me verstandig om de puntkomma bij de for-loop weg te halen :p
C:
1
2
for( ii = 1; ii < time; ii++ ) //HIER STOND EEN ;
        outp( 0x61, 0x4d );


Daarnaast wil ik nog even benadrukken dat dit geen C# is maar C of C++. Aan een C# handboek heb je bij deze talen vrij weinig: ookal verschilt de naam nauwelijks en lijkt de syntax soms best veel op elkaar zitten er grote, fundamentele verschillen tussen die talen. Zoeken naar een C of C++ boek dus! ;)

edit: vreemd. Deze topic staat bij mij bovenaan in PRG, zie zojuist dat de laatste reactie 2 dagen geleden was. En mijn puntkomma opmerking is al een keer gemaakt door yade, zie het nu pas. Ach, het is nog vroeg :+

[Voor 17% gewijzigd door Gimmeabrake op 03-06-2011 10:37]


Acties:
  • 0Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 30-05 14:22

leuk_he

1. Controleer de kabel!

Het inspringen is fout, de ; is "goed".


De for loop is er om een vertraging te genereren, het outp commando is er om de timer los te koppelen van de speaker, dus het geluid uit te zetten.

In dos had dit goed gewerkt, onder linux heb je als het goed is de hardware afgeschermd van gebruikers programma's. De loop werkt ook niet goed, op een snelle CPU zal deze te snel zijn, op een goede compiler wordt hij weggeoptimaliseerd.

dus het is onverstandig om in 2011 een pc op deze manier geluid te laten maken. (als je het over embedded hardware hebt is het aansturen van poorten wel een optie)

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 00:49
Zoals genoemd komt de code uit het real-mode DOS tijdperk waarin je je hardware nog direct aanstuurde (hoewel er niets DOS-specifieks aan de code is). Niettemin zijn de meeste PCs tegenwoordig nog wel redelijk compatible met de originele IBM PC, en zou je het geheel wel onder Linux werken moeten krijgen. Er zijn echter wel een aantal problemen met de code:
  1. Zoals leuk_he terecht opmerkt is een vertraging introduceren met een lusje not done, omdat de duur ervan onvoorspelbaar is. (Overigens optimaliseert GCC -- toch een goede compiler, mijns inziens -- dit soort lusjes juist expres niet weg.) De oplossing is simpel: gebruik gewoon sleep() of (onder Linux/POSIX) nanosleep() om een vertraging te introduceren.
  2. Onder een modern besturingssysteem kun je niet zomaar naar alle poorten schrijven; daar moet je eerst permissie voor vragen. ioperm() is daar inderdaad de geschikte functie voor, maar je moet natuurlijk wel de goede argumenten meegeven.
  3. Er is geen standaardfunctie voor outp() voor zover ik weet, aangezien dat een x86-specifieke instructie is, maar je kunt 'm wel zelf introduceren met behulp van een inline assembly statement.
  4. Tenslotte is de waarde die je naar port 42h schrijft géén frequentie, maar een vertraging. De PC speaker timer heeft een kloksnelheid van 1.193.180 Hz, dus om de juiste vertraging te berekenen moet je die frequentie delen door de frequentie van de gewenste toon.
Door dit alles te combineren, kom ik op zoiets uit:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>

#define outp(port, value) \
    asm("outb %1, %0" : : "d"((short)(port)), "a"((char)(value)));

void beep(unsigned freq)
{
    unsigned delay = 1193180/freq;      /* convert frequency to delay */
    outp(0x43, 0xb6);                   /* initialize PC  speaker */
    outp(0x42, delay & 0xff);           /* write delay low byte */
    outp(0x42, delay >> 8);             /* write delay high byte */
    outp(0x61, 0x4f);                   /* enable output */
    sleep(1);                           /* wait 1 second */
    outp(0x61, 0x4d);                   /* disable output */
}

int main()
{
    if (ioperm(0x42, 2, 1) != 0 || ioperm(0x61, 1, 1) != 0)
    {
        perror("ioperm()");
        return 1;
    }
    beep(280 /* Hz */);
    return 0;
}

Ik vermoed dat dit zou moeten werken, maar ik heb het niet getest, aangezien ik mijn PC-speaker fysiek niet aangesloten heb. :P

edit:
D'oh! Er blijken ook gewoon een macro outb in sys/io.h gedefinieerd te worden. Die kun je dus beter gebruiken in plaats van een eigen macro.

[Voor 4% gewijzigd door Soultaker op 03-06-2011 13:49]

Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee