[求助] 裸机使用printf程序跑飞

lzwml   2014-11-12 17:46 楼主
我怀疑的关键词 1、lds文件 【2】、Stepping stone 只拷贝4K(0x1000) 【3】、没有从Stepping stone跳转到SDRAM(我认为可能性最大) 【4】、启动代码里我没有把 BSS段 清0 5、NandFlash是否正确拷贝到SDRAM 下面是我进行的分析,希望大家能利用我的线索提供意见 --------------------------------------------------------- linux环境下开发裸机程序,printf相关代码是从uboot拷贝过来的。 1、用J-Link下载程序到SDRAM里,跳过Stepping Stone程序可以【正常运行】。 2、程序烧录到NandFlash里,重新上电,从Stepping Stone启动【不能运行】。可以看到LED等闪了几下,证明程序有过复位,接着就卡死在某处【我不懂配置GDB,没办法断点调试,但用J-Link ARM可以看到程序PC指针位置是0x01xxxxxx也可能是0x3000xxxx】。 不使用printf情况下,重复1、2步骤都不会死机 reset: //////////////////////////////////////////////////// //程序死机位置 bl boot_led0 @ 关闭LED bl disable_watchdog bl disable_interrupt bl init_clock bl init_sdram 初始化SDRAM bl init_stack @ 堆栈0x34000000 bl boot_led @ 显示LED bl usart_init @ 初始化串口 bl copy_nand2sdram @ 拷贝 /////////////////////////////////////////////////// //跳转方式对了吗?是否真的跳转到SDRAM里了,两种跳转方式我都用过,都会出现死机方式 ldr pc, =main @ 调用C程序中的main函数,绝对跳转,跳转范围(整个SDRAM) #bl main @ 调用C程序中的main函数,相对跳转,跳转范围(前后32M) --------------------------------------------------------- printf只是个 “表面现象”,问题不在printf上,有人遇到过类似的现象,说是堆栈不够,我把printf代码全部注释掉也一样死机,可以断定不是堆栈问题。 查看反汇编printf的地址是0x30001eac,连接地址是0x30000000,相对地址是0x1eac > 0x1000(大于4K空间) 30001eac : int printf(const char *fmt, ...) { 30001eac: e1a0c00d mov ip, sp 30001eb0: e92d000f stmdb sp!, {r0, r1, r2, r3} 30001eb4: e92dd800 stmdb sp!, {fp, ip, lr, pc} 30001eb8: e24cb014 sub fp, ip, #20 ; 0x14 30001ebc: e24dd00c sub sp, sp, #12 ; 0xc va_list args; int printed_l 会不会我的代码运行还是在Stopping stone的【SRAM】里而不是SDRAM里,所以没有办法访问0x1eac这个地址相对地址(0x00001eac) --------------------------------------------------------- Nandflash的读/写也可以排除,我做过测试,将Stepping stone的4K内容打印出来,与烧录的文件一致,证明Nand【写】没有问题。 读取0x30000000前20K内容,与烧录文件一致,证明Nand【读】没有问题。 --------------------------------------------------------- lds文件部分内容 SECTIONS { . = 0x30000000; . = ALIGN(4); .text : { src/start.o (.text) src/copyboot.o (.text) nand/Nand_S34ML02G1.o (.text) src/board.o (.text) *(.text) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); .rodata : { *(.rodata) } . = ALIGN(4); bss_start = .; .bss : { *(.bss) } bss_end = .; } 本帖最后由 lzwml 于 2014-11-13 10:41 编辑

回复评论 (3)

1、用J-Link下载程序到SDRAM里,跳过Stepping Stone程序可以【正常运行】。
2、程序烧录到NandFlash里,重新上电,从Stepping Stone启动【不能运行】。
这两个中断向量表是一样的吗?看看是不是中断向量表的事儿呢
点赞  2014-11-13 12:44
引用: haojie5588 发表于 2014-11-13 12:44
1、用J-Link下载程序到SDRAM里,跳过Stepping Stone程序可以【正常运行】。
2、程序烧录到NandFlash里,重 ...


我已经解决了,中断向量没问题,中断自始至终关闭的

        ///////////////////////////////////////////////////
        //跳转方式对了吗?是否真的跳转到SDRAM里了,两种跳转方式我都用过,都会出现死机方式
        ldr        pc, =main   @ 调用C程序中的main函数,绝对跳转,跳转范围(整个SDRAM)
        #bl main                  @ 调用C程序中的main函数,相对跳转,跳转范围(前后32M)

确实该用ldr pc,=main跳转,当初出问题是因为代码一直使用bl  main,当切换ldr        pc, =main时候问题依旧存在,我猜测是可能没有make clean(按道理来说应该不需要clean,有空再去比较*.dis文件)
现在改好后一切正常了
点赞  2014-11-13 17:22
谢谢分享经验~
点赞  2014-11-22 13:55
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复