stm32启动代码分析

(2012-06-12 09:43:31)

   
最近开始使用ST的stm32w108芯片(也是一款zigbee芯片)。开始看他的启动代码看的晕晕呼呼呼的
还好在csdn上看到一片文章写的不错,分享下:
文章转载至:http://blog.chinaunix.net/uid-2595338-id-2139588.html,感谢原作者!
 
使用的芯片是 STM32F103VET,编译器使用 IAR ARM V5.5
 
设置头文件查找路径,例如:
$PROJ_DIR$\..\
$PROJ_DIR$\..\..\..\Libraries\CMSIS\CM3\CoreSupport
$PROJ_DIR$\..\..\..\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x
$PROJ_DIR$\..\..\..\Libraries\STM32F10x_StdPeriph_Driver\inc
 
预定义的symbol 为,HD为high desity 的意思
USE_STDPERIPH_DRIVER
STM32F10X_HD
 
有两个符号是系统默认的,看名字就应该知道什么了。
$TOOLKIT_DIR$\ $PROJ_DIR$\
 
注意GPIO的端口操作是 16位的,否则送的数据无效
GPIOB_ODR = (uint16_t)0xff
 
__iar_program_start 是一个系统定义的标号,在自带的C库启动代码当中,IAR会自动连接到当然了,也可以自己定义一个
 
EXTERN __iar_program_start
        LDR R0, =__iar_program_start
        BX R0
 
另外一个必须有的符号就是 __vector_table 使用方法是
        SECTION .intvec:CODE:NOROOT(2) 
        PUBLIC __vector_table
        DATA
__vector_table
        DCD sfe(CSTACK)
        DCD Reset_Handler ; Reset Handler
        ......
首先中断向量独立在一个叫 .intvec 的段当中,这个段是 4字节对齐(2^2)所以用 DATA 来首先处理向量的入口地址为 4的倍数,然后放向量表。
需要注意的是 NOROOT(2) 和 ROOT(2) 的区别,如果NOROOT表示如果符号没有被关联的时候是被优化掉的,如果想不被优化则使用ROOT吧
其中向量表的第一个数据为堆栈的顶部,可以为一个确定的数值放在SRAM的尾部,这里演示代码使用的是使用固定连接脚本去处理,在连接脚本中定义了一个 CSTACK 的段,然后在启动代码中先声明这个段
SECTION CSTACK:DATA:NOROOT(3)
DCD sfe(CSTACK) 
然后通过 SFE 运算得到改段的结束地址,注意这个运算是在link的时候完成。所以IAR 的处理办法就是先定义一个block作为堆栈区,然后将堆栈指针放到这个block的末端,因为STM32的堆栈是向下生长的。
剩下的就是各个中断向量。接着看怎么处理
        THUMB
 
        PUBWEAK Reset_Handler
        SECTION .text:CODE:REORDER(2)
Reset_Handler
        LDR R0, =SystemInit
        BLX R0
        LDR R0, =__iar_program_start
        BX R0
               
        PUBWEAK NMI_Handler
        SECTION .text:CODE:REORDER(1)
NMI_Handler
        B NMI_Handler
 
首先,因为之前是DATA模式,所以这里先切换回THUMB模式,PUBWEAK 应该是由2个单词组成,PUBLIC 和 WEAK ,PUBLIC 表示导出标号,WEAK表示弱属性,这个属性有一个好处就是,如果用户程序定义了这个标号,那么系统自带的这个中断处理程序则丢弃,使用用户的处理程序,如果用户没有定义则使用系统默认的中断处理程序,这样处理给用户有足够的自由。
然后就装载 SystemInit 函数的地址,跳转去执行该函数,这个函数主要是设置系统的时钟。
最后装载 __iar_program_start 的地址,这个函数是在启动代码中 \arm\src\lib\thumb\下面的代码中找到,是系统自带的启动模块。在项目设置属性的 linker,library中勾选 Automatic runtime library 就可以自动装载了,然后在汇编代码中声明一下 
EXTERN __iar_program_start
就可以调用这个函数了。如果将那个够选项取消后立刻提示没有找到这个标号。
 
至于另外一个符号 __vector_table 是有特殊意义的,所以必须注意添加进去
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
 
还有一个最重要的标号就是 main ,初始化模块最后就是跳到 main 函数了,所以如果写C的话则写个main函数,如果写汇编的话同样也需要从main标号开始,很简单,导出一下就可以了。
        PUBLIC main
main:
 
连接脚本
Config/generic_cortex.icf 就是通用的 cortex M3内核连接脚本,只需要修改几个地址就OK了
首先定义可寻址的逻辑地址,ARM是4G
define memory mem with size = 4G;
然后定义 region 也就是实际的物理地址
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
 
Etual
2010-7-21

STM32启动代码分析 IAR 比较好的更多相关文章

  1. STM32启动代码分析及其汇编学习-ARM

    STM32 启动代码 Author By YuCloud 边看启动文件边学汇编 汇编 see ARM: Assembler User Guide see: https://blog.csdn.net/ ...

  2. STM32启动代码分析

    STM32启动文件简单分析(STM32F10x.s适用范围)定时器, 型号, 名字在<<STM32不完全手册里面>>,我们所有的例程都采用了一个叫STM32F10x.s的启动文 ...

  3. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  4. iar stm32 启动代码片段分析

    今天查看了 iar 上面的启动文件,好奇堆栈指针到底是什么时候赋值的,所以就仔细的阅读了代码和相关手册,找到了答案. 首先,芯片启动后,会从ROM的首地址处进行执行,那么我们从 linker 里面找找 ...

  5. STM32启动代码详细分析

    最近需要学习iap的功能,因此离不开stm32的启动代码的分析,以前看了很多遍,都看不懂,读书百遍,其义自见,因此我有看了一遍,下面的文章,挺好的,因此转载: 在上电复位后,我们都知道会先运行启动代码 ...

  6. Cortex-M0(NXP LPC11C14)启动代码分析

    作者:刘老师,华清远见嵌入式学院讲师. 启动代码的一般作用 1.堆和栈的初始化: 2.向量表定义: 3.地址重映射及中断向量表的转移: 4.初始化有特殊要求的断口: 5.处理器模式: 6.进入C应用程 ...

  7. ARM Linux启动代码分析

    前言 在学习.分析之前首先要弄明白一个问题:为什么要分析启动代码? 因为启动代码绝大部分都是用汇编语言写的,对于没学过或者不熟悉汇编语言的同学确实有一定难度,但是如果你想真正深入地学习Linux,那么 ...

  8. Android 4.2启动代码分析(一)

    Android系统启动过程分析 Android系统的框架架构图如下(来自网上):   Linux内核启动之后----->就到Android的Init进程 ----->进而启动Android ...

  9. STM32 启动代码 bootloader

    什么是启动代码?     启动代码是系统上电或者复位后运行的第一段代码,是进入C 语言的main 函数之前需要执行的那段汇编代码.STM32的启动代码在startup_stm32f10x_hd.s 启 ...

随机推荐

  1. MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术

    逻辑查询优化包括的技术 1)子查询优化  2)视图重写  3)等价谓词重写  4)条件简化  5)外连接消除  6)嵌套连接消除  7)连接消除  8)语义优化 9)非SPJ优化 一.子查询优化 1. ...

  2. boost::spirit unicode 简用记录

    本文简单记录使用boost::spirit解析有中文关键字的字符串并执行响应动作,类似于语法分析+执行. 关键字:字符串解析 boost::spirit::qi::parse qi::unicode: ...

  3. 为iOS的mobileconfig文件进行签名

    本文主要讲,使用苹果开发者证书进行签名达到目的,本文两种方法,一种是刀耕火种的一步步操作,一种使用脚本签名 一.导出苹果证书进行签名 1.从钥匙串(keychain)中导出证书 实用工具->钥匙 ...

  4. Android数据存储方式

    Android提供了5种方式存储数据: 1.使用SharedPreferences存储数据:它是Android提供的用来存储一些简单配置信息的一种机制,采用了XML格式将数据存储到设备中.只能在同一个 ...

  5. NSTimer “定时器”

    •NSTimer叫做“定时器”,它的作用如下 Ø在指定的时间执行指定的任务 Ø每隔一段时间执行指定的任务 Ø •调用下面的方法就会开启一个定时任务 + (NSTimer *)scheduledTime ...

  6. CAST()函数

    语法: CAST(expression AS data_type) 参数说明: expression:任何有效的SQServer表达式 AS:用于分割两个参数,在AS之前的是需要处理的数据,在AS之后 ...

  7. 如何将两个json合并成一个

    //调用方法: var targetObject = [{name:"11",age:11}]; var sourceObject = [{name:"22", ...

  8. Log4j 用法

    一.Log4j基本使用方法 Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式.日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来 ...

  9. 关于lambda表达式的一些学习——基于谓词筛选值序列

    今天看了一些关于lambda表达式的知识,然后对于Func<T,TResult>泛型委托不太熟悉,便查了查相关资料,又引出来了基于谓词筛选值序列这个对我来说的新鲜知识点,于是去查MSDN, ...

  10. 关于TortoiseGit使用的心得

    花了我一个晚上,终于弄明白为什么总是 push 失败的原因了!竟然是因为我用的是注册的用户名而不是邮箱名……囧死. 另外搞清楚了一个问题,就是 Git 和远程仓库交互有两种方式,即 https 方式和 ...