搜索
bottom↓
回复: 12

求助:有关ATmega128A WINAVR下的通用寄存器用法.

[复制链接]

出35入0汤圆

发表于 2015-2-1 19:40:50 | 显示全部楼层 |阅读模式
本帖最后由 Andrewz 于 2015-2-2 00:17 编辑

最近打算将ucos-ii移植到atmega128A.用的WINAVR编译器.在坛子里也看了一些资料.
现在对其CPU通用寄存器GPRs有一些疑惑.希望有大侠相助.

引用《建立一个属于自己的AVR的RTOS》一文中
"
在Win AVR中的帮助文件 avr-libc Manual中的Related Pages中的Frequently Asked Questions,其实有一个问题是"What registers are used by the C compiler?"  回答了编译器所需要占用的寄存器。一般情况下,编译器会先用到以下寄存器
    1 Call-used registers (r18-r27, r30-r31): 调用函数时作为参数传递,也就是用得最多的寄存器。
    2 Call-saved registers (r2-r17, r28-r29): 调用函数时作为结果传递,当中的r28和r29可能会被作为指向堆栈上的变量的指针。
    3 Fixed registers (r0, r1): 固定作用。r0用于存放临时数据,r1用于存放0。

找了下原文:
Call-used registers (r18-r27, r30-r31):
        May be allocated by gcc for local data. You may use them freely in assembler subroutines. Calling C subroutines can clobber any of them - the caller is responsible for saving and restoring.
Call-saved registers (r2-r17, r28-r29):
        May be allocated by gcc for local data. Calling C subroutines leaves them unchanged. Assembler subroutines are responsible for saving and restoring these registers, if changed. r29:r28 (Y pointer) is used as a frame pointer (points to local data on stack) if necessary. The requirement for the callee to save/preserve the contents of these registers even applies in situations where the compiler assigns them for argument passing.

这里没弄明白.

试着分析一下:
        比如我写了一个主函数,这个主函数正常运行着.那么,其r0-r31可能都存了数据.
        SREG则存了总状态.
        那么此时,
        来了一个子函数,产生了一个call,在这个call的过程中,Call-used registers数据会丢失.
        所以在call之前要存Call-used registers到堆栈.                                                        <- 从上面的英文来看,在跳转前Call-used registers全部保存.
        而此刻的Call-saved registers,在call的时候不会变,所以call完了再存也没关系.
        如果能保证其值不变,甚至不存,也没关系.显然,这个保证暂时无法给出.                        <- 从上面的英文看,Call-saved registers可在子函数里存.

        入栈GPRs再出栈GPRs,这样主函数就可以像什么事情都没发生一样继续运行.
        这个过程对于用C写程序的人来说,就好像没有发生过一样,编译器做好了.
        猜想编译器可以优化上面两种寄存器的出入栈.将无关GPRs优化掉.

        对于需要做任务切换的函数,不能用return,return只能退到调用之前的任务.
        此时要根据得到的最高优先级就绪编号找到最高优先级就绪任务,并且恢复其所有GPRs,且跳转到其中.
        此时,就要抛开编译器,手动上汇编了.

问题来了.
        在切换任务的那一刻:
                在将SP的任务函数地址赋给PC前,肯定需要将上一个任务的GPRs保管好.即需要PUSHALL
                由于已经PUSHALL了,此时32个GPRs可以随便用了.
                在切换到下一个任务前,需要将下一个任务的GPRs全部释放出来.
                而释放GPRs的前提条件是SP正确,所以,首先得到需要切换到的任务的SP,然后POPALL,这样,就完全恢复了GPRs.
                最后一步,RET.此时是返回,不是call,因此不会使得GPRs有改变.完全切换到下一个任务.

        以上是本人想法,没有验证过.但是坛子里找到的WINAVR + ucos的例子基本可以这样解读.

        编辑之前,我以为切换到下一个任务需要call,而call会破坏Call-used regiters, so 百思不得qi解.
       
        这样一算,总共32个寄存器,加SREG.切一次几百的周期就过去了.125ns*200. 几十个微秒用来切任务,每秒钟切200下,每秒要几毫秒,应该问题不大.
       
so, 我的问题...
求大侠指导.

       

       

       

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

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

出35入0汤圆

 楼主| 发表于 2015-2-2 19:35:09 | 显示全部楼层
原来AVR studio 4自带软件仿真功能.
在这个功能的帮助下,很方便的查看了各个寄存器的变化情况.
最终在WinAVR下,用上了ucos-ii.
LED闪烁起来了.

出35入0汤圆

 楼主| 发表于 2015-2-2 23:09:46 | 显示全部楼层
NND,原来是自己用错了.要在OSStart以后才开中断.
软件仿真出问题,在void  OS_MemClr (INT8U *pdest, INT16U size)这里,仿真过不去了.
然后堆栈的地址也不对.
下午能跑起来是因为在Create任务的时候不经意把中断开启了.然后通过中断就开始了任务的调用.
但是书上说,这样可能会导致问题.
蛋碎了.

出35入0汤圆

 楼主| 发表于 2015-2-3 00:09:58 | 显示全部楼层
好吧,在邵贝贝的书上写得清清楚楚,
在嵌入式应用中,用户必须在第一个任务中打开时钟节拍中断.

出35入0汤圆

 楼主| 发表于 2015-2-3 10:55:20 | 显示全部楼层
现在确定能用了.

特此上传.仅供学习参考之用.

不能保证用着不会崩溃.
如果有用过的,发现了问题,还请帮忙指出.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出35入0汤圆

 楼主| 发表于 2015-2-3 16:12:34 | 显示全部楼层
本帖最后由 Andrewz 于 2015-2-3 16:15 编辑

中断嵌套是不敢用了,不知道要用多大的堆栈.
现在弄了个发送结束中断.每隔一段时间发送一个B,发完了改变一个LED的状态.
另外弄了一个每隔1秒改变另一个LED状态的任务.
不知道为何,运行了一段时间后会卡一下.
猛然将板子提起来,也会卡住.

但是都是过一会就恢复了.
现在都搞不清是系统有问题还是板子的问题还是程序的问题了.


直接用ISP供电的,拉了好长一截线.
我不动,它就好像是正常的.
我一动,它就卡.

出35入0汤圆

 楼主| 发表于 2015-2-3 19:45:00 | 显示全部楼层
总结下了.

ATmega128A WINAVR下,
1.r0-r1可以做临时存储器.既相当于汇编语言里面上下相邻的两条指令当个中间变量.

2.r2-r17,r28-r29,在调用C语言时,其值不会改变.但是究竟什么操作会改变其值,暂无研究.

3.r18-r27,r30-r31,在调用C语言时,其值会被破坏.

显然,GPRs的内容会不会被破坏,是和WINAVR密切相关的.

如果使用汇编编程,则这些问题全部不存在.

最初有这个问题,是因为看到函数切换时,需要出入栈全部GPRs.

而这个和CM3里面只需保存r4-r11相比,本来就慢,还要多,岂不是更没有实时性.

减少出入栈GPR的目标没有实现.

ucos运行倒是实现了.

坐等大神优化.

出35入0汤圆

 楼主| 发表于 2015-2-3 20:32:46 | 显示全部楼层
两天了..
没人...

在论坛找AVR的资料,发现论坛里技术大牛真多...
06年就已经给AVR单片机总结了.
06年...
研究大牛研究过的东西..

出35入0汤圆

 楼主| 发表于 2015-2-4 16:54:48 | 显示全部楼层
AVR Simulator 仿真的时候无法将数据清零?SRAM应该清成00000000,结果成了01010101.
???

出0入0汤圆

发表于 2015-2-4 17:05:20 | 显示全部楼层
=-=
建议看下AVR 的寄存机的操作。R0-R15(间接)和R16-RN(直接)的操作方式是不同的。最后三个寄存器可以作为X/Y/Z指针使用。
这部分看汇编方式可能会理解的更清楚

出35入0汤圆

 楼主| 发表于 2015-2-4 20:07:42 | 显示全部楼层
lleaf 发表于 2015-2-4 17:05
=-=
建议看下AVR 的寄存机的操作。R0-R15(间接)和R16-RN(直接)的操作方式是不同的。最后三个寄存器可以 ...


瞬间有了存在感.

出35入0汤圆

 楼主| 发表于 2015-4-2 19:53:42 | 显示全部楼层
终于感觉AVR的东东要弄完了.结贴了.
实现了
ucos II
bootloader
最好能加个无线收发串口模块.
那样就能远程升级了.

出35入0汤圆

 楼主| 发表于 2015-6-24 10:42:31 | 显示全部楼层

在参考了本坛的将AVR const存储到FLASH方法后.
上面是带两个自定义任务的ucos.
真是,非常的细小了.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

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

本版积分规则

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

GMT+8, 2024-8-25 23:18

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

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