往外设寄存器写数据遇到的麻烦

发布于 2022-09-18 18:38:46 字数 525 浏览 35 评论 0

我在没有操作系统的情况下就可以正确往外设寄存器里读写数据,比如写入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 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

守护在此方 2022-09-25 18:38:46

我觉得可能是驱动写的有问题吧。得仔细查查,你要坚信一点,加上操作系统不会引入硬件的错误。
再仔细查查怎么映射的,这很关键

风透绣罗衣 2022-09-25 18:38:46

原帖由 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同时有效了。

心碎的声音 2022-09-25 18:38:46

时序乱跟硬件有关系也是你的驱动,32位的话,最好是操作4字节地址, 否则你4字节读写如果没有对齐就会出错,

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

涙—继续流 2022-09-25 18:38:46

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

泪是无色的血 2022-09-25 18:38:46

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

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

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

木有鱼丸 2022-09-25 18:38:46

你全部使用WRITEW 试试看,然后自己转换看看, 把你程序里面的WRITEL 都注销掉

回忆躺在深渊里 2022-09-25 18:38:46

原帖由 yidou 于 2009-3-26 17:36 发表

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

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

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

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

会发光的星星闪亮亮i 2022-09-25 18:38:46

原帖由 yjz98 于 2009/3/26 21:35 发表

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

比如你要写32bits(对齐地址)中的高16位, 你可以:
1. 先把32bits读出来
2. 把这个值的高16bits赋成新的值
3. 把新的32bits写回.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文