打印

关于“解析STM32启动过程”一文的疑问。

[复制链接]
4079|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
e2zone|  楼主 | 2013-6-15 00:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
原帖地址:https://bbs.21ic.com/icview-356121-1-1.html
疑问如下:
原文中的那个文档,其中说   “因此可以得到一条重要的信息:x8000000地址存放的是栈顶地址 __initial_sp ,0x8000004地址存放的是复位中断向量Reset_Handler(STM32使用 32 位总线,因此存储空间为 4字节对齐)”, 想问下,光从这个启动文件,__initial_sp 地址值,放到了0x800 0000位置,是如何看出来的,谢谢。

还有什么c/c++标准实时库,是什么回事,麻烦是否能给说下?并且从这段代码里,我并不能看出来程序的某条语句在什么地址,然后此汇编代码中也没有ENTRY的指示符。

如果说cortex-M3是固定上电复位以后,就是取0(片内flash和SRAM也会做映射)地址的第一个数值当做SP的值 ,然后取接下来的值做复位服务的入口,那么就是说永远都必须是,0x0地址放SP的值,0x4放ResetService的地址值了?并且编译器就知道没有ENTRY也可以。。。。。。。。。

谢谢!
沙发
john_lee| | 2013-6-15 01:38 | 只看该作者
还有什么c/c++标准实时库,是什么回事

没有这种说法。
如果说cortex-M3是固定上电复位以后,就是取0(片内flash和SRAM也会做映射)地址的第一个数值当做SP的值 ,然后取接下来的值做复位服务的入口,那么就是说永远都必须是,0x0地址放SP的值,0x4放ResetService的地址值了?

是的。

使用特权

评论回复
板凳
LDTEST| | 2013-6-15 10:36 | 只看该作者
1、0x8000000地址存放的是栈顶地址 __initial_sp ,0x8000004地址存放的是复位中断向量Reset_Handler
是这样的,至于为何没有 ENTRY ,未知,只能认为编译器把第一条 DCD 编译到了 0x8000000
2、至于如何看出来的,自己看 hex文件,或者 debug下看里面的程序
3、c/c++标准实时库  应该是 标准库, 实时恐怕是多打了两个字,里面的内容其实就是一段初始化内容,MDK这一段很绕,IAR 几乎没有
4、上电后取得地址是固定的, 编译器默认认为第一条dcd 就是?  这个有待研究

使用特权

评论回复
地板
e2zone|  楼主 | 2013-6-15 17:37 | 只看该作者
谢谢大家!

但是我还是不知道,他把这个汇编文件(启动文件),汇编的时候,生成的机器码是如何排列的(我觉得应该是按照逐条的汇编语句翻译后的机器码逐条排列)。
但是现在就有个问题了,那么编译成的最后的机器码,则必须是SP的值,然后接下来放置一条RESET_HANDLER的地址。那么汇编器是如何知道这几个值的呢?
还有个问题,就是system momory区域不是放置的是串口ISP程序么,出厂后固化的,那么自己还可以修改吗?


LDTEST:
3、c/c++标准实时库  应该是 标准库, 实时恐怕是多打了两个字,里面的内容其实就是一段初始化内容,MDK这一段很绕,IAR 几乎没有

这个标准库在什么地方?里面初始化的是什么东西?做的是什么动作?

谢谢!

使用特权

评论回复
5
zeluo| | 2013-6-15 19:11 | 只看该作者
在官网上找一找  应该有的吧   不是很了解这一块

使用特权

评论回复
6
dirtwillfly| | 2013-6-16 11:58 | 只看该作者
那个叫固件库,是把对硬件寄存器的操作都封装成函数了,更方便使用和学习

使用特权

评论回复
7
e2zone|  楼主 | 2013-6-16 14:24 | 只看该作者
dirtwillfly 发表于 2013-6-16 11:58
那个叫固件库,是把对硬件寄存器的操作都封装成函数了,更方便使用和学习 ...

我觉得他们说的那个库不是固件库。
因为那篇**中说,启动文件中的__main不是指c文件中的main函数。而是另外的一个函数,而这另外的一个函数回去调用初始化堆栈的代码,然后再回来调用c文件中的main。
现在我就是想知道,这个__main在哪里,即使不知道他的源码,也想知道他工作的过程。
谢谢!

使用特权

评论回复
8
dirtwillfly| | 2013-6-16 17:42 | 只看该作者
e2zone 发表于 2013-6-16 14:24
我觉得他们说的那个库不是固件库。
因为那篇**中说,启动文件中的__main不是指c文件中的main函数。而是 ...

我明白了,你说的是启动引导程序吧,这个程序在固件库里也有,是个扩展名为.s的一段类似汇编的程序
这个程序一般不用动,不熟悉的人也不能动,动了stm32就启动不了

使用特权

评论回复
9
e2zone|  楼主 | 2013-6-16 22:18 | 只看该作者
dirtwillfly 发表于 2013-6-16 17:42
我明白了,你说的是启动引导程序吧,这个程序在固件库里也有,是个扩展名为.s的一段类似汇编的程序
这个程 ...

呵呵,我就是想弄明白这个点s的文件,但是目前看了很多都还是不清楚。

使用特权

评论回复
10
john_lee| | 2013-6-16 23:08 | 只看该作者
从来就认为MDK的startup.s非常垃圾。

使用特权

评论回复
11
i55| | 2013-6-16 23:53 | 只看该作者
e2zone 发表于 2013-6-16 14:24
我觉得他们说的那个库不是固件库。
因为那篇**中说,启动文件中的__main不是指c文件中的main函数。而是 ...

对于STM32来说,从__main到main的过程对于iar和rvct(mdk所用的编译器)来说都是封装在.a库文件里面的,只有gcc是“裸”的,代码如下。
bss段就是rvct的ZI段,text就是RW段位于flash部分,data段就是RW位于ram的部分。
int fu_ck_mojinming; //这就是ZI段数据
int fu_ck_mojinming=1; //这就是RW段数据,fu_ck_mojinming的初值位于flash的text段,上电后要搬到ram的data段才能执行,撸主明白了么?



/***************************************************************************/
/*  ResetHandler                                                           */
/*                                                                         */
/*  This function is used for the C runtime initialisation,                */
/*  for handling the .data and .bss segments.                              */
/***************************************************************************/
void ResetHandler (void)
{
   uint32_t *pSrc;
   uint32_t *pDest;
   
   /*
    * Call the SystemInit code from CMSIS interface if available.
    * SystemInit is a week function which can be override
    * by an external function.
    */
   SystemInit();   
   
   /*
    * Set the "Vector Table Offset Register". From the ARM
    * documentation, we got the following information:
    *
    * Use the Vector Table Offset Register to determine:
    *  - if the vector table is in RAM or code memory
    *  - the vector table offset.   
    */
   *((uint32_t*)0xE000ED08) = (uint32_t)&_stext;
   
   /*
    * Copy the initialized data of the ".data" segment
    * from the flash to the are in the ram.
    */
   pSrc  = &_etext;
   pDest = &_sdata;
   while(pDest < &_edata)
   {
      *pDest++ = *pSrc++;
   }
   
   /*
    * Clear the ".bss" segment.
    */
   pDest = &_sbss;
   while(pDest < &_ebss)
   {
      *pDest++ = 0;
   }
   
   /*
    * And now the main function can be called.
    * Scotty, energie...
    */      
   main();   
   
   /*
    * In case there are problems with the
    * "warp drive", stop here.
    */
   while(1) {};   

} /* ResetHandler */

使用特权

评论回复
12
e2zone|  楼主 | 2013-6-17 01:11 | 只看该作者
i55 发表于 2013-6-16 23:53
对于STM32来说,从__main到main的过程对于iar和rvct(mdk所用的编译器)来说都是封装在.a库文件里面的, ...

现在我弄明白了__main这个函数了,这个函数是编译器生成的,用来初始化c文件中进入main函数之前需要的一些东西,比如一些全局的变量什么的,然后__main会调用c中的main。

然后您贴过来的这段代码,能给说下是什么吗?
我只能从名字上面看,去理解。这个就是复位的函数。
然后看到最后他是调用了main函数。

谢谢。

使用特权

评论回复
13
i55| | 2013-6-17 13:15 | 只看该作者
e2zone 发表于 2013-6-17 01:11
现在我弄明白了__main这个函数了,这个函数是编译器生成的,用来初始化c文件中进入main函数之前需要的一 ...

gcc的启动代码,gcc是stm32的三种编译器之一,另外两种是iar和rvct

使用特权

评论回复
14
e2zone|  楼主 | 2013-6-28 23:32 | 只看该作者
原**的疑惑:
1.烧写到flash中的位置,连接脚本中可以看到。
2.他所谓c实时库,就是指进入main函数之前的,初始化main函数以及以后的函数需要用到的一些数据。
3.可以有entry,需要写在rest_handler开始的地方,新的MDK环境不用写,是因为对此芯片有默认值。

使用特权

评论回复
15
无冕之王| | 2013-6-28 23:35 | 只看该作者
LZ的质疑习惯值得学习

使用特权

评论回复
16
hkcj| | 2013-6-29 17:45 | 只看该作者
楼主的学习精神真的很不错    需要向你学习  

使用特权

评论回复
17
e2zone|  楼主 | 2013-6-29 23:11 | 只看该作者
谢谢15楼和16楼的两位!
嘿嘿!

使用特权

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

本版积分规则

2

主题

77

帖子

1

粉丝