搜索
bottom↓
回复: 17

ADS程序里面的一个宏替换看不明白,特请指教。

[复制链接]

出0入0汤圆

发表于 2009-5-12 17:54:24 | 显示全部楼层 |阅读模式
#define ClearPending(bit) {\
                rSRCPND = bit;\
                rINTPND = bit;\
                rINTPND;\
                }   

这个是“2440addr.h”里面的一段代码;
请问这里的“rINTPND;\”有什么作用?我看这个怎么看都好像毫无意义!
上官先生有什么看法吗?

Thanks

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2009-5-12 21:41:44 | 显示全部楼层
多行宏
\  是换行符。

比如  ClearPending(1)

会生成如下代码

{
    rSRCPND = 1;
    rINTPND = 1;
    rINTPND;
}




你看下rINTPND是不是其他的宏


你的代码是不错了,是你抄错了吧

出0入0汤圆

发表于 2009-5-13 08:42:58 | 显示全部楼层
回1楼,这代码没错,我用GCC也编译过这个宏,而且必须要加上最后一句

rINTPND;\  

才能编译通过 ...... 我也有疑问

rINTPND 只是一个寄存器地址,定义为 :

#define rINTPND     (*(volatile unsigned *)0x4a000010)        //Interrupt request status

等答案

出0入0汤圆

 楼主| 发表于 2009-5-13 09:28:25 | 显示全部楼层
CSDN上有人说这是读寄存器······
个人不敢苟同!

出0入0汤圆

发表于 2009-5-13 09:45:43 | 显示全部楼层
看了下手册,INTPND是中断挂起寄存器,每位对应一个中断,如果某位置位,这执行中断。这段代码你是怎么用的?代码的上边有什么,下边有什么?

出0入0汤圆

发表于 2009-5-13 09:46:52 | 显示全部楼层
看下生成的汇编代码

出0入0汤圆

发表于 2009-5-13 12:47:05 | 显示全部楼层
编译环境是  arm-elf-gcc 4.2.2

#define rSRCPND     (*(volatile unsigned *)0x4a000000)        //Interrupt request status
#define rINTPND     (*(volatile unsigned *)0x4a000010)        //Interrupt request status

void KeyScan_Test(void)
{
        ClearPending(0x55);
}

#define        ClearPending(bit)    \
                        rSRCPND = bit ; \
                        rINTPND = bit ;   \
                        rINTPND ;\

设置优化等级为 -O2
30000e60 <KeyScan_Test>:
30000e60:        e3a0344a         mov        r3, #1241513984        ; 0x4a000000
30000e64:        e3a02055         mov        r2, #85        ; 0x55
30000e68:        e5832000         str        r2, [r3]
30000e6c:        e5832010         str        r2, [r3, #16]
30000e70:        e5931010         ldr        r1, [r3, #16]
30000e74:        e12fff1e         bx        lr

不设置优化等级
30001758 <KeyScan_Test>:
30001758:        e1a0c00d         mov        ip, sp
3000175c:        e92dd800         push        {fp, ip, lr, pc}
30001760:        e24cb004         sub        fp, ip, #4        ; 0x4
30001764:        e3a0244a         mov        r2, #1241513984        ; 0x4a000000
30001768:        e3a03055         mov        r3, #85        ; 0x55
3000176c:        e5823000         str        r3, [r2]
30001770:        e59f2010         ldr        r2, [pc, #16]        ; 30001788 <KeyScan_Test+0x30>
30001774:        e3a03055         mov        r3, #85        ; 0x55
30001778:        e5823000         str        r3, [r2]
3000177c:        e59f3004         ldr        r3, [pc, #4]        ; 30001788 <KeyScan_Test+0x30>
30001780:        e5933000         ldr        r3, [r3]
30001784:        e89da800         ldm        sp, {fp, sp, pc}
30001788:        4a000010         .word        0x4a000010

结论
可以看出,无论是否开优化,最后的一条指令都没有被去掉。
rINTPND ;
生成的代码是
30000e70:        e5931010         ldr        r1, [r3, #16]

可见,这确实是一条读寄存器的指令。

勘误一下,我之前编译的时候去掉这指令报错,但是今天我去掉发现没有报错,所以我认为这条指令不是必须的。
之前说错了。

出0入31汤圆

发表于 2009-5-13 13:47:23 | 显示全部楼层
好奇怪,居然不会优化掉

出0入0汤圆

发表于 2009-5-13 13:49:08 | 显示全部楼层
第一个
ldr        r1, [r3, #16]


第二个
ldr        r3, [r3]

确实读了 :)

那删掉肯定可以

还有个问题你的工具链是自己编译的还是下载的
如果是下载的给个地址,我之前强行编译了一个不太放心 :)

出0入0汤圆

发表于 2009-5-13 16:02:36 | 显示全部楼层
回8楼,你可以到这里下载,我的就是在上面搞的,呵呵~~~

http://gnuarm.org/

出0入0汤圆

发表于 2009-5-13 17:16:07 | 显示全部楼层
volatile 不允许优化了

出0入31汤圆

发表于 2009-5-13 20:27:44 | 显示全部楼层
了解了,确实是读
(*(volatile unsigned *)0x4a000010)就是取个数,只不过常见的形式是A=(*(volatile unsigned *)0x4a000010)

出0入0汤圆

 楼主| 发表于 2009-5-14 09:20:21 | 显示全部楼层
看来真的是读寄存器,因为由于volatile的存在,该语句不会被优化掉。
问题是,纯粹的C语言有规定这样写就一定要编译成读寄存器的指令吗?我好像没有见过那本手册上说这样写就等价于读操作。

出0入31汤圆

发表于 2009-5-14 11:35:34 | 显示全部楼层
按照c语言的语意应该是读寄存器,不然还能编译成什么指令

出0入0汤圆

 楼主| 发表于 2011-4-24 00:31:08 | 显示全部楼层
回复【8楼】wanmyqawdr
第一个
ldr        r1, [r3, #16]  
第二个
ldr        r3, [r3]  
确实读了 :)
那删掉肯定可以
还有个问题你的工具链是自己编译的还是下载的
如果是下载的给个地址,我之前强行编译了一个不太放心 :)

-----------------------------------------------------------------------

这个不能随便删。其作用是确保数据写入到rINTPND而不是保留在cache中。
至于为什么读rINTPND就能使cache中的数据update到rINTPND寄存器中,那就是硬件(arm920t)的规定啦。

出0入0汤圆

发表于 2011-4-27 13:36:47 | 显示全部楼层
回复【14楼】valley 微风山谷
回复【8楼】wanmyqawdr  
第一个  
ldr        r1, [r3, #16]   
第二个  
ldr        r3, [r3]   
确实读了 :)  
那删掉肯定可以  
还有个问题你的工具链是自己编译的还是下载的  
如果是下载的给个地址,我之前强行编译了一个不太放心 :)  
-----------------------------------------------------------------------
这个不能随便删。其作用是确保数据写入到rintpnd而不是保留在cache中。
至于为什么读rintpnd就能使cache中的数据update到rintpnd寄存器中,那就是硬件(arm920t)的规定啦。
-----------------------------------------------------------------------

这个和cache有什么关系?
1.你可能根本没有开mmu,没开mmu,无法用Dcache
2.写之后,并没有clean Dcache
3.读寄存器并不能强制dcache和寄存器一致
4.一般对寄存器区域的访问根本不开Dcache和write buffer

如何解释?
这一定是2440 中断控制器硬件上的特性,这个特性不具有一般性,手册上应该会提到

出0入0汤圆

 楼主| 发表于 2011-4-27 15:08:42 | 显示全部楼层
回复【15楼】wanmyqawdr
这个和cache有什么关系?
1.你可能根本没有开mmu,没开mmu,无法用Dcache
2.写之后,并没有clean Dcache
3.读寄存器并不能强制dcache和寄存器一致
4.一般对寄存器区域的访问根本不开Dcache和write buffer

如何解释?
这一定是2440 中断控制器硬件上的特性,这个特性不具有一般性,手册上应该会提到
-----------------------------------------------------------------------

其实本人水平很烂,而且是很久之前研究过一阵,所以可能有很多错误。硬着头皮回答一下吧。

1.是的,确实存在这种可能。但你确定不会开mmu吗?牺牲一点小小的性能提高程序的鲁棒性,这在一个软件工程师眼里不是理所当然的吗?
2.有没有clean,得看cache是否设置为write back或者是write through。
3.“ARM920T_TRM1_S”第102页:The write buffer is also drained before performing the following less controllable
activities, which you must consider as implementation-defined:fetch from noncachable memory.
    所以,读寄存器的作用是把write buffer的内容写到寄存器上(如果我的理解没错的话)。貌似我也没说“读寄存器能强制dcache和寄存器一致”。而且这里面的要求是读取noncacheable memory。看楼上的回复,我在手册里找了半天只找到这一句,我以前还以为无论是否cacheable都会drain the write buffer,可能是日子久了记忆发生偏移量吧。
4.根据前面的分析,如果write buffer可以关闭的话,确实就不存在写入后读一遍寄存器的必要啦 :-)

但如果d bus配置为noncached and buffered,假设下面这种情况:
disable interrupt
change 信号量  ; 由于是buffered,cpu执行disable interrupt后没有等待buffer写入,然后就发生了中断,然后在中断中改变了信号量……


以上是我的一些看法,也是我对“读rINTPND”的解释,纯属一家之言。

出0入0汤圆

发表于 2011-4-27 22:25:34 | 显示全部楼层
回复【16楼】valley  微风山谷
回复【15楼】wanmyqawdr
这个和cache有什么关系?
1.你可能根本没有开mmu,没开mmu,无法用dcache
2.写之后,并没有clean dcache
3.读寄存器并不能强制dcache和寄存器一致
4.一般对寄存器区域的访问根本不开dcache和write buffer
如何解释?
这一定是2440 中断控制器硬件上的特性,这个特性不具有一般性,手册上应该会提到
-----------------------------------------------------------------------
其实本人水平很烂,而且是很久之前研究过一阵,所以可能有很多错误。硬着头皮回答一下吧。
1.是的,确实存在这种可能。但你确定不会开mmu吗?牺牲一点小小的性能提高程序的鲁棒性,这在一个软件工程师眼里不是理所当然的吗?
2.有没有clean,得看cache是否......
-----------------------------------------------------------------------

读寄存器与dcache没有关系
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 23:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表