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. 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)

    1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...

  2. redhat openshift 跳转

    网址: https://openshift.redhat.com/ OpenShift免费套餐的限制是:最多15PV/s,有3个512MB内存的应用,月流量在50K以下. 可以绑米,可惜的是,需要代理 ...

  3. [字符哈希] POJ 3094 Quicksum

    Quicksum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16488   Accepted: 11453 Descri ...

  4. liunx下,只获取主机的IP?

    命令: ifconfig eth0|awk -F "[ :]+" 'NR==2{print $4}'

  5. javascript 手势缩放 旋转 拖动支持:hammer.js

    原文: https://cdn.rawgit.com/hammerjs/hammer.js/master/tests/manual/visual.html /*! Hammer.JS - v2.0.4 ...

  6. openssl

    openssl genrsa -des3 -out server.key 1024openssl req -new server.key -out servr.csr seserver-fnamese ...

  7. ssh 无密码登陆

    ssh -i littlesuccess-aws.pem root@172.31.36.91 "cat >> ~/.ssh/authorized_keys" < ...

  8. Qt中2D绘图问题总结(二)----------坐标系统

    坐标系统 使用QPainter绘制时使用到逻辑坐标,然后转换成绘图设备的物理坐标. 逻辑坐标到物理坐标的映射由QPainter的worldTransform()函数.QPainter的viewport ...

  9. Basic linux command

    1. useradd  解释:添加新用户,在/etc/password文件中添加一行记录. 参数: -g    用于添加账户时指定该账户的私有组,如果不指定-g参数,useradd命令会自动创建与该用 ...

  10. iOS 判断View 是否是第一次显示

    在实现某些需求的时候会有这样的情况,页面第一次加载显示的时候需要某些操作,而以后就不需要重复执行了, 一般这种处理都放在- (void)viewDidLoad或- (id)init因为一般这两个函数除 ...