我想访问 GPIO4 寄存器的值。
方法一: 在user spacer 里,程序如下
int main(int argc,char **argv)
{
int fd;
unsigned int val;
void *g_addr_gp4=NULL;
fd=open("/dev/mem",O_RDWR|O_SYNC);
if(fd==-1){
printf("@E:open /dev/mem\n");
return -1;
}
g_addr_gp4=mmap(NULL,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0x48320000); //gpio4 register base address
if((!g_addr_gp4) ){
printf("@E:g_addr null\n");
return -1;
}
val=*(volatile unsigned int *)(g_addr_gp4+0x134); //panic here, the err info following:
printf("<GPIO4 OE> %x\n",val);
val=*(volatile unsigned int *)(g_addr_gp4+0x13C);
printf("<GPIO4 DATAOUT> %x\n",val);
}
Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6fe9138
[ 1453.345893] pgd = 527a1bff
[ 1453.345897] [b6fe9138] *pgd=99495831, *pte=48320303, *ppte=48320a33
[ 1453.345950] ————[ cut here ]————
[ 1453.368826] WARNING: CPU: 0 PID: 21 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x330/0x380
[ 1453.378089] 44000000.ocp:L3 Custom Error: MASTER M2 (64-bit) TARGET L4_PER_0 (Read): Data Access in User mode during Functional access
[ 1453.390224] Modules linked in:
[ 1453.393299] CPU: 0 PID: 21 Comm: irq/21-l3-app-i Not tainted 4.19.381-rt19-g1224cd679e #56
[ 1453.401597] Hardware name: Generic AM43 (Flattened Device Tree)
[ 1453.407540] Backtrace:
[ 1453.410010] [<c010c7f0>] (dump_backtrace) from [<c010cb60>] (show_stack+0x18/0x1c)
[ 1453.417613] r7:00000009 r6:00000000 r5:c09a916c r4:dc555e24
[ 1453.423315] [<c010cb48>] (show_stack) from [<c079c514>] (dump_stack+0x24/0x28)
[ 1453.430576] [<c079c4f0>] (dump_stack) from [<c012c73c>] (__warn+0xe0/0xf8)
[ 1453.437483] [<c012c65c>] (__warn) from [<c012c354>] (warn_slowpath_fmt+0x50/0x6c)
[ 1453.445000] r9:dc543240 r8:e2c00164 r7:c09a9098 r6:c09a9244 r5:c09a913c r4:c0c05888
[ 1453.452782] [<c012c308>] (warn_slowpath_fmt) from [<c03e16d8>] (l3_interrupt_handler+0x330/0x380)
[ 1453.461692] r3:dc53f940 r2:c09a913c
[ 1453.465281] r5:00000002 r4:80080003
[ 1453.468889] [<c03e13a8>] (l3_interrupt_handler) from [<c0170418>] (irq_forced_thread_fn+0x28/0xa0)
[ 1453.477890] r10:c0c05888 r9:00000000 r8:00000001 r7:c01703f0 r6:ffffe000 r5:dc53fd40
[ 1453.485752] r4:dc407900
[ 1453.488301] [<c01703f0>] (irq_forced_thread_fn) from [<c017075c>] (irq_thread+0x124/0x24c)
[ 1453.496602] r7:c01703f0 r6:ffffe000 r5:dc407900 r4:dc53fd40
[ 1453.502298] [<c0170638>] (irq_thread) from [<c0149d98>] (kthread+0x158/0x160)
[ 1453.509465] r10:dc469ab0 r9:c0170638 r8:dc53fd40 r7:dc554000 r6:00000000 r5:dc53fdc0
[ 1453.517327] r4:dc53fe00
[ 1453.519876] [<c0149c40>] (kthread) from [<c01010f0>] (ret_from_fork+0x14/0x24)
[ 1453.527127] Exception stack(0xdc555fb0 to 0xdc555ff8)
[ 1453.532199] 5fa0: 00000000 00000000 00000000 00000000
[ 1453.540412] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1453.548625] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[ 1453.555268] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0149c40
[ 1453.563130] r4:dc53fdc0
[ 1453.565671] —[ end trace 0000000000000002 ]—
Bus error (core dumped)
方法二:开发简单的驱动程序
…
#define DEVICE_NAME "am437x-plc"
static int Dev_open(struct inode * inode , struct file * filp)
{
return 0;
}
static int Dev_release(struct inode * inode, struct file *filp)
{
return 0;
}
static int Dev_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
{
return 0;
}
ssize_t Dev_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset)
{
int ret=0;
return ret;
}
static long Dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
return val;
}
static const struct file_operations dev_fops =
{
.owner = THIS_MODULE,
.open = Dev_open,
.release = Dev_release,
.read = Dev_read,
.write = Dev_write,
.unlocked_ioctl = Dev_ioctl,};
static struct miscdevice demo_dev =
{
.minor = 55,//MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
void set_led_p(int mark)
{
unsigned int val;
void *gpio4_addr=NULL;
printk(KERN_NOTICE "$ set led <%d> !!!!\n",mark);
gpio4_addr=ioremap(0x48320000, 0x1000);
if(!gpio4_addr){
printk(KERN_ERR "$ fail to remap gpio5!!!\n");
return;
}
printk(KERN_NOTICE "$ remap gpio5 ok !!!\n");
val=ioread32(gpio5_addr+0x134); //panic here
iowrite32(val&(~(1<<9)),gpio5_addr+0x134);
iowrite32(1<<9,gpio5_addr+0x194);
val=ioread32(gpio4_addr+0x134);
iowrite32(val&(~((1<<28)|(1<<27)|(1<<29))),gpio4_addr+0x134);
iowrite32(1<<28,gpio4_addr+0x194);
mdelay(50);
}
int __init Dev_init(void)
{
int ret;
set_led_p(20);//panic here
//Regist misc device
ret = misc_register(&demo_dev);
if(ret){
printk("[ERROR] Misc device register\n");
return ret;
}
printk("$Tdr Ver2.0\n");
return 0;
}
void __exit Dev_exit(void)
{
misc_deregister(&demo_dev);
}
module_init(Dev_init);
module_exit(Dev_exit);
MODULE_AUTHOR("zxj");
MODULE_ALIAS("SPX misc Controller");
MODULE_DESCRIPTION("SPX misc Controller module");
MODULE_LICENSE("GPL");
以上两种方法,我以前经常在其他arm 系统中使用,包括 zynq7020(cortex-A9) , imx6ull(cortext-A7) , s3c6410(arm11)等, 从来没有遇到问题。
我认为也不是地址被其他 IP 或程序占用,而不能 mmap。 如果是被其他独占的话,那么 iommap, mmap 将返回 NULL, 而不是一个有效的虚拟地址。
问题:
1: 44000000.ocp:L3 Custom Error: MASTER M2 (64-bit) TARGET L4_PER_0 (Read): Data Access in User mode during Functional access
这种错误是什么含义,什么的情况会触发?
2: 该怎样去获取 CPU gpio 的值?
谢谢!
Shine:
请参考下面帖子里的方法试试。
e2e.ti.com/…/689887