Forum: Ders Arası RSS
Windows 7 ile paralel port erişimi
Sayfa:  1  2  sonraki 
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Windows 7 ile paralel port erişimi
Bu windowsçuların çok basit şeyleri çok karmaşık yapmakta üstlerine yok. Şimdi basitçe Cin Ali tarzı basit paralel porta erişim sağlayan bir D programı yazmak istiyorum. Ubuntu tarafı bir kaç saniyelik iş..

Ama yeni bilgisayarımın grafik kartı için Intel Ubuntu için ekran kartı sürücüleri yayınlamadığı için tabiri caizse tırmalıyorum  :rolleyes:

Burada anlatılanlara göre Windows ortamında paralel porta erişmek için C ile bir aygıt sürücüsü yazmak gerekiyormuş. (WinDDK kullanarak) Eğer aygıt sürücüsünü diğer bilgisayarlarda ya da 64 bitte çalıştırmak için dijital imza içeren bir sertifika satın almak gerekiyormuş.

Neyse tam birilerinin böyle bir sürücüyü zaten yazdığını öğrendiğimde sevinmiştim ki (kullanımı da çok kolaydı) bu sürücü sadece XP ve 2000 altında çalışıyormuş. Windows 7'yi desteklemiyor.

Sonunda bu adreste giriş çıkış için başka bir sürücü buldum. Şimdi bu paketin içinde şu dosyalar var:

inpout32.lib
inpout32.h
inpout32.dll


inpout32.h dosyası da o kadar karışık sayılmaz.

#pragma once
 
//Functions exported from DLL.
//For easy inclusion is user projects.
//Original InpOut32 function support
void    _stdcall Out32(short PortAddress, short data);
short    _stdcall Inp32(short PortAddress);
 
//My extra functions for making life easy
BOOL    _stdcall IsInpOutDriverOpen()//Returns TRUE if the InpOut driver was opened successfully
BOOL    _stdcall IsXP64Bit();            //Returns TRUE if the OS is 64bit (x64) Windows.
 
//DLLPortIO function support
UCHAR   _stdcall DlPortReadPortUchar (USHORT port);
void    _stdcall DlPortWritePortUchar(USHORT port, UCHAR Value);

Tamam inpout.h için ilintileri yazdık diyelim. Ama benim anlamadığım nokta kütüphaneyi dinamik olarak mı yükleyeceğiz. Örneğin birisi  dll dosyalarını dinamik olarak yükleyen bir kod yazmış.

Bu kodu C ile yazılmış dll dosyalarını yüklemek için kullanabilirmiyiz. Yoksa Linux'ta *.a dosyalarını derleme sırasında belirttiğimiz gibi buradaki *.lib dosyasını kullanarak hiç dinamik olarak yüklemeden programımızı oluşturabilirmiydik.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
.lib'ler yeterlidir diye biliyorum.

Ali
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Şöyle iki tane dosya oluşturdum.

//io.d
 
extern(C)
{
    void    Out32(short PortAddress, short data);
    short   Inp32(short PortAddress);
}
// test.d 
 
import std.stdio;
import io;
 
// parallel port adresi
short port = 0x0378;
 
void main()
{
    /* veriler */
    short veri = 0b_00000000;
    Out32(port, veri);
}

dmd -c test.d io.d

ile derledim

link test.obj io.obj inpout32.lib

ile bağlamaya çalıştım. Ama Borland'ın coff2omf aracıyla uygun biçime çevirmeyi denememe rağmen bağlama başarılı olmadı.

OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
test.obj(test)
 Error 42: Symbol Undefined _Out32

Direkt olarak hiç değiştirmeden bağlamayı çalışınca da bu hatayı veriyor.

OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
inpout32.lib Offset 00000H Record Type 0021
 Error 138: Module or Dictionary corrupt
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Dosyalardaki 'symbol'ları görmek isterdim. Linux olsa:

$ nm falanca.o | grep Out32

Çıktısı isimnde Out32 geçen isimlerin o dosya ile ilişkisini gösterir.

Ali
erdem (Moderatör) #5
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Hımm. Şimdi bu makaleyi okuduktan sonra konunun detaylarını yavaş yavaş anlamaya başlıyorum.

Buna göre C ilintileri yazarken ilkönce derleme anında mı yoksa çalışma zamanında mı kütüphaneyi bağlayacağımıza karar vermemiz gerekiyor.  Derleme anında derken C kütüphanelerini ya da program parçalarını direkt olarak bağlamayı kasdediyoruz. Çalışma zamanı derken de paylaşımlı bir kütüphaneyi (dll, so vs..) gibi programın çalışması sırasında yüklemeyi kasdediyoruz. Burada bağlayıcı bir bağlama işlemi gerçekleştirmiyor.

Posix tabanlı sistemlerde D C ABI'den anladığı için bağlama işlemini kolaylıkla gerçekleştirebiliyoruz. Windows tarafında ise 4 tane farklı program parçacığı biçemi var: COFF, OMF, ELF. DMD (Burada program parçacığını object file anlamında kullandım. Ali bey böyle diyordu sanırım)

DMD oldukça eski bir bağlayıcı olan Optlink'i bağlayıcısını ve OMF kullanıyor. GDC'nin Windows uyarlaması MinGW ise ELF destekliyor. Microsoft Visual Studio ile gelen derleyici de COFF kullanıyor.

Elle DLL dosyalarını yüklediğimizde uygulamamız ile DLL arasındaki etkileşim sadece bellek düzeyinde oluyor.

Yok eğer derleme anında kütüphaneyi kullanmak istiyorsak program parçacığının biçemi burada bağlayıcının davranışını belirliyor. Eğer bağlayıcı program parçacığının biçimini tanımazsa, çalıştırılabilir bir dosya oluşmuyor. Bu durumda karşımıza şu seçenekler çıkıyor:

- C kütüphanesini D bağlayıcısının anlayabileceği biçimde program parçaları oluşturabilen bir derleyici ile derlemek.

- Program parçalarını uygun biçime çevirmek için bir dönüştürücü araç kullanmak.

- Bir DLL'nin içinden bağlayıcı kütüphane oluşturabilen bir program kullanmak.
Bu mesaj erdem tarafından değiştirildi; zaman: 2012-08-13, 14:14.
Değişiklik nedeni: Microsoft Visual Studio ile gelen derleyici de COFF kullanıyor.
erdem (Moderatör) #6
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sonunda Borland'ın implib aracını kullanarak bağlama işlemi başarılı oldu. Sorun sanırım program parçacıklarındaki işlevlerde _ olmamasından kaynaklanıyormuş.

implib -a inpout32.lib inpout32.dll

komutuyla DLL dosyasından bir *.lib dosyası oluşturdum. Daha sonra bağlayıcıyı çalıştırdım.

link test.obj io.obj inpout32.lib

ve program sorunsuz şekilde oluştu. Ancak programı normal şekilde çalıştırınca erişim hataları verdi.

object.Error: Access Violation
40BEEC
40BD77
40255A
40217B
411949

Ama yönetici olarak Runas /user:Erdem test.exe olarak çalıştırdığımda sorunsuz çalışıyor. Hatta delikli deneme kartı üzerinde devreyi kurarak da denedim.

Gene de Windows 7'nin acaba konsoldan çalışan ve portlara erişim sağlayan tüm programları bu şekilde mi çalıştırıyor, yoksa programı oluştururken derleme anında kütüphaneleri bağladığımızdan mı kaynaklanıyor emin olamadım. Daha sonra çalışma zamanında paylaşımlı kütüphaneyi yükleyerek denemeyi düşünüyorum.
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ben de bilmiyorum ama dmd'yi -g (belki de -gc) seçeneği ile derlersen 40BEEC gibi adreslerin yanında işlevlerin isimlerini de görebilirsin. (Umarım. :))

Ali
erdem (Moderatör) #8
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Ben de bilmiyorum ama dmd'yi -g (belki de -gc) seçeneği ile derlersen 40BEEC gibi adreslerin yanında işlevlerin isimlerini de görebilirsin. (Umarım. :))

İyi ki de bilmiyorsunuz!  :-D

Bir de bilseydiniz ne olacaktı bilmiyorum.

Tahmin edin dmd'ye -g seçeneği ekledikten sonra ne oldu. Program yönetici olarak çalıştırmaya gerek kalmadan basitçe test.exe diyerek çalışıyor.

Çok teşekkürler! :)
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok saçma! -g yalnızca işlev, değişken, vs. isimlerini ekler. (?)

Ali
erdem (Moderatör) #10
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet dediğiniz gibi -g seçeneği hata ayıklama bilgisini ekliyor.

Ama konuyla alakası var mı bilmiyorum ama şöyle bir durum var. Vista ve sonrası sistemlerde UAC (User Account Control) diye bir özellik var. Ve programla gelen dosyalarla beraber bu izinleri vermek ve sürücüyü \Win32 klasörüne kopyalamak için bir uygulama var.

Şimdi ilk kez hiç üzerinde değişiklik yapılmamış inpout32.lib kütüphanesini kullandığımda sorunsuz olarak sürücüyü kopyaladı. Ama daha sonra bu dosyayı dmd'nin anladığı OMF biçimine çevirince şu şekilde bir hata verdi:

[Resim: http://farm8.staticflickr.com/7260/7551850608_49a1c017be.jpg]

Derlerken -g seçeneğini kaldırınca gene erişim hatası veriyor.

Ya da ek olarak işlev, değişken isimlerini eklediğimiz zaman, DLL dosyasından oluşturduğumuz kütüphane dosyası ve program parçaları birbirine uyumlu hale gelmiş mi oldu acaba . Çünkü program parçalarını (object file) dmd ile oluşturduk ama kütüphane dosyalarını oluştururken Borland'ın implib aracından faydalandık. Belki Borland'ın yaptığı bağlayıcı işlev ve değişken isimlerinin de program parçalarına eklenmesini istiyor olabilir. En azından bana en mantıklısı bu geliyor  ;-)

Bir de ilk kez C ilintisi için örnek verdiğinizde sanki bu debug bilgilerinin faydalı olabileceğinden bahsettiğinizi hayal meyal hatırlar gibiyim. Gene de emin değilim.

@ek : Hımm.. Şimdi baktığımda sadece gcc'ye -m32 bayrağını eklemeyi tavsiye etmişsiniz.

Sonuç olarak süper bir çözüm olmuş oldu. Devre üzerinde de denedim. Gayet güzel çalışıyor! Teşekkürler  :-)
Bu mesaj erdem tarafından değiştirildi; zaman: 2012-07-11, 14:54.
erdem (Moderatör) #11
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İlk denemeleri oluşturmaya başladım. Ama programın taşınabilir olması, hem Linux hem de Windows tarafında çalışabilmesi için şu şekilde yazdım. Sizce nasıl fikir.
// giriscikis.d
 
version (linux) {
    import core.bitop;
    alias outp yaz;
    alias inp oku;
    alias ioperm erişimhakları;
    
    extern (C) int ioperm (uint __from, uint __num, int __turn_on) ;
}
 
version (Windows) {
    alias Out32 yaz;
    alias Inp32 oku;
    
    extern (C) {
        void    Out32(short PortAddress, short data);
        short   Inp32(short PortAddress);
    }
}
Hatta düşününce belki buradaki adres tanımlamaları da giriş çıkış dosyasına gidebilirmiş. Çünkü paralel portun adresi kullanıcının değiştirebileceği bir değişken değil.
// ledyak.d
 
import std.stdio;
import giriscikis;
 
void main()
{
    version (linux) {
        /*
            paralel portun adresi 
        */
        const uint adres = 0x0c000;
        /* 
            göndereceğimiz veri 
        */
        ubyte veri = 0b_11111111;
        erişimhakları(adres, 1, 1);
    }
    
    version (Windows) {
        /*
        paralel portun adresi 
        */
        short adres = 0x0378;
        /* 
            göndereceğimiz veri 
        */
        short veri = 0b_00001010;
    }
    
    yaz (adres, veri);
}
Bu mesaj erdem tarafından değiştirildi; zaman: 2012-07-12, 11:54.
Değişiklik nedeni: kodu değiştirdim
acehreli (Moderatör) #12
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Mantıklı. Paralel portun adresi sabit mi gerçekten? İki tane de olabilir. Hatta BIOS'ta ayarlanabiliyor muydu?

Ali
erdem (Moderatör) #13
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Windows'ta sabit genelde 0x0378 oluyor galiba. Linux'ta ise emin değilim.

$ dmesg | grep parallel

ile paralel port adresini öğrenebiliyorduk. Sizin de bahsettiğiniz gibi BIOS'tan da değiştirilebiliyor diye biliyorum.
zafer #14
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Erdem, konuyu merakla takip ediyorum. Bu konular hoşumada gidiyor katkı sağlamakta istiyorum ama cahilligimi maruz görürsen bu son kodlar tam olarak ne yapıyor. Bu kodlar bir devre üzerinde mi çalışıyor?
https://github.com/zafer06 - depo
erdem (Moderatör) #15
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet Zafercim aynen öyle.

Burada daha ayrıntılı anlatmıştım ama basitçe yaptığı delikli deneme kartı (breadboard) üzerinde bulunan 4 tane ledi yakıyor. Aslında burada ledleri yakan program da çok basit:

yaz (adres, veri);

Yani paralel porta istediğimiz veriyi yazıyor. Örneğin veri = 0b_00001111; ise sadece ilk 4 ledi yakıyor.

Buna elektroniğin Merhaba Dünya! programı diyebiliriz  :-)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-21, 15:20:59 (UTC -08:00)