前一次发帖问的关于这个问题内容如下:
我用的是s3c2410的开发板,linux操作系统,我知道在arm下读写io要用/dev/port,但是 相应io的控制寄存器如何读写,是否也是用port文件,同样的方法?
下面直接读取的方法应该不行吧:
先用gpio(1-5)试试,这其中对应的引脚是GPG0、GPG1、GPG8、GPG9和GPG10,我是在linux下做开关量的采集。
控制寄存器 设置为: GPGCON &=(0xFFC0FFF0);0、1、8、9、10都设为输入状态
GPGUP也要设置 GPGUP=0x0;
这样设置就可以直接从 GPGDAT读数据。
在linux下设置的话,我直接在函数里写:
unsigned int *GPGCON=0x56000060; //0x56000060是GPGCON的地址
unsigned int *GPGUP=0x56000068; //0x56000068是GPGUP的地址
&GPGCON &=(0xFFC0FFF0);
&GPGUP =0x0;
是不是在linux下的物理地址都是映射为虚拟地址,是不是要读相应的虚拟地址,那是如何映射的?
帖的地址是 http://topic.eeworld.net/u/20080613/22/76c1285a-cfaa-4fb8-8ec7-534c8d5b6d55.html
那个帖子已经结了,我试了试ioremap函数,不过,这个函数只能在内核里用,我想用在应用程序下,所以我又试/dev/mem 文件和mmap函数,这段代码如下:
#define GPG 0x56000060
#define GPG_CON 0x0
#define GPG_UP 0x8
#define GPG_DAT 0x4
void * map_base;
int io_setting02()
{
//unsigned int GPGCON=0x56000060, GPGUP=0x56000068, GPGDAT=0x56000064;
int fd=-1;
if((fd=open("/dev/mem",O_RDWR|O_SYNC))==-1){
return(-1);
}
map_base=mmap(0, 0xff, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPG);
*(volatile unsigned int*)(map_base+GPG_CON)&=(0xFFC0FFF0); // 设置GPGCON
*(volatile unsigned int*)(map_base+GPG_UP)=0x0; //设置GPGUP
close(fd);
munmap(map_base,0xff);//解除映射关系
}
但是在开发板上运行出现下面的错误:
pc : [<000089b0>] lr : [<00008994>] Not tainted
sp : bffffe3c ip : bffffe34 fp : bffffe5c
r10: 400dc26c r9 : 00008db4 r8 : 00000001
r7 : 4001fe94 r6 : 0000862c r5 : bffffea4 r4 : 00000648
r3 : ffffffff r2 : ffffffff r1 : 0001107c r0 : ffffffff
Flags: nzCv IRQs on FIQs on Mode USER_32 Segment user
Control: 317F Table: 33234000 DAC: 00000015
Segmentation fault
现在不知道如何办了,请教下,这个读写io控制寄存器应该怎么做呢? 谢谢!
应用程序不允许直接操作内核空间的地址。
你应该在驱动层,暴露一个接口函数,供应用层open之后调用,以其返回值或者获得有效的地址,然后才可以操作。
或者直接在驱动里面设计好GPIO口的操作函数,比如配置功能,拉高拉低等,然后供应用层调用。
hh,shuiyan,你好,是不是我就只能谢驱动了啊,用/dev/mem文件 和 mmap函数做映射也不行啊
找到相关的s3c2410.h 了,决定试试这个先,有问题再来请教了