關於一個 GPIO的小程式 我沒辦法run..

我們生活周遭存在太多太多的 embedded system ,過去 embedded system 有專屬的 OS,現在 linux 也可以應用在嵌入式環境,不過本版將廣泛討論所有嵌入式系統不只 linux 喔,歡迎有這方面經驗或有興趣的朋友一同進來討論。

版主: chester

關於一個 GPIO的小程式 我沒辦法run..

文章rz600000 » 週一 9月 17, 2007 9:17 pm

代碼: 選擇全部
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<sys/mman.h>
#include<fcntl.h>
#include <asm/page.h>
#define ECS0_BASE 0x03F00000
#define IO_REG0                 (*(unsigned short *)(ECS0_BASE+0x0C00))
#define IO_REG2                 (*(unsigned short *)(ECS0_BASE+0x0C04))

int main(void)
{

        int gpio_fd;
        void * gpio_map;
        gpio_fd = open("/dev/mem",O_RDWR);
        gpio_map = mmap(NULL,PAGE_SIZE,PROT_WRITE, MAP_SHARED, gpio_fd,IO_REG2);

        while(1)
        {
                gpio_map = 0xffff;
        }

}




arm-linux-gcc -s -o testled chap06_1.c

之後丟到s3c2410 creator 上面run 會出現 segmentation fault

這只是想讓版子上面的LED 一直呈現 暗的狀態

我是新手 多包含...謝謝
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章rz600000 » 週一 9月 17, 2007 9:20 pm

對了 忘了說
1= off
0 =on


還有上面那個
IO_REG2 是 那個LED的 address
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章訪客 » 週一 9月 17, 2007 9:56 pm

mmap所回傳的是記憶體的address,
也就是你的gpio_map所存的是"/dev/mem"的記憶體起始位址,
所以你要使用指標來存取"/dev/mem"的這塊記憶體,
可以參考網路上的範例:
http://www.jollen.org/blog/2007/03/mmap_vma.html
http://blog.richliu.com/2006/10/17/369/
訪客
 

文章rz600000 » 週一 9月 17, 2007 11:10 pm

代碼: 選擇全部
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<sys/mman.h>
#include<fcntl.h>
#include <asm/page.h>
#define ECS0_BASE 0x03F00000
#define IO_REG2                 (unsigned short )(ECS0_BASE+0x0C04)

int main(void)
{

        int fd;
        void * fdp;
        fd = open("/dev/mem",O_RDWR);


        if(     (int )(fdp = mmap(0,1024, PROT_WRITE, MAP_SHARED, fd,IO_REG2)) == -1 )
        {
                printf("mmap failed!\n");
                return 0;
        }

}


...我改成這樣 我之前mmap 的 argu 錯了..
但是還是有mmap 錯誤

對了感謝上面那位大大~~~~
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章訪客 » 週二 9月 18, 2007 11:14 am

代碼: 選擇全部
        fd = open("/dev/mem",O_RDWR);
        if ( fd < 0 ) {
                printf("open file error\n");
                return 0;
        }


        if(     (int )(fdp = mmap(0,1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == -1 )
        {
                printf("mmap failed!\n");
                return 0;
        }
        return 0;



以上是我修改的code,可以在x86上執行。
使用時,要使用root權限去open /dev/mem,才能open成功

另外,mmap的原型為:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

所以,最後一個參數,應該是使用offset....
訪客
 

文章rz600000 » 週二 9月 18, 2007 2:11 pm

可是我要從 IO_REG2 的 位址開始map 我是開/dev/mem 的 IO_REG2 offset 的位置 開始 map 我在想想好了 謝啦
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章rz600000 » 週二 9月 18, 2007 2:20 pm

對了問一下
代碼: 選擇全部
#define IO_REG0                 (*(unsigned short *)(ECS0_BASE+0x0C00))


這段的意思 是說 先取出 ECSO_BASE+0x0c40的 data 再取什麼????這裡我不懂了

可以說一下上面那個define 的意思嗎 感恩
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章Franklin » 週二 9月 18, 2007 2:25 pm

unsigned short *ptr;

ptr = (unsigned short *)(ECS0_BASE+0x0C00);

IO_REG0 = *ptr;

拆成這樣有沒有比較好懂?
頭像
Franklin
懵懂的國中生
懵懂的國中生
 
文章: 171
註冊時間: 週五 6月 16, 2006 1:13 pm

try it

文章訪客 » 週三 9月 19, 2007 1:15 am

fd = open("/dev/mem",O_RDWR); 這行最好加 O_SYNC

fdp = mmap(0,1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) 這行改成

fdp = mmap(0,1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (ECS0_BASE+0x0C00));
這樣就mmap成功, 之後fdp就是(ECS0_BASE+0x0C00)的virtual address, 可供AP使用, 然後
*((unsigned short *)fdp) = 0xffff;
控制GPIO
訪客
 

文章rz600000 » 週三 9月 19, 2007 3:37 pm

謝謝上面那位大大

但是這個方法我試過 不行 我map (ECS0_BASE+0x0C00)
會mmap fail 但是要是我只 mmap ECS0_BASE 卻可以成功
這是為什麼?

還有若我mmap ECS0_BASE 之後用手動算出
我要 control 的 I/O address 這樣作還是失敗 該怎麼作??

麻煩各為了
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章lunatich » 週四 9月 20, 2007 10:58 am

rz600000 寫:謝謝上面那位大大

但是這個方法我試過 不行 我map (ECS0_BASE+0x0C00)
會mmap fail 但是要是我只 mmap ECS0_BASE 卻可以成功
這是為什麼?

還有若我mmap ECS0_BASE 之後用手動算出
我要 control 的 I/O address 這樣作還是失敗 該怎麼作??

麻煩各為了


mmap (ECS0_BASE+0x0C00)會mmap fail

但是mmap ECS0_BASE 可以成功可能跟分頁機制有關吧,

不太清楚,但是如果你 mmap ECS_BASE成功的話,

得到的位置加上0x0C00就是你想要的位置了
lunatich
可愛的小學生
可愛的小學生
 
文章: 2
註冊時間: 週四 9月 20, 2007 10:50 am

文章rz600000 » 週五 9月 21, 2007 12:12 am

上面那位大大 是說mmap base address之後 再加上我所要access的address(0x0c00)就可以得到我要的address (即base+0x0C00)

但因mmap回來的 fp = mmap(......) 的那個fp的type 是 void *

所以要先將(void *) fp cast 成 (unsigned char *) fp

才可以做+0x0c00的動作 ???是否這樣

因為我想先轉成 unsigned char * 是因為char 是佔一個byte 應該會跟我想要+0x0c00的adress是對齊的(即移動 0x0c00個byte)
這樣對嗎 ??

之後我得到那個address後再將(unsigned char*) cast 成(unsigned short*) 再作存取 因那個 I/O mem 是 2 byte (16bits) 的register 是這樣媽 謝謝......


問的問題有點冗長 感恩各位看完..謝謝 煩請幫忙.. :-D
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章lunatich » 週五 9月 21, 2007 12:03 pm

rz600000 寫:上面那位大大 是說mmap base address之後 再加上我所要access的address(0x0c00)就可以得到我要的address (即base+0x0C00)

但因mmap回來的 fp = mmap(......) 的那個fp的type 是 void *

所以要先將(void *) fp cast 成 (unsigned char *) fp

才可以做+0x0c00的動作 ???是否這樣

因為我想先轉成 unsigned char * 是因為char 是佔一個byte 應該會跟我想要+0x0c00的adress是對齊的(即移動 0x0c00個byte)
這樣對嗎 ??

之後我得到那個address後再將(unsigned char*) cast 成(unsigned short*) 再作存取 因那個 I/O mem 是 2 byte (16bits) 的register 是這樣媽 謝謝......


問的問題有點冗長 感恩各位看完..謝謝 煩請幫忙.. :-D


我試的情況是void不用cast成unsigned char, 它位移單位就是

byte了, 位址最後再丟給unsigned short的指標作存取, 如果不

放心可以把位址printf出來看, 做一下確認............

還有你mmap只要求1024byte大小不夠, 0x0C00 = 3072已經

超出範圍了
lunatich
可愛的小學生
可愛的小學生
 
文章: 2
註冊時間: 週四 9月 20, 2007 10:50 am

文章rz600000 » 週五 9月 21, 2007 2:14 pm

感恩 lunatich 跟 眾多的訪客 謝謝您們 :-D
rz600000
可愛的小學生
可愛的小學生
 
文章: 44
註冊時間: 週日 10月 22, 2006 10:18 pm

文章jackluli » 週三 4月 02, 2008 3:17 pm

小弟想問各位學長
不知道有什麼AP是可以測試x86的GPIO的in&out
我參考上面學長的CODE在x86執行會有錯誤
所以想問是否有這方面的程式可以測試
:-P
jackluli
可愛的小學生
可愛的小學生
 
文章: 49
註冊時間: 週一 3月 17, 2008 1:56 pm


回到 embedded system

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客