6018|9

81

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求助:嵌入式Linux下如何控制GPIO [复制链接]

1.我买了一块基于ARM9的EP9315开发板,但是没有买JTAG仿真器,请问不用仿真器怎样调试和运行测试程序?是不是一定要有仿真器才行?
2.交叉编译一个控制ARM9的GPIO的程序,开发板上已经有Linux操作系统,但是在板子上运行时出现如下错误:
pc : [<000084a4>] lr : [<00008608>] Not tainted
sp : bffffe24 ip : bffffe38 fp : bffffe34
r10: 40127c98 r9 : 00008564 r8 : 00000001
r7 : 4000b040 r6 : 000082c4 r5 : bffffe84 r4 : 4001c720
r3 : 00000003 r2 : 00000003 r1 : 40129940 r0 : ffffffff
Flags: nZCv IRQs on FIQs on Mode USER_32 Segment user
Control: C000717F Table: 00AC0000 DAC: 00000015
Segmentation fault
我的程序代码是:
//程序控制GPIOE0(GRLED)和GPIOE1(RDLED)连接的红绿灯闪烁
#include
#include
#include
#include
#include
#include

//定义GPIOE端口地址
#define GPIO_BASE 0x80840020
#define rPEDR 0x00000000 //E口数据寄存器
#define rPEDDR 0x00000004 //E口数据方向寄存器

volatile unsigned int *PEDR,*PEDDR;
static void Delay() //延时函数
{
int j;
for(j=0;j<0xffff;j++)
;
}
void Display() //显示函数
{
int h;
*PEDDR=0x3 ; //初始化GPIO,设置方向为出
for(h=0;h<10;h++)
{
*PEDR=0x1;
Delay();
printf("Now,Green Light\n");
*PEDR=0x2;
Delay();
printf("Now,Red Light\n");
*PEDR=0x0;
printf("Now,No Light\n");
Delay();
*PEDR=0x3;
printf("Now,both Light\n");
}
printf("It's done\n");
}

int main()
{
int gpio_fd;
unsigned char *gpio_map;
gpio_fd =open("/dev/mem",O_RDWR);
if (gpio_fd == -1)
{
printf("can't open /dev/mem.\n");
}
gpio_map = (unsigned char *)mmap(NULL, 0x30,PROT_READ | PROT_WRITE, MAP_SHARED,gpio_fd, GPIO_BASE);
PEDR = (volatile unsigned int *) (gpio_map+rPEDR);
PEDDR = (volatile unsigned int *) (gpio_map+rPEDDR);
Display();
if (gpio_fd != 0x0)
{
close(gpio_fd);
}
printf("GPIO Control Test end\n");
return 0;
}
我一直困惑不知道为什么?求助各位,是不是嵌入式Linux不能直接控制硬件,进行地址映射后也不行吗?
我是菜鸟,由于这块开发板资料少得可怜,真心向各位求助,不甚感激!


最新回复

我也遇到相同的问题,我试过了,mmap貌似只能map片外的物理地址,我的gpio寄存器是片内的,所以在mmap的一步,返回的是NULL,你以为正确,事实上已经失败了。你应该在map_base=mmap(0,0xff,PROT_READ|PROT_WRITE,MAP_SHARED,fd,GPIO_BASE); 后面加上: if( (map_base == MAP_FAILED) ||(map_base == NULL)) { printf("Error, can not get the mapping address of 0x%x\n", GPIO0_OR); return -1; } 我相信,你肯定打出了error,所以我觉得有2中可能,mmap可以定义地址段,某个参数可以map片内地址,第二就是用驱动了。这样麻烦一些。  详情 回复 发表于 2009-5-31 13:53
点赞 关注

回复
举报

74

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
1。嵌入式的系统调试和一般的应用开发是不同的。一般是从串口打LOG出去。来进行调试的,加断点一系列的手段,一般是不用的。
2LINUX肯定是支持直接控制硬件的,但是一你定义的地址对吗?二从报错的信息看CPU的工作模式好像也有问题
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
不懂,up
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

4
 
不懂,up
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
我不太清楚你所说的工作模式是应该设置成什么。我没有仿真器,把我交叉编译的程序通过TFTP的方式传到开发板的linux上运行就报错了。你说的linux可以直接操作硬件是怎么操作的,我的意思是不写驱动直接从应用层写程序控制,因为项目紧张但是我对linux内核和驱动开发还不了解,现在想写不涉及驱动的程序去测试下我们刚制作的开发板;另外如果没有操作系统在ADS下写测试程序怎样让板子运行?真的不知道怎么弄,还请高手说得再详细点,不甚感激。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

6
 
这个需要按linux的驱动模型来做吧,原则上linux是不允许在应用程序中直接访问硬件的,每个进程都有自己独立的虚拟地址空间。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

7
 
用mmap是可以在用户空间读写控制硬件设备的。
你的程序在结构上没问题,那就要确认对应的地址GPIO_BASE是否正确。

给个参考程序看看
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include

  7. void * map_base;
  8. FILE *f;
  9. int n,fd;

  10. int main(int argc,char *argv[])
  11. {
  12.     if((fd=open("/dev/mem",O_RDWR|O_SYNC))==-1){
  13.     return(-1);
  14.     }

  15.     map_base=mmap(0,0xff,PROT_READ|PROT_WRITE,MAP_SHARED,fd,GPIO_BASE);
  16.    PEDR = (volatile unsigned int *) (map_base+rPEDR);
  17.    PEDDR = (volatile unsigned int *) (map_base+rPEDDR);

  18.     PEDR = 0x03; //E0 E1配成输出

  19.     while(1){
  20.         PEDR = (1<<0);//E0置高
  21.          sleep(1);
  22.         PEDR &= !(1<<0);//E0口置低
  23.          sleep(1);
  24.     }
  25.     close(fd);
  26.     munmap(map_base,0xff);//解除映射关系
  27. }
复制代码
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(初级)

8
 
这个调试应该很简单:
先写个空main,只printf一行字,运行,看看是否正常。
然后加入fd=open.....,运行。
再加入addr=mmap(...),运行。
最终再加入对addr的操作。

这样很快能找到出问题的地方。
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

9
 
我按照的说的调试方法试过了,一直到地址映射时程序都正确,但是对方向寄存器赋值*PEDR = 0x03,以及后面对数据寄存器赋值处就出错了,是不是赋值方法有问题还是什么别的原因?
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

10
 
我也遇到相同的问题,我试过了,mmap貌似只能map片外的物理地址,我的gpio寄存器是片内的,所以在mmap的一步,返回的是NULL,你以为正确,事实上已经失败了。你应该在map_base=mmap(0,0xff,PROT_READ|PROT_WRITE,MAP_SHARED,fd,GPIO_BASE);
后面加上:
if( (map_base == MAP_FAILED) ||(map_base == NULL))
{
printf("Error, can not get the mapping address of 0x%x\n", GPIO0_OR);
return -1;
}

我相信,你肯定打出了error,所以我觉得有2中可能,mmap可以定义地址段,某个参数可以map片内地址,第二就是用驱动了。这样麻烦一些。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表