嵌入式linux下的io内存映射问题

yjz9898 2009-03-14 03:37:25
#define HPI_PHYSICAL_BASEADDR 0x30000000
hpi_vbase = (int *) ioremap_nocache (HPI_PHYSICAL_BASEADDR, 0x1e);
u32 w,test;
u16 t1, t2;
t1 = (0xffff & (w >> 16));
t2 = (0xffff & w);
writew (t1, hpi_vbase + 0x04);
writew (t2, hpi_vbase + 0x06);
test=*(hpi_vbase + 0x04)

我在程序里写了上面的代码,向hpi_vbase + 0x04(高半字地址)和hpi_vbase + 0x06(低半字地址)写入w,
然后又在后面跟了个printk语句打印
printk("%d\n",test<<16|*(hpi_vbase + 0x06));
结果输出的值不是我想要写入的w,有大为大侠知道我的问题处在哪么?
...全文
115 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
duloveding 2010-05-04
  • 打赏
  • 举报
回复
现在问题解决了吗?我现在也有同样的问题!
cth2008 2009-06-19
  • 打赏
  • 举报
回复
你的外设是什么,时序看看
yjz9898 2009-03-18
  • 打赏
  • 举报
回复
数据没写进去,写入和读出的地址定义的是一样的。现在改变写入的值根本就不影响读出的值,读出的值老是524288.运行测试程序的时候用printk观察,是能够进入驱动的每一个函数的,当写的时候,会进入fops里的写函数,会执行在6楼提到的赋值操作,读的时候,也会进入fops里的读函数,只是读出来的东西不受写的东西的影响,我怀疑是根本就没写进去。实在没辙了,贴主要代码了,大家爱帮我看看
short int *vbase;
vbase=(short int *)ioremap_nocache(0x30000000,0x1b);
static int __init hpi_init (void)//初始化代码,在加载模块的时候执行{
AT91_SYS->EBI_SMC2_CSR[2] = 0x22003484;
if (!request_mem_region (HPI_PHYSICAL_BASEADDR,HPI_PHYSICAL_size, "HPI"))
{ printk ("Error request mem \n"); }
else
{ PDEBUG ("request mem success!\n"); }
hpi_vbase = (short int *) ioremap_nocache (HPI_PHYSICAL_BASEADDR, HPI_PHYSICAL_size);
ret = register_chrdev (254, "HPI", &hpi_fops);}
ssize_t hpi_write (struct file *file, const char *buf, size_t count,loff_t * offp)//写函数 写函数里调用了三个函数:写控制寄存器HPIC_Write (0x00010001);写地址寄存器HPIA_Write (0x0003ffe0);写数据寄存器HPID_AutoWrite (*pwritetmp++);
inline void HPIC_Write (int w)
{short int t1, t2;
t1 = (short int)(0xffff & (w >> 16));
t2 = (short int)(0xffff & w);
mb();writew (t1, (u16 *)(hpi_vbase + 0x00));mb();writew (t2, (u16 *)(hpi_vbase + 0x02));
delay();
}
inline void HPIA_Write (int w)
{ short int t1, t2;
t1 = (short int)(0xffff & (w >> 16));
t2 = (short int)(0xffff & w);
mb();writew (t1, (u16 *)(hpi_vbase + 0x04));mb();writew (t2, (u16 *)(hpi_vbase + 0x06));
delay();
}
void HPID_AutoWrite (int w)
{ short int t1, t2;
t1 = (short int)(0xffff & (w >> 16));
t2 = (short int)(0xffff & w);
mb();outw (t1, hpi_vbase + 0x08);mb();outw (t2, hpi_vbase + 0x0a);mb();
delay();
}
上面的函数都会执行到,就是执行贴出来的三个内联函数的时候,数据没有写入到指定的外设地址中去。
yjz9898 2009-03-18
  • 打赏
  • 举报
回复
实现arm和一个从设备之间的通信,具体就是操作从设备的三个寄存器,利用arm的数据总线的d0-d15来实现和从设备的数据传输。我定义了以下一些变量:
short int *vbase,t1,t2; int t3;
vbase=(short int *)ioremap_nocache(0x30000000,0x1b);
*(vbase+0x00)=t1;//对从设备的寄存器写值
*(vbase+0x02)=t2;
writew (t1, hpi_vbase + 0x04);
writew (t2, hpi_vbase + 0x06);
做了以上操作后,确发现从设备的寄存器中的值并不是我写入的值(根本就没写进去) ,这是怎么回事啊?多谢各位高手指点指点!
j2mej2se 2009-03-16
  • 打赏
  • 举报
回复
不懂,帮顶
yjz9898 2009-03-16
  • 打赏
  • 举报
回复
还有一个问题,就是我发现我吧数据从用户(内核)空间传输到内核(用户)空间的时候,数据传输是没有问题的,可是我在内核空间用kmalloc分配了我要传输的数据量大小的空间,然后用两个指针指向他们,一个拿来自增访问这篇区域的对应数据,一个用来保存区域开始位置的地址,当我把这片区域的数据逐个写入hpi_vbase+0x08,hpi_vbase+0x0a组成的字空间后,再打印输出那片区域的数据(用的是把自增指针重新赋值位另一个指向开始地址的指针),发现开始的几个数据还对,可是后面的那些数就出错了,根本就不是从用户空间传过来的那些数据了(在用户空间没有传输新的数据的情况下),这是怎么回事啊,没有重新写数据,怎么数据就变了呢?
我贴出代码,让大家给分析分析!
pwritetmp = pwrite;//两个指针int *
for(i=0;i<33;i++)
printk("%d !\n",*pwritetmp++);//这是从用户空间拷贝到pwrite指向的区域后打印出来的数据,表现正常
i=0;
pwritetmp = pwrite;
while (i < 33)

{
printk("before HPID_AutoWrite %d !\n",*pwritetmp++);//打印出的数据,后面的一大半数据不对
HPID_AutoWrite (*pwritetmp++);//这个函数的功能也就是把指针指向地址内的数据写入到另外的地址去
wmb ();
i++;
}
pwritetmp = pwrite;
for(i=0;i<33;i++)
printk("after HPID_AutoWrite %d !\n",*pwritetmp++);//打印出的数据,基本上面目全非了
多谢各位指点指点!
yjz9898 2009-03-16
  • 打赏
  • 举报
回复
跟帖的问题解决了,现在还是感觉下面的两条语句没有达到预期的效果,没哟将数据写入到外部设备的寄存器。
writew (t1, hpi_vbase + 0x04);
writew (t2, hpi_vbase + 0x06);

21,606

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧