打印

奇怪程序还没有执行RAM里居然有数据?????

[复制链接]
3539|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
itelectron|  楼主 | 2011-1-2 23:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
香水城| | 2011-1-3 10:28 | 只看该作者
非常正常的现象,一点也不奇怪,:lol

使用特权

评论回复
板凳
itelectron|  楼主 | 2011-1-3 17:58 | 只看该作者
?????香板
难道在PC 到达0X000000之前 就把 ROM里的 DATA COPY到ARM 里面了?????

使用特权

评论回复
地板
香水城| | 2011-1-3 18:16 | 只看该作者
?????香板
难道在PC 到达0X000000之前 就把 ROM里的 DATA COPY到ARM 里面了?????
itelectron 发表于 2011-1-3 17:58


你在RAM中看到的是ROM里的DATA吗?

使用特权

评论回复
5
itelectron|  楼主 | 2011-1-3 21:08 | 只看该作者
不知道?只看到RAM  有数据 但不知道这个数据是 那里来的  一般程序的开始 我会写 一个程序清除RAM
但是 看到程序未执行 RAM 里 就有数据了  现在 就不知道该不该清RAM

使用特权

评论回复
6
itelectron|  楼主 | 2011-1-5 21:36 | 只看该作者
:shutup:

使用特权

评论回复
7
itelectron|  楼主 | 2011-1-5 21:57 | 只看该作者
是  STM32  的   BOOTLOAD  在做怪?

如果我想自己写 BOOTLOAD   STM32 的 芯片是否允许?

使用特权

评论回复
8
itelectron|  楼主 | 2011-1-5 22:06 | 只看该作者
本帖最后由 itelectron 于 2011-1-5 22:10 编辑

转载的  感觉 有 错误  特别是 贴的 图   STM32  好象不能 从 0X00执行程序 只能从0X8000000  开始 执行!


STM32启动代码概述
发布: 2009-5-20 16:00 | 作者: hnrain | 查看: 1013次

一般嵌入式开发流程就是先建立一个工程,再编写源文件,然后进行编译,把所有的*.s文件和*.c文件编译成一个*.o文件,再对目标文件进行链接和定位,编译成功后会生成一个*.hex文件和调试文件,接下来要进行调试,如果成功的话,就可以将它固化到flash里面去。

启动代码是用来初始化电路以及用来为高级语言写的软件作好运行前准备的一小段汇编语言,是任何处理器上电复位时的程序运行入口点。

比如,刚上电的过程中,PC机会对系统的一个运行频率进行锁定在一个固定的值,这个设计频率的过程就是在汇编源代码中进行的,也就是在启动代码中进行的。与此同时,设置完后,程序开始运行,注意,程序是在内存中运行的。这个时候,就需要把一些源文件从flash里面copy到内存中,又要对它们进行初始化读写,这又有频率的设置。这些都是初始化。

初始化完成后,我们又要设置一些堆栈,要跳到C语言的main函数里面运行。这就需要堆栈。对普通的ARM CPU有这样一个要求:在绝对地址为零的地方要放置一个异常向量表,但并不是所有的ARM CPU都留有这个一个空间,这就需要用到映射的功能。我们可以将其它地方的一些空间映射到绝对地址里面。当发生异常时,ARM核来读取异常中断表的时候,它会使用映射之后的那个表,这个就可以接着往下执行,否则在绝对地址零的地方找不到任何信息,程序就会死掉。这些运行的环境全部建立好后,程序就会跳转到我们的main函数里面。

总之,启动代码,就是对最小系统的初始化。包括晶振,CPU频率等。

启动代码的最小系统是:异常向量表的初始化–存储区分配–初始化堆栈–高级语言入口函数调用– main()函数。

程序的启动过程:








以下面这个例子为例,编译完后,DEBUG后,我们可以看到,光标指向绝对地址为零的地方,这里存放的就是一个异常向量表。







它对应在startup.s里的源文件如下:







单步运行后,马上跳转到初始化CPU的频率。即初始化锁相环,将其锁在一个固定的频率。具体代码如下:

; Setup PLL

               IF     PLL_SETUP <> 0

               LDR    R0, =PLL_BASE

               MOV    R1, #0xAA

               MOV    R2, #0x55



; Configure and Enable PLL

               MOV    R3, #PLLCFG_Val

               STR    R3, [R0, #PLLCFG_OFS]

               MOV    R3, #PLLCON_PLLE

               STR    R3, [R0, #PLLCON_OFS]

               STR    R1, [R0, #PLLFEED_OFS]

               STR    R2, [R0, #PLLFEED_OFS]



; Wait until PLL Locked

PLL_Loop       LDR    R3, [R0, #PLLSTAT_OFS]

               ANDS   R3, R3, #PLLSTAT_PLOCK

               BEQ    PLL_Loop



; Switch to PLL Clock

               MOV    R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)

               STR    R3, [R0, #PLLCON_OFS]

               STR    R1, [R0, #PLLFEED_OFS]

               STR    R2, [R0, #PLLFEED_OFS]

               ENDIF  ; PLL_SETUP



然后再初始化每一种模式的堆栈,再进行单步运行的时候,下面我们可以看到,它自动跳转到main()函数:

; Enter the C code



               IMPORT __main

               LDR    R0, =__main

               BX     R0





               IF     :DEF:__MICROLIB



               EXPORT __heap_base

               EXPORT __heap_limit



               ELSE



这个时候,程序会运行各种scatterload函数,将我们的堆栈、全局变量等内容拷贝到内存中去。拷贝完后,就正式跳转到我们的main()函数中来执行了。







这就是启动代码执行的全过程,呵呵,平时我们看到以为只是执行main()函数就行了,是不是没有想到在执行 main() 函数后还有这么多学问呢?

使用特权

评论回复
9
香水城| | 2011-1-6 10:59 | 只看该作者
其实你看到的这种现象,有可能是Bootloader在作怪,还有一种可能是芯片上电后RAM的内容本身就是随机的。

使用特权

评论回复
10
itelectron|  楼主 | 2011-1-6 11:37 | 只看该作者
还有一种可能是芯片上电后RAM的内容本身就是随机的。
-----------------------------------------------------------------------------

如果是这样的话 恐怕 会出现 BUG 吧!
以前写程序都习惯 在程序的开始 清RAM

如 51


INIT:                               
        MOV        R0, #RAM_Len  ;RAM_Len                EQU        07FH               
        CLR        A                       
Clear RAM:                               
        MOV        @R0, A                       
        DJNZ        R0, Clear RAM

使用特权

评论回复
11
ST_ARM| | 2011-1-6 12:01 | 只看该作者
STM32的上电时,RAM的内容试随机,绝大多数的MCU里RAM在上电时,RAM里的内容时随机的,楼主在学习单片机时没有认真看书中的每一句话。

学习不认真,打屁股!!!

使用特权

评论回复
12
itelectron|  楼主 | 2011-1-6 12:55 | 只看该作者
本帖最后由 itelectron 于 2011-1-6 13:07 编辑

回LS

偶一清 内存  发生 就跳 13 楼中断里了 :L
#define F103VE_RAM_END ((u32)0x2000FFFF) /* STM32F103VE_RAM_END_ADDR */
#define F103VE_RAM_START (*((u32*)(0x20000000))) //
#define RAM_Size ((0xFFFF+1)/4)
void F103VE_RamClear(void)
{        u32 RAM_Cnt;
        u32 *P_RAM_START=&F103VE_RAM_START;
        for(RAM_Cnt=0x00000000;RAM_Cnt<RAM_Size;RAM_Cnt++) //0xFFFF+1/4=0x4000
        {
                (*(P_RAM_START+RAM_Cnt))=0x00000000;
        }
}

使用特权

评论回复
13
itelectron|  楼主 | 2011-1-6 12:57 | 只看该作者
void HardFaultException(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}

使用特权

评论回复
14
香水城| | 2011-1-6 14:07 | 只看该作者
12楼这段程序本身占用了一些RAM区,你清除所有RAM单元时破坏了这段程序需要的RAM,不产生问题才怪呢。

使用特权

评论回复
15
pkat| | 2011-1-6 16:26 | 只看该作者
不奇怪

使用特权

评论回复
16
itelectron|  楼主 | 2011-1-6 18:15 | 只看该作者
TO  14  偶知道  所以 偶想改成用 寄存器:lol

不过实际上是  执行完  清RAM代码 后 在执行若干 语句 才出现 错误中断


        for(RAM_Cnt=0x120;RAM_Cnt<RAM_Size;RAM_Cnt++) //0xFFFF+1/4=0x4000
        {

                (*(P_RAM_START+RAM_Cnt))=0x00000000;

        }

使用特权

评论回复
17
itelectron|  楼主 | 2011-1-6 18:16 | 只看该作者
把16  楼的  RAM_Cnt=0x0000000改成   RAM_Cnt=0x120  就OK了

使用特权

评论回复
18
itelectron|  楼主 | 2011-1-6 18:19 | 只看该作者
其实感觉 STM32  的 启动部分 不够 透明

不象2440 那样清楚

使用特权

评论回复
19
itelectron|  楼主 | 2011-1-6 18:21 | 只看该作者
不过 问题  依旧 没有彻底 解决  请问 香版有  详细些的 STM32  BOOTLOAD  的文档么?

使用特权

评论回复
20
itelectron|  楼主 | 2011-1-6 18:22 | 只看该作者
还有一个不是很明白  ST  公司 为什么 不公布下 BOOTLOAD 固件程序。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:MARK: zhi kan ji shu

274

主题

2762

帖子

8

粉丝