2753|5

8

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

WINCE 5.0 待机恢复的问题,最后回不到C中 [复制链接]

先说说环境,是WINCE 5.0, S3C2440A的cpu,64M 内存,NAND FLASH,用的不是STEPLOADER,是自己用ADS写的BOOTLOADR。
之前已经看过很多关于休眠的帖子,别人遇到的问题的解决方式也试过了。
CONFIG.BIB中有这个了
        SLEEP               80028000  00002000        RESERVED
看之前一个帖子,有个同学是用的8C028000,但是很奇怪,这个C028000不是64M内存以内的啊?!
反正现在我可以把东西保存到这里的,然后把STEPLDR中的唤醒的汇编代码拷贝到我的ADS BOOTLOADER中,
设置的时钟等都是按照startup.s中的WINCE设置的一模一样了。
现在是能休眠了,那个POWEREN的管脚已经变低。然后我是EXINT0中断唤醒的,也已经唤醒了,能跳到
BOOTLOADR中,而且能监测到GSTATUS2的唤醒标志,而且基于SLEEPDATA_BASE_VIRTUAL这个地址的校验,就是保存
在GSTATUS3中的校验位也对了,已经又我的BOOTLOADER跳进了startup.s中的Awake_address函数,
这个我是通过点LED确认了。
问题是到了
;       2. Recover Last mode's REG's, & go back to caller of OALCPUPowerOff()

        ldr     sp, [r3, #SleepState_SVC_SP]
        ldr     lr, [sp], #4
        ldmia   sp!, {r4-r12}
        mov     pc, lr                          ; and now back to our sponsors
在把LR放到PC前都是可以控制LED的,但是这句并没有使程序返回到OEMPowerOff()函数中,而是好像跑飞了。
我在 startup.s 中的OALCPUPowerOff函数里这个地方加了

;;       5. Cache Flush
        bl                OALClearUTLB
        bl                OALFlushICache
        ldr     r0, = (DCACHE_LINES_PER_SET - 1)   
        ldr     r1, = (DCACHE_NUM_SETS - 1)   
        ldr     r2, = DCACHE_SET_INDEX_BIT   
        ldr     r3, = DCACHE_LINE_SIZE     
        bl                OALFlushDCache

;add by me
        b  Awake_address ;我加了这句,是可以让WINCE正常返回的,就是能让CE继续跑的

;       6. Setting Wakeup External Interrupt(EINT0,1,2) Mode
        ldr     r0, =vGPIOBASE

这样应该是可以说明我的Awake_address函数是没有错的啊,能返回C,而且能恢复所以现场的。
所以现在就不知道怎么解决了。请高手指点,谢谢。

最新回复

现在用AXD仿真了,得到在BOOTLOADER中是这样 SleepState_WakeAddr            0x804070AC SleepState_MMUCTL       0xC000327F SleepState_MMUTTB       0x31F40000 SleepState_MMUDOMAIN    0x00000001 根据返回地址 0x804070AC ,应该是页表中偏移 0x2010 处,于是查页表内存 0x31F42010 为: 0x31f42010  0E 04 40 30 0E 04 50 30 0E 04 60 30 0E 04 70 30 ..@0..P0..`0..p0 0x31f42020  0E 04 80 30 0E 04 90 30 0E 04 A0 30 0E 04 B0 30 ...0...0...0...0 0x31f42030  0E 04 C0 30 0E 04 D0 30 0E 04 E0 30 0E 04 F0 30 ...0...0...0...0 的确是指向 0x30400000 啊,而且 domain = 0,上面的 mmudomain 设置为domain0 依靠 AP 位,这个AP 位为01, 这样理论上页表没有错啊,MMUCTL 的设置表面上看也没有错的。 所以我的代码中         mcr     p15, 0, r8,  c1, c0, 0          ; restore MMU control ;   3. Jump to Kernel Image fw.s (Awake_address)         mov     pc, r7                          ;  jump to new VA (back up Power management stack)         这几句都能跑的,能回到 SleepState_WakeAddr 这个地方的啊。 而且我查 SleepState_WakeAddr 0x804070AC 对应的的映射地址 0x304070AC 里的内容的确是 startup.s 中 Awake_address 里的内容,所以的确是能MMU 映射,并跳到这个函数里的。 关键是现在我是在WINCE 进入休眠后,再打开AXD来仿真的,但跑到打开MMU这句后,AXD不能对任何内存访问了, 甚至0x80000000 和 0xa0000000也不行了,奇怪。  详情 回复 发表于 2009-4-17 17:52
点赞 关注

回复
举报

1

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
好了,我不过这个MMU了,做一次人肉MMU。
直接在恢复MMU那句之前,把SleepState_WakeAddr 0x804070AC 转换为对应的的映射地址 0x304070A
然后让程序跑到这里,的确是回到Awake_address 函数了。
然后是一堆恢复各状态寄存器的指令,都正常,一直到了这里:
;       2. Recover Last mode's REG's, & go back to caller of OALCPUPowerOff()

        ldr     sp, [r3, #SleepState_SVC_SP]
        ldr     lr, [sp], #4
        ldmia   sp!, {r4-r12}
        mov     pc, lr                          ; and now back to our sponsors

这里 sp 就是 R13啦,获得的是保存的 0xffffc79c ,然后我手动查 MMUTABLE
就是 0x31f43ffc 获得的表是 0x31f45c01 。然后查 这个内存 0x31ffc79c,晕,全部是0.
所以 这个 堆栈 指针指向的内容是0,下面的那个出栈就使 lr 是0 了, 这么我的程序就跑到0 了。
当然上面是我没有打开MMU 的情况下做的, 不知道真正的 MMU 查表出来的结果是否这样,但跟我现在
的情况比较相近了, 难道这个堆栈出错了?! 奇怪,内存中的其他地方都没有出错啊。
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
首先:“这个C028000不是64M内存以内的啊?! ”
这个地址是开了MMU后映射的地址,具体的地址映射关系可以查看相应的文件。

其次,mov    pc, lr 后出现问题
估计问题还是出在MMU上,通过AXD查看当前PC值和LR值吧。
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 
但是我的设置是
g_oalAddressTable
;        DCD     0x80000000, 0x30000000, 96      ; 32 MB DRAM BANK 6
        DCD     0x80000000, 0x30000000, 64      ; 32 MB DRAM BANK 6
0x3C028000应该是映射到0x8C028000啊,就算是非CACHE也是在0xAC028000啊,怎么会是0x8C028000呢,奇怪。难道是他们的映射跟我不同?

顺便请教,如果我现在想用AXD调试,那么是否是在待机后再用仿真器连上啊?这时不会改变CPU内部的状态么?
我现在就是没办法知道这时候的PC值。
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
待机状态能否通过AXD连接上板子不是很清楚,
只知道进入WINCE后是不能连接板子的
如果AXD设置成stop target when connecting的话连接上后应该不会改变PC值的,当初我调bootloader的时候就是直接通过AXD看的
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

6
 
现在用AXD仿真了,得到在BOOTLOADER中是这样
SleepState_WakeAddr            0x804070AC
SleepState_MMUCTL       0xC000327F
SleepState_MMUTTB       0x31F40000
SleepState_MMUDOMAIN    0x00000001

根据返回地址 0x804070AC ,应该是页表中偏移 0x2010 处,于是查页表内存 0x31F42010 为:

0x31f42010  0E 04 40 30 0E 04 50 30 0E 04 60 30 0E 04 70 30 ..@0..P0..`0..p0
0x31f42020  0E 04 80 30 0E 04 90 30 0E 04 A0 30 0E 04 B0 30 ...0...0...0...0
0x31f42030  0E 04 C0 30 0E 04 D0 30 0E 04 E0 30 0E 04 F0 30 ...0...0...0...0

的确是指向 0x30400000 啊,而且 domain = 0,上面的 mmudomain 设置为domain0 依靠 AP 位,这个AP
位为01, 这样理论上页表没有错啊,MMUCTL 的设置表面上看也没有错的。
所以我的代码中

        mcr     p15, 0, r8,  c1, c0, 0          ; restore MMU control
;   3. Jump to Kernel Image fw.s (Awake_address)
        mov     pc, r7                          ;  jump to new VA (back up Power management stack)
       
这几句都能跑的,能回到 SleepState_WakeAddr 这个地方的啊。

而且我查 SleepState_WakeAddr 0x804070AC 对应的的映射地址 0x304070AC 里的内容的确是
startup.s 中 Awake_address 里的内容,所以的确是能MMU 映射,并跳到这个函数里的。

关键是现在我是在WINCE 进入休眠后,再打开AXD来仿真的,但跑到打开MMU这句后,AXD不能对任何内存访问了,
甚至0x80000000 和 0xa0000000也不行了,奇怪。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表