June 12, 2010

Embedded Linux Picture Frame!

Filed under: Embedded Linux — Tags: , , , , , , — admin @ 10:53 pm

Hi,

In this article, I will talk about how to control IO ports using Embedded Linux platforms.

The platform which is used in this project is a edb9302 compliant development board. It has 16 MB Intel strata flash and 32 MB SD RAM, gpio connection in order to communicate custom design interfaces, for information about the development board, can be looked at this link;

http://www.cirrus.com/en/products/pro/detail/P1066.html

Briefly in this project , i have connected a elt240320atp LCD screen to the embedded Linux development board with a parallel gpio interface.

An interface software is written, in order to create communication between the embedded Linux development board and the elt240320atp LCD screen.

Let’s take a look interface software.

The program is designed to communicate with lcd screen can be split into two parts, gpio controller and elt240320atp lcd screen controller.

All right, how to open GPIO interface without using a device driver in a Embedded Linux platform?
Answer, using /dev/mem device.

/dev/mem device is a king of character device is used to access to physical memory via generic file manipulation system calls, for example; open, read, write, seek, close, etc.

As can be seen in the code snipe,

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	iofd = open("/dev/mem", O_RDWR | O_SYNC);
	if (iofd == -1) {
		fprintf(stderr ,"\n%s\n", "Cannot open /dev/mem device!");
		return(errno);
	}
 
	ptrregisterbase = (unsigned char *) mmap(0, getpagesize(), PROT_READ|PROT_WRITE, \
					MAP_SHARED, iofd, 0x80840000 );
 
	ptrconfigbase   = (unsigned char *) mmap(0, getpagesize(), PROT_READ|PROT_WRITE, \
					MAP_SHARED, iofd, 0x80930000 );
 
	porta_dr  = ptrregisterbase+0x00;/*data register*/
	porta_ddr = ptrregisterbase+0x10;/*data direction register*/
 
	portb_dr  = ptrregisterbase+0x04;
	portb_ddr = ptrregisterbase+0x14;

In the code snipe above; main.c:line 64, /dev/mem device is opened as a character device. In case of cache mechanism of the MMU, O_SYNC is used in order not the MMU to cache the written data.

In the line 70 and 73, mmap function is used in order to map the file descriptor which is obtained by open function to the pointer to a integer.

EP9302-ELT240320ATP

figure.1: EP9302 - ELT240320ATP connection

As can be seen in the figure.1 sbc and lcd connected with each other.

ELT240320ATP

figure.2: ELT240320ATP, 320x240 TFT LCD

A picture is printed on the screen of the lcd, top left text is also printed as courier font.

Whole project code and pictures can be downloaded here.

Any kind of feedback or question is accepted gratefully.

Best Regards.

bolatdinc at gmail.com

4 Comments »

  1. Bolat Bey Selamlar,

    Öncelikle siteniz uygulamaya ve geliştrime çalışmalarına çok yardımcı olabilecek bir şekilde hazırlanmış.

    Özellikle arm linux üzerine çalışıyor ve uygulama üretiyor olmanız ayrı bir şans benim için.

    Eğer ilgilenirseniz ve fazla vaktinizi almazsam bir sorum olacak;

    Kullanmış olduğum aşağıdaki board:

    http://www.olimex.com/dev/pdf/ARM/CIRRUS/CS-E9302.pdf

    sizin örneğinizdeki board ile sanırım aynı.

    Benim sıkıntım ep 9302 üzerindeki 32MB sdram ‘e ulaşamamak.

    Özellikle 0xC0000000, 0xD0000000, 0x0E0000000 adres base li SDRAM blocklarına ulaşmak istediğimde segmentation fault hatası alıyorum.

    Şöyle ki; örneğin

    fd = open(“/dev/mem”, O_RDWR );
    if (fd == -1) {
    fprintf(stderr ,”\n%s\n”, “Cannot open /dev/mem device!”);
    return(errno);
    }

    sdrambase = (unsigned char *) mmap(0, getpagesize(), PROT_READ|PROT_WRITE, \
    MAP_SHARED, fd, 0xc0000000 );

    şelinde dediğimde sdrambase pointerını kullanmaya çalıştığımda segmentation fault hatası alıyorum.

    örneğin *sdrambase=0x323; demem segmentation fault hatasına neden oluyor.

    GPIO lar için yaptığım uygulamalar çalışıyor. Bu şekilde elde ettiğim pointerlara değer atabiliyorum. (ancak tabi gpio içim mmap ten dönen pointerlar registerlara bakarken burada sdram adreslerine işaret ediyor ve belki bu da bir problem oluşturabilir diye düşünüyorum.Siz ne dersiniz)

    Sanırım SDRAM e ulaşmak içim open ve mmap komutlarını kullanmak yeterli, initialize etmek için daha “low level” bir şeyler yapmaya gerek var mı?

    Bu konuda internetten de malesef pek somut bir bilgiye ulaşamadım. Yardımcı olursanız minnettar kalırım.

    teşekkür ederim / murat.

    Comment by murat karahan — December 8, 2010 @ 2:45 am

  2. Murat bey merhaba,

    Iletmis oldugunuz soru oldukca spesifik, elimden geldigince yardimci olmaya calisayim.

    http://www.cirrus.com/en/pubs/manual/EP93xx_Users_Guide_UM1.pdf linkinde, Sayfa:13-9 da bulunan, “13.8.1 Chip Select SDCSN[3:0] Decoding” kismini bir inceleyin
    Ardindan gine ayni dokumandaki sayfa 2-16 ile 2-32 arasini inceleyin orada memory mapped accessible register maplar goreceksiniz.

    EP9302 islemcilerinde (ARM920T) MMU bulundugundan ve Linux kerneli bu MMU uzerinde calisitigindan MMU sizin Dinamik Bellek (SDRAM) uzerinde islem yapmaniza izin vermeyecektir. Bunun pekcok nedeni vardir baslicasi, boot asamasinda Linux kernel imaji, zImage, uImage vs, kendisini extract ettikten sonra text section ini (linux imajinin calistirilabilir bolgesi) bu bellek alanina kopyalar, ve dolayisi ile kernel kendisinin calistigi bolgeyi MMU ile koruma altina alir. Ayrica MMU tarafindan page edilmis bir bolgedeki proccess erisim hakki olmayan baska bir page e ulasmaya calisirsa, MMU icsel bir kesme olusturarak islemciyi belirli bir adrese dallandirir. Bu da Linux kerneli uzerinde calisan proces lerde genellikle “Segmentation Fault” seklinde kendini gosterir.

    Sayet yapmak istediginiz konu hakkinda daha detayli bilgi veriseniz. Belki daha uygun bir yol bulunabilir.

    Saygilarimla

    Comment by admin — December 8, 2010 @ 8:55 am

  3. Bolat Bey Tekrar Selamlar,

    Gerçek zamanlı bir kontrol algoritması çalıştırmak kullanacağım matrisleri tutmak için external olarak CS 9302 üzerindeki external SDRAM ve Nor Flash belleklere ulaşmak istiyorum.

    En azından dün externallar için olan adreslere özellikle SDRAM için 0xF0000000 ve Nor Flash için 0x60000000 baselerinden başlamak üzere pointer değerlerini mmap ile istedim. Segmentation fault hatası artık almıyorum. Ancak bu sefer de mmap ten dönen pointerlara herhangi bir şey yazamıyorum.

    Şöyleki;

    sdram_add_point = mmap (…,0xF000000);

    *sdram_add_point=0x01;

    ikinci satırdaki sdram_add_point içeriğine

    print(“%u”,*sdram_add_point); şeklinde bastırdığımda çok farklı değerler görüyorum.

    Malesef CS 9302 üzerindeki sdram ya da nor flasha bir şeyler yazmak ya da okumak ile ilgili malesef internette hiç bir şey bulamıyorum.

    Yardımlarınız için teşekkür ederim.

    Murat

    Comment by murat karahan — December 9, 2010 @ 2:17 am

  4. Murat bey merhaba,

    Bu konuda size tavsiyem SDRAM a direk pointerlar ile erismek yerine bunu yapacak bir kernel modulu yazmaniz bu kernel modulune /dev yada /proc file system ile erismeniz. Sayet Real-time proccess iniz sadece kernel spacede calisiyorsa o zaman uygulamanizi elf yerine yerine direk kernel modulu olarak yazabilirsiniz. Bunun icin module_init fonksiyonunu programinizin entry point i olarak (normal elf de main fonksiyonu yerine) kullanabilirsiniz. Ayrica kernel space de de malloc ve turevi dinamik bellek fonksiyonlarinin kmalloc gibi karsiliklari mevcuttur.
    NOR flash bellege ulasmak istiyorsaniz da uzerinde bir mtd partitionu yaratip jffs2 seklinde bicimlendirmeniz erisiminizi mumkun kilacaktir. Karttaki NOR flash (Intel STRATA flash) protection mekanizmasina sahip oldugundan, simdiye kadar bu bolgeye direk olarak bootloader yada JTAG arayuzu ile erisebildim. Bundan dolayi MTD ve JFFS2 iyi bir cozum olacaktir.

    Calistiginiz konu ile alakali olarak olarak “Tornado and VxWorks, Christof Wehner” kitabini tavsiye ederim.

    Saygilarimla

    Comment by admin — December 9, 2010 @ 7:07 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress