北京pk10开奖号码查询,pk10直播9号彩票网,北京pk10开奖直播号彩票网,北京赛车pk10直播9号彩票网,www.agbgames.com pk10开奖

Baidu

北京pk10开奖号码查询9号彩票 万利彩票 熊猫彩票 98彩票 www.agbgames.com博乐彩票 云鼎彩票 快赢彩票 快赢彩票 永利彩票 趣彩彩票 金巴黎彩票 广发彩票 葡京彩票 顺发彩票 鸿利彩票 聚富彩票 我赢彩票 大发彩票 财神汇彩票 苹果彩票 欢乐彩票 大唐彩票 盛兴彩票 智博彩票 环球彩票 金彩彩票 彩盈彩票 丰亿彩票 金沙彩票 www.agbgames.com金福彩票 大运彩票 万彩会彩票 大乐购彩票 宏发彩票 八八彩票 金凤凰彩票 易发彩票 豪门会彩票 迪士尼彩票 众彩彩票 丰亿彩票 大世纪彩票 创元彩票 鑫彩网彩票 大无限彩票 利来彩票 华夏彩票 金砖彩票 大金彩票 千禧彩票 全迅彩票 菠萝彩票 大赢家彩票 华人彩票 通博彩票 万家彩票 盛世彩票 福布斯彩票 鼎盛彩票www.agbgames.com 澳彩网彩票 东方彩票 新世佳彩票 皇冠彩票 港龙彩票 迅雷彩票 幸运飞艇开奖 幸运飞艇彩票 幸运飞艇官网 幸运飞艇技巧 幸运飞艇开户 幸运飞艇代理 幸运飞艇开奖记录幸运飞艇开奖直播 幸运飞艇开奖记录查询 www.agbgames.com幸运飞艇投注平台 幸运飞艇计划软件 凤凰娱乐 500万彩票 E时彩 88彩票 J8彩票 5颗星彩票 W彩票网 M5彩票 天天彩票 彩客网彩票 好彩头彩票 彩票在线 www.agbgames.com乐彩网彩票 GT彩票 投彩彩票 中华彩票 568彩票 快开彩票 18彩票 传奇彩票 网易彩票 幸运彩票 e乐彩 彩票控 状元彩票 拉菲彩票 999彩票 杏彩彩票 东方彩票 皇族彩票 qq彩票 金誉彩票 爱投彩票 人人彩票 爱购彩 众购彩票 盈彩娱乐 彩票王 非凡彩票 五洲尚合彩票 www.agbgames.com快开彩票 彩盈线上娱乐 富利娱乐 传奇娱乐 全民彩票北京pk10开奖号码查询

简析STM32的启动过程

来源:网络整理 作者:2017年04月18日 16:08
[导读] 当前的嵌入式应用程序开发过程里,C语言已成为了绝大部分场合的最佳选择。如此一来main函数似乎成为了理所当然的起点——因为C程序往往从main函数开始执行
关键词:STM32

  当前的嵌入式应用程序开发过程里,C语言已成为了绝大部分场合的最佳选择。如此一来main函数似乎成为了理所当然的起点——因为C程序往往从main函数开始执行。但一个经常会被忽略的问题是:微控制器(单片机)上电后,是如何寻找到并执行main函数的呢?很显然微控制器无法从硬件上定位main函数的入口地址,因为使用C语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,这样一来main函数的入口地址在微控制器的内部存储空间中不再是绝对不变的。相信读者都可以回答这个问题,答案也许大同小异,但肯定都有个关键词,叫“启动文件”,用英文单词来描述是“Bootloader”。

  无论性能高下,结构简繁,价格贵贱,每一种微控制器(处理器)都必须有启动文件,启动文件的作用便是负责执行微控制器从“复位”到“开始执行main函数”中间这段时间(称为启动过程)所必须进行的工作。最为常见的51,AVR或MSP430等微控制器当然也有对应启动文件,但开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main函数开始进行应用程序的设计即可。

简析STM32的启动过程

  关于“启动模式”

  话题转到STM32微控制器,无论是keil uvision4还是IAR EWARM开发环境,ST公司都提供了现成的直接可用的启动文件,程序开发人员可以直接引用启动文件后直接进行C应用程序的开发。这样能大大减小开发人员从其它微控制器平台跳转至STM32平台,也降低了适应STM32微控制器的难度(对于上一代ARM的当家花旦ARM9,启动文件往往是第一道难啃却又无法逾越的坎)。 相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC =0x000000)同时中断向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况:

  1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;

  2、 通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;

  3、 通过boot引脚设置可以将中断向量表定位于内置Bootloader区,本文不对这种情况做论述;

  Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。

  细说STM32的启动过程

  下面就从ST的启动文件说起,由于库中的startup_stm32f10x_md.s与编译环境有关,所以针对的是库中的

  STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\TrueSTUDIO路径下的文件进行分析。

  system_stm32f10x.c

  SystemInit():在“startup_stm32f10x_xx.s”文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有 flash的设定),这个函数会在系统复位之后首先被执行。文件中默认的一些设置:允许HSE(外部时钟),FLASH(允许预取缓冲区,设置2个等待周 期),PLL系数为9,开启PLL并选择PLL输出作为时钟源(SYSCLK),后续设置SYSCLK = HCLK = APB2 = 72MHz,APB1 = HCLK/2 = 36MHz,HCLK即AHB的时钟。

  SystemCoreClockUpdate():在系统时钟HCLK变化的时候调用,以更新一个全局变量SystemCoreClock,这个变量可以为应用程序使用,必须保证正确。默认不调用这个函数,因为SystemCoreClock默认被设置为设定的频率了(72MHz)

  另外,下面这种设置寄存器的方法值得借鉴,先用位名清除相应的位,再进行设置,例如:

  #define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!《 PLL entry clock source */

  #define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!《 HSE divider for PLL entry */

  #define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!《 PLLMUL[3:0] bits (PLL mulTIplicaTIon factor) */

  #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!《 HSE clock selected as PLL entry clock source */

  #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!《 PLL input clock*9 */

  /* PLL configuraTIon: PLLCLK = HSE * 9 = 72 MHz */

  RCC-》CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));

  RCC-》CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

  startup_stm32f10x_md.s:(针对F103RBT6为中容量的产品)

  这个文件里面首先定义了复位中断(复位入口矢量被硬件固定在地址0x0000_0004)的处理函数:Reset_Handler,它的作用就是将保存于flash中的初始化数据复制到sram中,调用上面说到的SystemInit来初始化时钟,接着跳转到main执行。

  接着定义了Default_Handler, 这个是作为其他所有中断的默认处理函数,作用就是死循环,所以你假如开启了某个中断,请按照这里面的中断函数名给它写中断处理函数,例如串口中断处理函数名是 USART1_IRQHandler,你开了串口中断,如果不重写USART1_IRQHandler,就默认执行Default_Handler,死循环了。而如果你有重写,那么中断向量表中的处理函数的地址就会更新为你自己写的那个函数的地址了。为什么会这样呢?因为此文件的末尾用了类似这样的语句:

  .weak USART1_IRQHandler

  .thumb_set USART1_IRQHandler,Default_Handler

  它给中断处理函数提供了弱(weak)别名(Default_Handler),如果不重写,中断了默认执行Default_Handler,如果重写了,因为是弱别名,所以会被你写的同名函数覆盖。

  最后定义了一个中断向量表的段(.secTIon .isr_vector,“a”,%progbits),这个表将会放置在0x0000 0000那里,第二个字(0x0000 0004)是复位向量,复位之后从这地址所指的函数执行。

  那么,如何保证.isr_vector这个段将放在flash的最开始(0x08000000)呢?这就需要链接脚本了,即我们用的那个stm32_flash.ld文件了,查看一下就知道了,里面先定义了堆栈的地址:

  _estack

  /* Highest address of the user mode stack */

  _estack = 0x20005000; /* end of 20K RAM */

  接着定义了堆和栈的大小:

  /* Generate a link error if heap and stack don‘t fit into RAM */

  _Min_Heap_Size = 0; /* required amount of heap */

  _Min_Stack_Size = 0x100; /* required amount of stack */

  接着声明了各个内存的区域(定义了几个代表某个线性空间的名字,如下面的FLASH):

  /* Specify the memory areas */

  MEMORY

  {

  FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K

  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K

  MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K }

  接着下面再介绍上面这三个名字里面都放了什么东西,首先是FLASH的:

  /* Define output sections */

  SECTIONS

  {

  /* The startup code goes first into FLASH */

  .isr_vector :

  {

  。 = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */

  。 = ALIGN(4); } 》FLASH

  /* The program code and other data goes into FLASH */

  .text :

  {

  。 = ALIGN(4); *(.text) /* .text sections (code) */

  *(.text*) /* .text* sections (code) */

  *(.rodata) /* .rodata sections (constants, strings, etc.) */

  *(.rodata*) /* .rodata* sections (constants, strings, etc.) */

  *(.glue_7) /* glue arm to thumb code */

  *(.glue_7t) /* glue thumb to arm code */

  KEEP (*(.init))

  KEEP (*(.fini))

  。 = ALIGN(4); _etext = 。; /* define a global symbols at end of code */

  } 》FLASH

  可以看到startup_stm32f10x_md.s中定义的这个段.isr_vector确实放在了最开头的位置。

  但是我们前面说复位向量在0x0000 0004,现在其地址是在flash中,所以地址是0x0800 0004,这个怎么回事呢?原来,stm32可以通过boot0、boot1引脚的配置将flash映射到0x0000 0000处。具体可参考stm32的用户手册2.4节。

  从主闪存存储器启动(BOOT0 = 0,BOOT1 = X):主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(0x0800 0000)访问它,即闪存存储器的内容可以在两个地址区域访问,0x0000 0000或0x0800 0000。

  至此,整个STM32的启动过程以及程序结构都可以比较清晰了。

相关阅读

发表评论

elecfans网友

分享到:

用户评论(0

推荐阅读

每月人物

狗尾草严汉明:智能家居的AI痛点与语音解决方案落地项目

狗尾草严汉明:智能家居的AI痛点与语音解决方案落地项目
狗尾草科技有限公司COO严汉明认为,智能家居之前火不起来,有几个原因:智能家居成本太高,消费者对其的认知度还不够,交互感不够好。今年具备AI的...

紫光赵伟国:10年内成为全球记忆体前五大业者

紫光赵伟国:10年内成为全球记忆体前五大业者
外界多视紫光集团董事长赵伟国为中国发展半导体领军人物,他近期接受Nikkei Asian Review专访时,提到两个发展重要目标,第一,在行动芯片业务方面,要在...

每周排行

  • 型 号
  • 产品描述
pk10开奖记录 pk10开奖直播www.agbgames.com pk10直播 pk10官网 pk10开奖 pk10论坛 pk10技巧 pk10助赢软件 pk10杀号 pk10杀号软件 pk10冠亚军玩法 pk10冠军玩法 pk10玩法攻略www.agbgames.com pk10玩法规则 pk10中奖规则 pk10定位胆玩法 pk10彩赔率多少 pk10走势 pk10开户 pk10开奖记录百度9号彩票网 pk10开奖号码查询 pk10开奖直播 pk10计划群www.agbgames.com pk10玩法 pk10网站 pk10玩法介绍 pk10后二 pk10改单 pk10开奖直播百度9号彩票网 pk10qq群 pk10稳赚 pk10分析软件 pk10群 pk10平台网址 pk10赚钱 pk10综合走势图www.agbgames.com pk10遗漏 pk10人工计划 pk10投注技巧 pk10直播百度9号彩票网 pk10开奖时间 pk10评测 pk10平台评测网 pk10网站制作 pk10现场开奖 pk10官方开奖www.agbgames.com pk10地址 北京赛车pk10开奖记录 北京赛车pk10开奖直播 北京赛车pk10直播 北京赛车pk10官网 pk10官网百度9号彩票网 北京赛车pk10开奖 北京赛车pk10论坛 北京赛车pk10技巧 北京pk10玩法规则 北京赛车pk10助赢软件 北京赛车pk10杀号 北京赛车pk10杀号软件 北京赛车pk10冠亚军玩法 北京赛车pk10冠军玩法www.agbgames.com 北京赛车pk10玩法攻略 北京赛车pk10中奖规则 pk10开奖百度9号彩票网 pk10论坛百度9号彩票网 北京赛车pk10定位胆玩法 北京赛车pk10彩赔率多少 北京赛车pk10走势 北京赛车pk10开户 北京赛车pk10开奖号码查询 北京赛车pk10开奖直播 北京赛车pk10计划群 北京赛车pk10玩法 北京赛车pk10网站www.agbgames.com pk10技巧百度9号彩票网 pk10助赢软件百度9号彩票网 pk10杀号百度9号彩票网 pk10杀号软件百度9号彩票网 北京赛车pk10玩法介绍 北京赛车pk10后二 北京赛车pk10改单 北京赛车pk10qq群 北京赛车pk10稳赚 北京赛车pk10分析软件 北京赛车pk10群 北京赛车pk10平台网址 pk10玩法规则百度9号彩票网www.agbgames.com pk10中奖规则百度9号彩票网 pk10定位胆玩法百度9号彩票网 北京赛车pk10赚钱 北京赛车pk10综合走势图 北京赛车pk10遗漏 北京赛车pk10人工计划 北京赛车pk10投注技巧 北京赛车pk10开奖时间 北京赛车pk10评测 北京赛车pk10平台评测网 北京赛车pk10网站制作 pk10走势百度9号彩票网 北京赛车pk10现场开奖www.agbgames.com 北京赛车pk10官方开奖 北京赛车pk10地址 北京pk10开奖记录 北京pk10开奖直播 北京pk10直播 北京pk10官网 北京pk10开奖 北京pk10论坛 北京pk10技巧 北京pk10玩法规则 北京pk10助赢软件 北京pk10杀号 北京pk10杀号软件 pk10开户百度9号彩票网www.agbgames.com 北京pk10冠亚军玩法 北京pk10冠军玩法 北京pk10玩法攻略 北京pk10中奖规则 北京pk10定位胆玩法 pk10冠军玩法百度9号彩票网 北京pk10彩赔率多少 北京pk10走势 北京pk10开户 北京pk10开奖号码查询 北京pk10开奖直播 pk10彩赔率多少百度9号彩票网 北京pk10计划群 北京pk10玩法 北京pk10网站www.agbgames.com 北京pk10玩法介绍 北京pk10后二 北京pk10改单 北京pk10qq群 北京pk10稳赚 北京pk10分析软件 北京pk10群 北京pk10平台网址 北京pk10赚钱 pk10冠亚军玩法百度9号彩票网 pk10玩法攻略百度9号彩票网 北京pk10综合走势图 北京pk10遗漏 北京pk10人工计划 北京pk10投注技巧 北京pk10开奖时间 北京pk10评测www.agbgames.com 北京pk10平台评测网 北京pk10网站制作 北京pk10现场开奖 北京pk10官方开奖 北京pk10地址 北京赛车pk拾开奖记录 北京赛车pk拾开奖直播 北京赛车pk拾直播 北京赛车pk拾官网 北京赛车pk拾开奖 北京赛车pk拾论坛 北京赛车pk拾技巧 北京pk10玩法规则 北京赛车pk拾助赢软件 北京赛车pk拾杀号www.agbgames.com 北京赛车pk拾杀号软件 北京赛车pk拾冠亚军玩法 北京赛车pk拾冠军玩法 北京赛车pk拾玩法攻略 北京赛车pk拾中奖规则 北京赛车pk拾定位胆玩法 北京赛车pk拾彩赔率多少 北京赛车pk拾走势 北京赛车pk拾开户 北京赛车pk拾开奖号码查询 北京赛车pk拾开奖直播 北京赛车pk拾计划群 北京赛车pk拾玩法 北京赛车pk拾网站 北京赛车pk拾玩法介绍www.agbgames.com 北京赛车pk拾后二 北京赛车pk拾改单 北京赛车pk拾qq群 北京赛车pk拾稳赚 北京赛车pk拾分析软件 北京赛车pk拾群 北京赛车pk拾平台网址 北京赛车pk拾赚钱 北京赛车pk拾综合走势图 北京赛车pk拾遗漏 北京赛车pk拾人工计划 北京赛车pk拾投注技巧 北京赛车pk拾开奖时间 北京赛车pk拾评测 北京赛车pk拾平台评测网www.agbgames.com 北京赛车pk拾网站制作 北京赛车pk拾现场开奖 北京赛车pk拾官方开奖 北京赛车pk拾地址