07 ARM Cortex 汇编boot程序编写

ARM boot程序编写

作者将狼才鲸
创建日期2022-04-06

Gitee文档源码地址:embedded-knowledge-wiki/ documents / 2.3.1.2_ARM编程.md
CSDN文章阅读地址:
Bilibili视频讲解地址(待完成):才鲸嵌入式
本篇文章是一系列文章中的一部分,主文档:才鲸嵌入式 / 嵌入式知识图谱WiKi

一、ARM-MDK IDE集成开发环境下载

  • MDK-arm软件社区版官方介绍(无代码大小限制,不能用于商用,需要先获取社区版许可证):MDK-社区版概述

  • 获取社区版许可证:Log in with your Arm or Mbed account

  • 下载地址主界面:MDK Community Edition

  • 下载地址举例:https://www.keil.com/fid/comahow53j1j1wriguw1y56me9lv1dgw3o3fd1/files/eval/mdk536.exe

  • MKD-arm评估版软件官方下载地址(有32K代码限制):mdk536.exe

  • MKD里面没有软件仿真器,如果没有板子,可以编译完生成可执行程序后在QEMU软件里面仿真运行。

二、ARM boot代码编写

; 使用Keil自动生成时,也可用纯C写Boot相关的配置

                INCLUDE YOUR_CONFIG.INC ; #include "YOUR_NAME.INC" 包含头文件
; 用户自定义宏定义
YOUR_CONFIG1    EQU 0x01    ; 类似于#define宏定义,用不同的配置选项配置程序
YOUR_CONFIG2    EQU 0x01

                PRESERVE8   ; 指定当前文件要求堆栈八字节对齐
                THUMB       ; 使用THUMB指令集,不使用ARM指令集

; 定义堆,堆是malloc主动分配内存的位置
Heap_Size       EQU 0       ; Heap_Size是MDK指定的堆空间长度名称;不用malloc分配的堆没什么用,所以长度设置为0
                IF Heap_Size != 0       ; IF ELSE ENDIF和同名宏定义的含义类似
                AREA     HEAP, NOINIT, READWRITE, ALIGN=3 ; 申明开辟名为HEAP的内存,不写入值初始化,可读可写,2^3 8字节对齐
                EXPORT   __heap_base    ; MDK指定的名称,堆起始地址位置
                EXPORT   __heap_limit   ; MDK指定的名称,堆结束地址位置
__heap_base
Heap_Mem        SPACE    Heap_Size      ; 开始分配指定长度的内存
__heap_limit
                ENDIF

; 定义栈,栈是为全局变量自动分配空间的位置
Stack_Size      EQU      (4096)         ; Stack_Size是MDK指定的栈空间长度名称

                AREA     STACK, NOINIT, READWRITE, ALIGN=3 ; 申明开辟名为STACK的内存,不写入值初始化,可读可写,2^3 8字节对齐
                EXPORT   __stack_limit  ; MDK指定的名称,栈起始地址位置
                EXPORT   __initial_sp   ; MDK指定的名称,栈结束地址位置

__stack_limit
Stack_Mem       SPACE    Stack_Size     ; 开始分配指定长度的一片连续的内存
__initial_sp

                AREA     RESET, DATA, READONLY      ; 定义数据段,名字为RESET;上电后首先运行的函数地址
                EXPORT   __Vectors                  ; 输出ARM CMSIS中需要用到的一些标号,__Vectors函数在后续定义
                EXPORT   __Vectors_End
                EXPORT   __Vectors_Size
                EXPORT   Default_Interrupt_Handler  ; 中断入口
                IMPORT   __initial_sp

; 申明异常和中断入口
__Vectors       DCD      __initial_sp               ;     Top of Stack
                DCD      Reset_Handler              ;     Reset Handler
                DCD      NMI_Handler                ; -14 NMI Handler
                DCD      HardFault_Handler          ; -13 Hard Fault Handler
                DCD      MemManage_Handler          ; -12 MPU Fault Handler
                DCD      BusFault_Handler           ; -11 Bus Fault Handler
                DCD      UsageFault_Handler         ; -10 Usage Fault Handler
                DCD      0                          ;     Reserved
                DCD      0                          ;     Reserved
                DCD      0                          ;     Reserved
                DCD      0                          ;     Reserved
                DCD      SVC_Handler                ;  -5 SVCall Handler
                DCD      DebugMon_Handler           ;  -4 Debug Monitor Handler
                DCD      0                          ;     Reserved
                DCD      PendSV_Handler             ;  -2 PendSV Handler
                DCD      SysTick_Handler            ;  -1 SysTick Handler

                ; Interrupts
                DCD      Interrupt_Handler_0
                ; …… 省略其它中断 ……
                DCD      Interrupt_Handler_45       ; BCD:分配存储单元
__Vectors_End
__Vectors_Size  EQU      __Vectors_End - __Vectors

                ; 类似于宏定义函数
                MACRO                               ; 宏定义函数的开始                     
                Set_Default_Handler $Handler_Name   ; 前一个时宏定义函数的名字,后面是要操作的对象
$Handler_Name   PROC                                ; 定义子程序
                EXPORT   $Handler_Name [WEAK]       ; 输出函数名;[WEAK]虚函数,可定义可不定义
                B        .                          ; 死循环
                ENDP                                ; 子程序定义结束
                MEND                                ; 宏定义函数结束

                AREA     |.text|, CODE, READONLY    ; 定义.text代码段,只读

                ; 申明默认的异常和中断处理函数
                Set_Default_Handler  Reset_Handler
                Set_Default_Handler  NMI_Handler
                Set_Default_Handler  HardFault_Handler
                Set_Default_Handler  MemManage_Handler
                Set_Default_Handler  BusFault_Handler
                Set_Default_Handler  UsageFault_Handler
                Set_Default_Handler  SVC_Handler
                Set_Default_Handler  DebugMon_Handler
                Set_Default_Handler  PendSV_Handler
                Set_Default_Handler  SysTick_Handler
                Set_Default_Handler  Default_Interrupt_Handler
                Set_Default_Handler  Interrupt_Handler_0
                ; …… 省略其它中断 ……
                Set_Default_Handler  Interrupt_Handler_45
 
                ; 各种程序
                ; Reset_Handler是板子上电后首先执行的位置,它由异常中断的跳转来实现
Reset_Handler   PROC                    ; 程序名 PROC 程序内容 ENDP 程序结束
                EXPORT   Reset_Handler
                IMPORT	 __hardwareInit ; 自己编写的C程序,在里面初始化各种硬件配置
                IMPORT   __main         ; main()函数入口
                BL       __hardwareInit ; 调用初始化硬件的汇编函数
                BL       __main         ; 跳转到main()函数
                BL       cpuStall       ; 程序退出后一直死循环
                ALIGN
                ENDP

cpuStall        PROC
                EXPORT   cpuStall
                B        .              ; 死循环
                ENDP
                END                     ; 通知编译器已经到了该源文件的结尾了
                
__hardwareInit  PROC
                EXPORT   __hwInitialize
                PUSH     {R0,R1,R2,R3,LR} ; 压栈
                ; 配置GPIO输出
                ; 配置PLL系统主频,将主频从晶振原有的频率提高到实际的工作频率
                ; 初始化串口
                ; 初始化其它外设
                POP      {R0,R1,R2,R3,LR} ; 弹栈
                BX       LR               ; 跳转到LR寄存器里的地址执行,也就是跳转回被调用的地方
                ALIGN
                ENDP
                
                ; 其它的.inc汇编头文件中要做的事
                ; 定义各个硬件模块的地址
                ; 定义所有中断号                

linux 汇编 preserve8,为什么ARM汇编程序前要加PRESERVE8
ARM/THUMB汇编(补丁开发类)基础教程
Thumb 指令集
keil 环境下 AREA SUN ,NOINIT, READONLY , ALIGN=3 分别表示什么意思
【ARM汇编】SPACE和DCD指令的区别
STM32 stack_size和heap_size大小设置的意义
堆(heap)和栈(stack)有什么区别??
arm汇编指令-DCD
ARM 汇编 伪指令 MACRO及MEND
灵活使用ARM汇编的WEAK关键字
ARM汇编中B .的实际意义
【cm-3】汇编中的句子:AREA |.text|, CODE, READONLY, ALIGN=2详解
ARM汇编:汇编中proc、endp、ret、near、far指令用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值