免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2630 | 回复: 8
打印 上一主题 下一主题

往外设寄存器写数据遇到的麻烦 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-25 19:48 |只看该作者 |倒序浏览
5可用积分
我在没有操作系统的情况下就可以正确往外设寄存器里读写数据,比如写入1234,那么会读出1234.
可是我在linux下写了个驱动,用驱动映射后来读写的时候,写入1234,读出的确是1212,写入5678,读出的是5656.

用不带操作系统和带操作系统交叉调试的时候,不带操作系统写进去一个数据1234,然后加上操作系统读可以读出1234;  加操作系统写入1234,不带操作系统读,读出的是1212,这就说明带操作系统的时候写入出了问题,这是什么原因引起的啊?有哪些朋友遇到过啊?

工作平台:arm+linux    at91rm9200    linux2.4
附件为抓出来的时序图。

HWIL没有正常的跳变,它对应的是地址位的A1。按理说我要操作16位的地址空间,A0位不管,A1位应该是读写一次就会发生变化的,可是在图上可以看出是读或写两次A1位才发生一次跳变。

[ 本帖最后由 yjz98 于 2009-3-26 17:30 编辑 ]

Snap1.jpg (36.83 KB, 下载次数: 32)

Snap1.jpg

论坛徽章:
0
2 [报告]
发表于 2009-03-25 23:04 |只看该作者
我觉得可能是驱动写的有问题吧。得仔细查查,你要坚信一点,加上操作系统不会引入硬件的错误。
再仔细查查怎么映射的,这很关键

论坛徽章:
0
3 [报告]
发表于 2009-03-26 13:22 |只看该作者
原帖由 emmoblin 于 2009-3-25 23:04 发表
我觉得可能是驱动写的有问题吧。得仔细查查,你要坚信一点,加上操作系统不会引入硬件的错误。
再仔细查查怎么映射的,这很关键


我相信你说的是正确的,加上操作系统不会引入硬件的错误,可就是总感觉操作系统的引入把时序搞乱了。现在我要操作的物理地址是
0x30000000,0x30000002,0x30000004,0x30000006,0x30000008,0x3000000a,
0x30000010,0x30000012,0x30000014,0x30000016,0x30000018,  0x3000001a,
其中0x30000000这个地址是我的一个片选ncs2的基地址,这些地址应该都要指向双字节(半字)的外设寄存器。
我要在linux下先是用vbase=(unsigned long)ioremap_nocache(0x30000000,0x18)做了个映射返回一个虚拟地址
vbase,然后就可以操作vbase,vbase+2,vbae+4,vbase+6,vbase+8,vbase+0xa,vbase+x10,vbase+0x12,vbase+0x14,vbase+0x16,vbase+0x18,vbase+0x1a来达到操作对应的那几个物理地址了吧!(操作的时候把这些值都做了强制类型转换(unsigned short int *))

上面的操作应该是正确的吧!可以看出我的编码的地址用的是板子对齐(A0没用)。在应用程序读写的时候发现了一个很奇怪的问题,竟然我arm数据总线那边的读写使能信号NRD和NWR0同时有效了。

论坛徽章:
0
4 [报告]
发表于 2009-03-26 14:40 |只看该作者
时序乱跟硬件有关系也是你的驱动,32位的话,最好是操作4字节地址, 否则你4字节读写如果没有对齐就会出错,

[ 本帖最后由 star316 于 2009-3-26 14:44 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-03-26 17:31 |只看该作者

回复 #4 star316 的帖子

可是我的硬件连接不能改变。一次读写的又是外设16位的寄存器。这样的话不能做到总是操作4字节对齐的地址空间。大家有什么办法可以强制操作四字节对齐的地址空间啊。我新上传了时序图,大家帮我看看!

论坛徽章:
5
6 [报告]
发表于 2009-03-26 17:36 |只看该作者
原帖由 yjz98 于 2009/3/26 17:31 发表
可是我的硬件连接不能改变。一次读写的又是外设16位的寄存器。这样的话不能做到总是操作4字节对齐的地址空间。大家有什么办法可以强制操作四字节对齐的地址空间啊。我新上传了时序图,大家帮我看看!


前面的贴子已经提到四字节对齐的问题.

处理这种不对齐的(16bits)寄存器地址, 就:
读: 把它封装在对应的(32bits)地址中, 一次操作32bits, 得到结果后再取其中的16bits.
写: 类似.

论坛徽章:
0
7 [报告]
发表于 2009-03-26 19:17 |只看该作者
你全部使用WRITEW 试试看,然后自己转换看看, 把你程序里面的WRITEL 都注销掉

论坛徽章:
0
8 [报告]
发表于 2009-03-26 21:35 |只看该作者
原帖由 yidou 于 2009-3-26 17:36 发表


前面的贴子已经提到四字节对齐的问题.

处理这种不对齐的(16bits)寄存器地址, 就:
读: 把它封装在对应的(32bits)地址中, 一次操作32bits, 得到结果后再取其中的16bits.
写: 类似.


读这样处理可以理解,可以先用real读,然后取它的低或高16位;
那写怎么处理啊?用writel写,这不一下就写到外设寄存器里去了吗?怎么来取其中的16位?不过外设一次只能写16位,这写出去的32位会在舍去?

能列出几行实力代码吗?太感谢了!

论坛徽章:
5
9 [报告]
发表于 2009-03-27 09:14 |只看该作者
原帖由 yjz98 于 2009/3/26 21:35 发表


读这样处理可以理解,可以先用real读,然后取它的低或高16位;
那写怎么处理啊?用writel写,这不一下就写到外设寄存器里去了吗?怎么来取其中的16位?不过外设一次只能写16位,这写出去的32位会在舍去?
...


比如你要写32bits(对齐地址)中的高16位, 你可以:
1. 先把32bits读出来
2. 把这个值的高16bits赋成新的值
3. 把新的32bits写回.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP