Linux'ta seri port programlama biraz karışık iş aslında. bilinen HOWTO'lar seri programlamadan ziyade, xTY I/O meselelerini anlatıyor. Ama bir hayli eksik anlatıyor. Gerçi çoğu zaman bu yeterli oluyor zaten.
Bu hususu daha iyi anlamakta fayda var. Öncelikle ne nasıl oluyor? En altta bir donanım var. Mesela bildiğimiz UART. Yani seri iletim donanımı. Bu donanım olayın kalbi. Fakat siz bu donanımla doğrudan (yani xTY haliyle) uğraşamazsınız. Zira linux onu alır, bir TTY'ye çevirir. Donanım ile doğrudan alakadar olan kernelin kendisi. Fakat donanımdan gelen/giden veriler "line discipline" denen bir katmana gelir. Bu katmanda da işlenir. Bu katman ne yapar? Örneğin sizin yollamak istediğini "LF" lerin ardına "CR" ekler. Gelen CR leri "LF" ye çevirir, "TAB" ları 8 boşluğa çevirir vs. vs. Bu durum eski aptal terminal devrinde çok anlamlı bir şeydi elbette. Terminalin enter tuşu atıyorum WISE terminalde ASCII 13 yollarken, ALTOS terminalde 25 Yollardı mesela. Bunların doğru satır sonu işaretine, LF'ye çevrilmesi gerekirdi. İşte Line Discipline denen şey bunu sağlar. Bu ise, sizin aurdino'ya göndereceğiniz veriler o line discipline sürücüsünden geçecek. Onun siizn yolladığınız verileri kafasına göre değiştirmemesi için bir şeyler yapmalısınız. Bunun en basit yolu, seri portu, daha doğrusu TTY'yi "raw" hale getirmektir: cfmakeraw(). Diğer yandna ihtyiacınıza göre kendiniz Line discipline modüllleri yazıp kullanabilirsiniz. Örneğin N_PPP, N_SLIP, N_KISS gibi modüller mevcut. Varsayılan line discipline "N_TTY" ki bu da aptal terminal I/O olduğunu farzeder kablonun ucunda. Peki neden Line discipline yazmak gereksin? Bunun gereği zorunluluğu yok elbette. Fakat N_TTY bazı şeyleri göz ardı eder. Örneğin, sizin yazma işleminin bittiğini anlama imkanınız yoktur. Sizin write() çağrınız hemen geri döner, N_TTY onu arabelleğe alır ve gönderir usul usul. Bu da bazen sıkıntılara sebep olur. Benzer şekilde bazen alttaki donanıma doğrudan erişmek gerekebilir. Bu mümkün değildir aslen, zira sizin her çağrınız Line discipline gider. Ama onlar bazı çağrıları serbest bırakır. Bu da ioctl() kullanarak donanım bazlı bir şeyler yapabileceğiniz anlamına gelir. Mesela ioctl(fd, TIOCMGET, &controlbits); controlbits |= TIOCM_RTS; ioctl(fd, TIOCMSET, &controlbits); gibisinden, seri portun RTS ayağını elle kontrol edebilrsiniz. Mesela, seri prottan çalışan bir PIC programlayıcı yapıyorsanız, bu olmazsa olmaz olacaktır. Ama o kadar uzağa gitmeden, DCD hattına bakmak çoğu zaman modemin bağlı olup olmadığını anlamanın en güvenli yolu olacaktır. Şimdi toparlarsak. Öncelikle TTY çağrılarını, yani o tcsetattr vs. gibi termios şeylerini anlamanız gerekiyor. Bu yetmediği durumda, ya line discipline yazmanız veya mümkünse dar bir çerçevede de olsa hardware erişimi (gibi bir şey) sunan IOCTL'lere bakmanız gerekiyor. Seri iletişimde sürprizler yaşamamak için bunları öncelike hazmetmeye çalışın. Tevsiye edilen POSIX (uygulama) seviyesi dökümanları yanında, http://www.linux.it/~rubini/docs/serial/serial.html /usr/src/hede/..../kernel/Documentation/tty.txt gibi kernel seviyesi dökümanları okumanız faydalı olacaktır. 2011/5/3 Erdem ARTAN <[email protected]> > > > Merhaba, > > Python'da USB arayüzü üzerinden /dev/ttyACM0 noktasına bağlanan bir > donanıma (Arduino UNO), basit bir şekilde aşağıdaki yöntemle veri > gönderebiliyordum: > > from serial import * > s = Serial('/dev/ttyACM0',9600) > s.write("4") > > > Fakat bunu C dilinde nasıl yapabileceğimi tam olarak bulamadım. > > > Erdem Artan > > > _______________________________________________ > Linux-programlama mailing list > [email protected] > https://liste.linux.org.tr/mailman/listinfo/linux-programlama > Liste kurallari: http://liste.linux.org.tr/kurallar.php > >
_______________________________________________ Linux-programlama mailing list [email protected] https://liste.linux.org.tr/mailman/listinfo/linux-programlama Liste kurallari: http://liste.linux.org.tr/kurallar.php
