4. stm32启动代码分析(一)

 

硬件平台:  stm32f407ve

软件平台:  win10 (OS Name:                   Microsoft Windows 10 Enterprise

                    OS Version:                10.0.18363 N/A Build 18363)

             Keil5  5.26.2

             HAL库版本: 2.14.0(目前下载的最新的)

 

库函数的使用要得益于你本身对c语言指针,结构体,及结构体指针的认识。如果你对这些的熟悉程度不够的话,只能说会阻止你进一步前进。

硬件方面,你最好能有基本的数电模电常识,有单片机理论基础,或者微机原理理论,这样你在理解这些硬件组成,或者电路初始化流程,控制电路工作的时候能更好的接受并理解。甚至对芯片的基本结构,芯片的常用电路的使用都会有很多帮助(比如cpu,晶振电路,电源电路,复位电路等)。

学习本身是多看书,多练习。目前我们学习的知识基本可以通过反复练习得到。大家不要想着看我给大家写的文档,看一下就会了,这肯定不现实的。这无疑是等着别人嚼碎的食物残渣放到你嗷嗷待哺的嘴里,你不用嚼了,吞下去,你就饱了,仅仅是饱了而已,你并没有获得多少营养。是不是想着都觉得恶心?

所以我鼓励大家一起学,一起想,一起成长的那些人。不要做张开嘴巴等着别人喂食的人,而要开始学会自己找食物,自己去咀嚼食物,然后最终独立,越飞越高越精彩。

开始的一截确实很艰难,但是谁不是从艰难中走过来的呢?谁都不例外,你走过来了就顺利了。

系统的学习还是很重要的,零碎的看网络上的博文还是得不到真正的提升,多看书,多练习。

 

本次教程对stm32代码进行初步的分析.

 

Stm32的启动都是startup.s开始的,这是个汇编文件,它需要指定中断向量,程序入口,以及堆栈的位置,只有汇编才能完成。

 

2. 我们直接到183行的位置,看到Reset_Handler这个标号,表示是机器复位异常之后的入口地址

 

  1. 系统在这个位置调用了两个函数(SystemInit和__main(并不是我们自己写的main函数)),这个SystemInit函数都是c语言完成的。

SystemInit函数在system_stm32f4xx.c文件中,看注释的话表示这是一个初始化,对fpu(浮点数运算器),还有中断向量表和外部内存的进行了配置

 

配置的寄存器都属于rcc部分,这里可以参考《STM32F4xx中文参考手册.pdf》和《arm cortexM3和cortexM4权威指南》手册,都可以得到答案。

这是权威指南的第13章的文字描述:

 

void SystemInit(void)

{

//首先是对浮点数的支持,M4可以开启,也可以关闭,设置的内容参考上图

  /* FPU settings ------------------------------------------------------------*/

  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

  #endif

   //以下是对rcc的设置,主要是时钟的设置,恢复默认配置。见下图说明。

  /* Reset the RCC clock configuration to the default reset state ------------*/

  /* Set HSION bit */

  RCC->CR |= (uint32_t)0x00000001;

 

  /* Reset CFGR register */

  RCC->CFGR = 0x00000000;

 

  /* Reset HSEON, CSSON and PLLON bits */

  RCC->CR &= (uint32_t)0xFEF6FFFF;

 

  /* Reset PLLCFGR register */

  RCC->PLLCFGR = 0x24003010;

 

  /* Reset HSEBYP bit */

  RCC->CR &= (uint32_t)0xFFFBFFFF;

 

  /* Disable all interrupts */

  RCC->CIR = 0x00000000;

//这里是外部sram或者外部sdram的配置,我们没有使用,可以不关心

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)

  SystemInit_ExtMemCtl();

#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

//这是向量表位置指定的部分,可以将向量表指定到内存中,但一般没有使用,具体可以参考指南手册,有讲到这个向量表放在flash中能加速中断响应,也就没必要指定到内存中了。

  /* Configure the Vector Table location add offset address ------------------*/

#ifdef VECT_TAB_SRAM

  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

#else

  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */

#endif

}

 

 

 

下图是rcc时钟寄存器的配置,是来自《STM32F4xx中文参考手册》,里面有详细的中文说明,具体含义可以参考一下,包括寄存器的配置也是可以参考该手册的。

 

 

调用了systemInit函数之后,我们看到时钟默认选择了内部rc振荡器时钟,就是16MHz。外部时钟没有使能,PLL也关闭了。

 

这里我需要说的一个概念是SOC(system on chip),stm32这类都是SOC了,在芯片内部,除了cpu本身之外,还有各种控制器等一些器件,这样就组合成了片上系统(SOC),以下谈到的器件都是指片上器件(指芯片上除了cpu之外的其他功能电路单元)。

 

时钟树在整stm32单片机都是比较重要的一块。时钟频率在不同的器件上可能不同,比如内核(cpu)的时钟就是最高的,它需要尽快的去执行指令。其次一些外部设备可能就不需要很高的频率,比如串口通信的uart,iic等,这些设备都是慢速设备,根本不需要很高的频率了,所以在这个芯片上,不同的器件有不同的工作时钟频率,当然这里的不同频率就会涉及到不同的总线(如AHB,APB等)。

 

一个要考虑的就是频率越高,设计的电路越复杂,成本也越高。

另外一个需要考虑的问题,当然就是功耗问题,频率越高,功耗也越大。

这些都是嵌入式设备需要考虑的部分,所以不可能将一个嵌入式芯片设计为一个时钟频率,这样的话就会涉及到时钟树的问题,不同的器件使用不同的频率。当然结构上来说,他还有PLL电路,可以根据自己的实际需要,让cpu运行在一个适当的频率上,既达到功能的需求,也达到最佳的功耗(满足低功耗,或者让设备在电池工作的情况下工作的时间更长)。

 

Pll电路是用来倍频的。外部的晶振只有25MHz(一般比较低,减少PCB电路设计的复杂度,减少电路的电磁辐射,频率低价格也便宜),经过PLL电路之后,到达cpu的频率可以到达168MHz(stm32f407)

 

现在很多单片机内部都会设计一个rc(电容电阻)震荡电路,提供给cpu工作脉冲(数字电路需要时钟脉冲驱动计算),这个电路一般频率不高,在时钟频率稳定要求不高的场合可以使用。但是RC电路本身受温度的影响比较大,频率变化比较大,所以一般都会使用外部晶体振荡器,保证在对时钟要求高的通信电路中正常使用。

 

所有stm32单片机在启动的时候还是可以使用内部振荡器开始工作,之后设置好外部晶振之后就可以使用外部晶振工作了。(对于stm32单片机,使用外部晶振会增加一些功耗,同时还有两个IO引脚被用于晶振对路,就不能用作普通IO端口了)。

 

 

之后调用__main函数,这是一段不公开的库函数,最终会调用我们自己写的main函数。我没有具体分析过这段代码的功能,因为是汇编,还比较长。

可以使用调试的方法把这段汇编找到。

0x08000188 F000F802  BL.W          __scatterload (0x08000190)
0x0800018C F000F83C  BL.W          __rt_entry (0x08000208)
0x08000190 A00A      ADR           r0,{pc}+4  ; @0x080001BC
0x08000192 E8900C00  LDM           r0,{r10-r11}
0x08000196 4482      ADD           r10,r10,r0
0x08000198 4483      ADD           r11,r11,r0
0x0800019A F1AA0701  SUB           r7,r10,#0x01
0x0800019E 45DA      CMP           r10,r11
0x080001A0 D101      BNE           0x080001A6
0x080001A2 F000F831  BL.W          __rt_entry (0x08000208)
0x080001A6 F2AF0E09  ADR.W         lr,{pc}-0x07  ; @0x0800019F
0x080001AA E8BA000F  LDM           r10!,{r0-r3}
0x080001AE F0130F01  TST           r3,#0x01
0x080001B2 BF18      IT            NE
0x080001B4 1AFB      SUBNE         r3,r7,r3
0x080001B6 F0430301  ORR           r3,r3,#0x01
0x080001BA 4718      BX            r3
0x080001BC 2050      DCW           0x2050
0x080001BE 0000      DCW           0x0000
0x080001C0 2070      DCW           0x2070
0x080001C2 0000      DCW           0x0000
0x080001C4 3A10      SUBS          r2,r2,#0x10
0x080001C6 BF24      ITT           CS
0x080001C8 C878      LDMCS         r0!,{r3-r6}
0x080001CA C178      STMCS         r1!,{r3-r6}
0x080001CC D8FA      BHI           __scatterload_copy (0x080001C4)
0x080001CE 0752      LSLS          r2,r2,#29
0x080001D0 BF24      ITT           CS
0x080001D2 C830      LDMCS         r0!,{r4-r5}
0x080001D4 C130      STMCS         r1!,{r4-r5}
0x080001D6 BF44      ITT           MI
0x080001D8 6804      LDRMI         r4,[r0,#0x00]
0x080001DA 600C      STRMI         r4,[r1,#0x00]
0x080001DC 4770      BX            lr
0x080001DE 0000      MOVS          r0,r0
0x080001E0 2300      MOVS          r3,#0x00
0x080001E2 2400      MOVS          r4,#0x00
0x080001E4 2500      MOVS          r5,#0x00
0x080001E6 2600      MOVS          r6,#0x00
0x080001E8 3A10      SUBS          r2,r2,#0x10
0x080001EA BF28      IT            CS
0x080001EC C178      STMCS         r1!,{r3-r6}
0x080001EE D8FB      BHI           0x080001E8
0x080001F0 0752      LSLS          r2,r2,#29
0x080001F2 BF28      IT            CS
0x080001F4 C130      STMCS         r1!,{r4-r5}
0x080001F6 BF48      IT            MI
0x080001F8 600B      STRMI         r3,[r1,#0x00]
0x080001FA 4770      BX            lr
                 main:
0x080001FC B51F      PUSH          {r0-r4,lr}
                 main:
0x080001FE F001FCFF  BL.W          _fp_init (0x08001C00)
                 main:
0x08000202 BD1F      POP           {r0-r4,pc}
                 main:
0x08000204 B510      PUSH          {r4,lr}
                 main:
0x08000206 BD10      POP           {r4,pc}
                 main:
0x08000208 F000F8B8  BL.W          __user_setup_stackheap (0x0800037C)
0x0800020C 4611      MOV           r1,r2
                 main:
0x0800020E F7FFFFF5  BL.W          __rt_lib_init (0x080001FC)
                 main:
0x08000212 F001FA03  BL.W          main (0x0800161C)



__main:
0x08000130 F000F802  BL.W     __scatterload_rt2_thumb_only (0x08000138)
0x08000134 F000F83C  BL.W     __rt_entry_sh (0x080001B0)
                 __scatterload_rt2_thumb_only:
0x08000138 A00A      ADR      r0,{pc}+4  ; @0x08000164
0x0800013A E8900C00  LDM      r0,{r10-r11}
0x0800013E 4482      ADD      r10,r10,r0
0x08000140 4483      ADD      r11,r11,r0
0x08000142 F1AA0701  SUB      r7,r10,#0x01
                 __scatterload_null:
0x08000146 45DA      CMP      r10,r11
0x08000148 D101      BNE      0x0800014E
0x0800014A F000F831  BL.W     __rt_entry_sh (0x080001B0)
0x0800014E F2AF0E09  ADR.W    lr,{pc}-0x07  ; @0x08000147
0x08000152 E8BA000F  LDM      r10!,{r0-r3}
0x08000156 F0130F01  TST      r3,#0x01
0x0800015A BF18      IT       NE
0x0800015C 1AFB      SUBNE    r3,r7,r3
0x0800015E F0430301  ORR      r3,r3,#0x01
0x08000162 4718      BX       r3
0x08000164 0298      LSLS     r0,r3,#10
0x08000166 0000      MOVS     r0,r0
0x08000168 02B8      LSLS     r0,r7,#10
0x0800016A 0000      MOVS     r0,r0
                 __scatterload_copy:
0x0800016C 3A10      SUBS     r2,r2,#0x10
0x0800016E BF24      ITT      CS
0x08000170 C878      LDMCS    r0!,{r3-r6}
0x08000172 C178      STMCS    r1!,{r3-r6}
0x08000174 D8FA      BHI      __scatterload_copy (0x0800016C)
0x08000176 0752      LSLS     r2,r2,#29
0x08000178 BF24      ITT      CS
0x0800017A C830      LDMCS    r0!,{r4-r5}
0x0800017C C130      STMCS    r1!,{r4-r5}
0x0800017E BF44      ITT      MI
0x08000180 6804      LDRMI    r4,[r0,#0x00]
0x08000182 600C      STRMI    r4,[r1,#0x00]
0x08000184 4770      BX       lr
0x08000186 0000      MOVS     r0,r0
                 __scatterload_zeroinit:
0x08000188 2300      MOVS     r3,#0x00
0x0800018A 2400      MOVS     r4,#0x00
0x0800018C 2500      MOVS     r5,#0x00
0x0800018E 2600      MOVS     r6,#0x00
0x08000190 3A10      SUBS     r2,r2,#0x10
0x08000192 BF28      IT       CS
0x08000194 C178      STMCS    r1!,{r3-r6}
0x08000196 D8FB      BHI      0x08000190
0x08000198 0752      LSLS     r2,r2,#29
0x0800019A BF28      IT       CS
0x0800019C C130      STMCS    r1!,{r4-r5}
0x0800019E BF48      IT       MI
0x080001A0 600B      STRMI    r3,[r1,#0x00]
0x080001A2 4770      BX       lr
                 __rt_lib_init:
0x080001A4 B51F      PUSH     {r0-r4,lr}
0x080001A6 F3AF8000  NOP.W    
                 __rt_lib_init_user_alloc_1:
0x080001AA BD1F      POP      {r0-r4,pc}
                 __rt_lib_shutdown:
0x080001AC B510      PUSH     {r4,lr}
                 __rt_lib_shutdown_user_alloc_1:
0x080001AE BD10      POP      {r4,pc}
                 __rt_entry_sh:
0x080001B0 F000F82F  BL.W     __user_setup_stackheap (0x08000212)
0x080001B4 4611      MOV      r1,r2
                 __rt_entry_postsh_1:
0x080001B6 F7FFFFF5  BL.W     __rt_lib_init (0x080001A4)
                 __rt_entry_postli_1:
0x080001BA F000F919  BL.W     main (0x080003F0)

 

 

 

 

github的工程源码:

https://github.com/zhaozhi0810/stm32f407_hal_keil5

 

发布了24 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhaozhi0810/article/details/104233837
今日推荐