BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / embedded-system / #10499同步于 2011/4/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Embedded_System机器人发帖

【又一问题】ARM mini2440板子寄存器读写问题

jay1
2011/4/21镜像同步12 回复
在编写GPIO驱动程序mini2440_gpios.c中,想控制GPF IO的模式(input&output)和读其接口的数据,利用如下语句: #define GPGCON (*(volatile unsigned long *)0x56000060) #define GPGDAT (*(volatile unsigned long *)0x56000064) 【(地址是查的S3C2440的芯片手册,如下图) 】 …… GPGCON = 0;(根据数据手册定义是将GPF口全部设置为input模式) …… 驱动程序调试通过,没有错误。 然后写了一个简单的测试程序gpios_test.c,编译后运行,在执行到GPGCON = 0 ;这个语句就过不去, 系统提示: Unable to handle kernel paging request at virtual address 56000060 pgd = c33f0000 [56000060] *pgd=00000000 Internal error:Oops:5 [#1] Modules linked in mini2440_gpios mini2440_backlight CPU : 0 PC is at mini2440_gpios_open+0x14/0x3c [mini2440_gpios] …… 我实在是搞不明白,只能用内部接口函数s3c2410_gpio_cfgpin()进行端口配置,但是一次只能配置一位,十分不方便,恳请高手赐教!!!不甚感谢!! [ema41]
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
ArmStrong机器人#1 · 2011/4/21
对地址不能这样读 用IOADDRESS()或者p2v()转化一下那个地址 这两个宏在头文件里都可以找得到 【 在 jay1 (黑色幽默) 的大作中提到: 】 : 在编写GPIO驱动程序mini2440_gpios.c中,想控制GPF IO的模式(input&output)和读其接口的数据,利用如下语句: : #define GPGCON (*(volatile unsigned long *)0x56000060) : #define GPGDAT (*(volatile unsigned long *)0x56000064) : ...................
jay1机器人#2 · 2011/4/21
这两个函数我百度了下好像没有什么资料。。。。这个函数具体是在哪个头文件?我调用的是以下几个。。。 #include <linux/module.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <asm/uaccess.h> #include <asm/arch/regs-gpio.h> #include <asm/hardware.h> 我刚开始学。。。实在很菜。。。能不能说具体一点?拜托了! 【 在 ArmStrong 的大作中提到: 】 : 对地址不能这样读 : 用IOADDRESS()或者p2v()转化一下那个地址 : 这两个宏在头文件里都可以找得到 : ...................
jay1机器人#3 · 2011/4/21
我查找了我调用的几个头文件里,没有找到IOADDRESS()。。。 【 在 ArmStrong 的大作中提到: 】 : 对地址不能这样读 : 用IOADDRESS()或者p2v()转化一下那个地址 : 这两个宏在头文件里都可以找得到 : ...................
ArmStrong机器人#4 · 2011/4/22
就是说不能直接对物理地址进行读写,要转化成虚拟地址,具体怎么转化可以参考内核里的其它代码,肯定会有很多这样的操作的 【 在 jay1 (黑色幽默) 的大作中提到: 】 : 我查找了我调用的几个头文件里,没有找到IOADDRESS()。。。
jay1机器人#5 · 2011/4/22
我找到了!!是ioremap函数,在ADC的驱动中有 static void __iomem *base_addr; base_addr=ioremap(S3C2410_PA_ADC,0x20); if (base_addr == NULL) { printk(KERN_ERR "Failed to remap register block\n"); return -ENOMEM; } 太感谢你了!!!!! 【 在 ArmStrong 的大作中提到: 】 : 就是说不能直接对物理地址进行读写,要转化成虚拟地址,具体怎么转化可以参考内核里的其它代码,肯定会有很多这样的操作的 : 【 在 jay1 (黑色幽默) 的大作中提到: 】 : : 我查找了我调用的几个头文件里,没有找到IOADDRESS()。。。 : ...................
jay1机器人#6 · 2011/4/22
这里还有一个问题,ADC驱动中有如下代码 static void __iomem *base_addr; #define ADCCON (*(volatile unsigned long *)(base_addr + S3C2410_ADCCON)) //ADC control #define ADCTSC (*(volatile unsigned long *)(base_addr + S3C2410_ADCTSC)) //ADC touch screen control #define ADCDLY (*(volatile unsigned long *)(base_addr + S3C2410_ADCDLY)) //ADC start or Interval Delay #define ADCDAT0 (*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT0)) //ADC conversion data 0 #define ADCDAT1 (*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT1)) //ADC conversion data 1 #define ADCUPDN (*(volatile unsigned long *)(base_addr + 0x14)) //Stylus Up/Down interrupt status 但是我在GPIO中用 #define GPIODAT (*(volatile unsigned long *)(base_addr + S3C2410_GPGDAT)) 在编译驱动程序时会报错 error:invalid operands to binary + 然后无法直接对寄存器操作,只能通过ioread32(base_addr)来读。。。 求解释!先谢过了!! PS;我还以为少添加了头文件,我把ADC驱动的所有头文件都添加进来,结果还是报错。。无奈了。。 【 在 ArmStrong 的大作中提到: 】 : 就是说不能直接对物理地址进行读写,要转化成虚拟地址,具体怎么转化可以参考内核里的其它代码,肯定会有很多这样的操作的 : 【 在 jay1 (黑色幽默) 的大作中提到: 】 : : 我查找了我调用的几个头文件里,没有找到IOADDRESS()。。。 : ...................
susanbear机器人#7 · 2011/4/22
可以把每个你想操作的物理端口地址都ioremap一次试试.... 对寄存器进行读操作用ioread(),写操作要用iowrite(),直接对寄存器进行操作是什么意思呢
ArmStrong机器人#8 · 2011/4/22
在你的文件里没有S3C2410_GPGDAT的定义吧 【 在 jay1 (黑色幽默) 的大作中提到: 】 : 这里还有一个问题,ADC驱动中有如下代码 : static void __iomem *base_addr; : #define ADCCON (*(volatile unsigned long *)(base_addr + S3C2410_ADCCON)) //ADC control : ...................
jay1机器人#9 · 2011/4/22
调用ioread和iowrite不是比较慢吗?是希望说像一个变量一样,直接可以进行读写赋值。 【 在 susanbear 的大作中提到: 】 : 可以把每个你想操作的物理端口地址都ioremap一次试试.... : 对寄存器进行读操作用ioread(),写操作要用iowrite(),直接对寄存器进行操作是什么意思呢 : -- : ...................