Menu (English) | Linux & Asm x86-32 | PIC microchip | Debian Packages | Links | Javastation Sun | Weblog | About
Menu (Nederlands) | Linux & Asm x86-32 | PIC microchip | Tux maakt koffie | Links |   | Weblog | Over
Laatste aanpassing : 2005-03-15

Hoe bedien ik mijn koffiemachine vanuit Linux?


SBC SK305

Dit kan je natuurlijk op verschillende manieren doen. Het grootste probleem is natuurlijk dat het niet altijd evident is om kabels van de PC naar de koffiemachine (of eenders welk ander elektrisch toestel) te trekken. Daarom ben ik op zoek gegaan naar een draadloze manier om dit te verwezelijken.

PHILIPS verkoopt draadloze afstands-schakelsystemen. Deze bestaan uit een draadloze zender die een of meedere apparaten kan bedienen. Hiervoor wordt gebruik gemaakt van een draadloze ontvanger die in het stopkontakt wordt gestoken.


Achterkant Voorkant

Deze afstandsbediening is vrij eenvoudig aan te passen, zodat je hem kan aansluiten op de PC. Het enige wat je daarvoor nodig hebt is een ULN2803. Ikzelf heb die afstandsbediening zo aangesloten op een IO-kaartje dat in mijn PC aanwezig is, maar het zou ook via de printerpoort moeten werken.

Schema

Om uiteindelijk de afstandsbediening aan te sturen dien je de gepaste waarde naar de IO-poort (of printerpoort) te sturen. Onder GNU/Linux kan je dit bv. doen met hetvolgende C-programma, dat ik vroeger eens als voorbeeld heb ontvangen (LINUX.B fidonet).

= Deze bewaar ik : Linux ===============================================KeepIt=
Msg  :   30     [1-87]                     Rcv
From : Pros Robaer                         27-May-97  20:22:14  2:292/8013.4
To   : Jan Wagemakers                                           2:292/8133
Subj : Linux & Assembler
=====================================================================REM_LINUX=
* Copied from: LINUX.B
Hallo Jan,

Op Sun, 25 May 97 08:29:28 +0200 schreef je naar Pros Robaer:

 PR>> BTW: als je (zoals elke rechtgeaarde bitneuker) met je parallelle
 PR>> poort of iets dergelijks wil gaan prossen, vergeet dan niet om eerst
 PR>> netjes toestemming te vragen [ioperm()], of je programma vliegt er
 PR>> uit...

 JW> Whue, dat is voorlopig nog chinees voor mij ;-)

Net zo min als je geheugen mag gebruiken, dat niet aan jouw
programma is toegewezen door het OS, mag je geen I/O-poorten
gebruiken, zonder het eerst te vragen. Doe je het toch, dan werpt
het OS je programma er uit vanwege een "Segmentation Fault"...

Daarmee ben je nog niet klaar. Als "normale" user zal je geen
toestemming krijgen om zo'n programma uit te voeren. Remedie: ofwel
log je in als root, ofwel zet je het UID-bit v/h prog. Zo:

  chown root.root poorttest
  chmod 4755 poorttest


 JW> En nu we er toch over bezig zijn, ik heb in mijn kompjoeter een zelfgebouwd
 JW> (elektuur) I/O-kaartje zitten. Onder dos kan ik dan BV. Ledjes laten
 JW> oplichten door : - mov dx,0310h
 JW>                  - out dx,al
 JW> Enig idee of dit ook onder Linux gaat?

Dit zou moeten werken:

----BEGIN-C-SOURCE---poorttest--------------------------------------

/*
 * poorttest
 *
 * schrijf iets naar poort 0x310
 */

#include <stdio.h>
#include <stdlib.h>
#define INLINE inline
#include <unistd.h>

unsigned short poort = 0x310;
int byte;

static INLINE void
outb (short port, char val)
{
  __asm__ volatile ("out%B0 %0,%1"::"a" (val), "d" (port));
}


/*
 * voor het geval je een poort wil lezen.
 * gebruik: byte = inb (het-adres-van-de-poort);
 */

static INLINE unsigned char
inb (short port)
{
  unsigned int ret;
  __asm__ volatile ("in%B0 %1,%0":"=a" (ret):"d" (port));
  return ret;
}

int
main (int argc, char *argv[])
{
  if (argc != 2)
    {
      printf (" Gebruik: %s <x>, waarbij x = 0...255\n", argv[0]);
      exit (2);
    }


  /*
   * als het programma meerdere malen naar dezelfde I/O-poort moet
   * schrijven, volstaat het 1 maal ioperm () aan te roepen.
   */

  ioperm (poort, 1, 1);
  byte = atoi (&argv[1][0]);
  outb (poort, byte);
}

----eind-C-SOURCE---------------------------------------------------

Plaats dit stuk potjeslatijn in een bestand (poorttest.c), en
compileer het met de magische woorden:

gcc -s -O3 -Wall -w -o poorttest poorttest.o

Hierna zou een "./poorttest 123" de byte 123 naar I/O-adres 0x310
moeten schrijven. Meer info vindt je in 1 v/d mini-HOWTO's.


Vriendelijke groeten vanwege

Pros (die ook al eens graag een bitje neukt :)


--- Sprot 1.0 #0001
 * Origin: Rivendel (2:292/8013.4)
=====================================================================REM_LINUX=


Omdat ik echter iemand ben die een voorliefde heeft voor assembler, heb ik dit C-Programma omgezet naar assembler (GNU as). Niet dat dit echte voordelen heeft, de koffie zal niet merkbaar sneller klaar zijn ;-)

Hieronder zie je de assembler versie.

===============================================================================
.globl main
    .type    main,@function
main:
        popl %ecx                # Hoeveel argumenten?
        cmpl $0x2, %ecx          # port nummer --> Steeds 2 argumenten nodig
        jne help                 # niet 2 --> geef help tekst
    
        popl %ecx                # skip argument 1 (= bestandsnaam prog)

        movl $101, %eax          # "ioperm" (system call = 101).
        movl $0x310, %ebx           
        movl $1, %ecx                
        movl $0x310, %edx
        int $0x80                # Vraag ioperm voor poort 0x310

        popl %ecx                # haal argument van stack : %ecx = nummer
    
        call atoi                # konverteer string (nummer) naar byte (%dl)
        movl %edx, %eax          # %al = nummer
        movw $0x310, %dx         # port 310(hex)
        outb %al, %dx
        
        jmp stop
    
help:   
        movl $gebruik, %ecx
        movl $9, %edx
        call print
    
        movl (%esp), %ecx         # ecx = argument 1 = naam programma
        movl $1, %edx
lus:
        cmpb $0, (%ecx) 
        je ok
        incl %edx
        incl %ecx
        jmp lus
ok: 
        popl %ecx
        call print
    
        movl $info, %ecx
        movl $26, %edx
        call print
stop:
        movl $1, %eax            # Exit
        movl $0, %ebx          
        int $0x80  

#------------------------------------------------------------------------------
print:      # Druk een string af
#------------------------------------------------------------------------------
# Ontvangt : %ecx = adres van de af te drukken string
#            %edx = lengte van de af te drukken string
#------------------------------------------------------------------------------
        movl $4, %eax            # nummer van syscall 'write()'
        movl $1, %ebx            # schrijf naar stdout
        int $0x80                # roep syscall aan
        ret
#------------------------------------------------------------------------------ 

#------------------------------------------------------------------------------ 
atoi:       # konverteer een string (0 ... 255) naar een getal. 
#------------------------------------------------------------------------------ 
# Ontvangt   : %ecx = adres van de te konverteren string
# Geef terug : %dl  = het getal      
#------------------------------------------------------------------------------ 
        xorl %eax, %eax
        xorl %ebx, %ebx

        movl %ecx, %edi
        incl %edi
        cmpb $0, (%edi)
        je l1
        incl %edi
        cmpb $0, (%edi)
        je l2
l3: 
        movb (%ecx), %dl
        subb $48, %dl
        movb $100, %al
        mulb %dl
        movl %eax, %ebx
        incl %ecx
l2: 
        movb (%ecx), %dl
        subb $48, %dl
        movb $10, %al
        mulb %dl
        incl %ecx
l1: 
        movb (%ecx), %dl
        subb $48, %dl
        addb %al, %dl
        addb %bl, %dl
        ret
#------------------------------------------------------------------------------     

.data
gebruik:
        .ascii "Gebruik: "
info:
        .ascii " <x>, waarbij x = 0...255\n"
=============================================================================== 
as port.s -o port.o
ld port.o -e main -o port

Zo, dit was het dan. Nu ga ik rustig een taske koffie drinken ;-)


Meer informatie over het maken van koffie met je PC vind je op http://www.tldp.org/HOWTO/mini/Coffee.html



Valid HTML 4.01!
Google