关于驱动的问题,用到了ioremap和(*(unsgined char *))virtual_addr=0xff这种赋值方式
源码大概这个样子的:
平台是ARM9
virtual_addr=ioremap(phy_addr,1);virtual_addr是一个外设寄存器地址,是两字节的;
*((unsigned int *)virtual_addr)virtual_addr=0xffff;
程序遇到了问题,出错了.
请教一下,这种操作方式有什么错误??和ioremap()中第二个参数1有关吗?我查到的是这个参数指资源个数,但不理解是怎么回事
顺便再问下,outb,outw,inb,inw这类函数能用在上面.我自己感觉这类函数是linux为了支持IO端口空间和内存空间单映射才加上的,说白了就是x86下的in,out指令,所以在ARM平台下是不可用的.而且我用的时候也确实出了问题.不知道这么说对不对?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
I think u should call request_mem_region() before ioremap(), and use the following helper functions to access your ioport or iomem rather than direct access, cause they can handle the difference between ioport and iomem:
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);
......
I'm not familiar ARM9 platform, but if it functions well when using inb/outb, the phy_addr should be an ioport. For ioports, Linux also provide:
void __iomem *ioport_map(unsigned long port, unsigned int nr);
which remap ioport into iomem.
But I still suggest u use the helper functions I listed to access ur io regions whether u did ioport_map() or not.
I'd like to receive ur comment.
谢谢帮顶~~~
你说的我今天查了查,大概了解了点:
IO映射到内存后,理论上是可以直接访问地址来访问相应存储器的;但linux为兼容多个平台,提供了writeb,readb,writew,readw之类的函数,它们在不同的平台下有不同的实现形式.
我下午又调了调程序,将程序改成了这个样子
virtual_addr=(unsigned long)ioremap(phy_addr,1);
writeb(0xc0,vritual_addr);
这样就可以工作了;
但我要写的寄存器不光是单字节的,还有一个双字节的,我用了下面的程序去写
virtual_addr=(unsigned long)ioremap(phy_addr,2);
writew(0x5000,virtual_addr);
但却写不进去,我用readw(virtual_addr)读回来的结果一直是0
我上面提到的writeb(w),是在网上查到的结果,也是用来读写IO的,不知道和你说的iowrite有什么区别没?我明天试下,谢谢了
给你一个思路:
你考虑过little-ending 的问题吗,如果cpu和device的字节序是不一样,那肯定会出错的
另外,好奇,你既然是io寄存器,为什么不直接调用inb,outb, inw,outw,呢,map一个寄存器,2个寄存器,整个开销太大了。
另外ioremap面向页的,存在一些align问题,最好map一段连续的页对齐的空间
[ 本帖最后由 longda 于 2008-3-11 15:28 编辑 ]