一文读懂 | STM32的启动配置,以及从启动到执行main函数的执行步骤

前言

        STM32基本外设众多,学习需要花费很长时间。这里首先需要明白的是STM32的启动过程,首先将介绍内存分区以及STM32的3中启动配置,这里并未使用代码详细解释,更多的是用于嵌入式方向面试需要。

正文

内存分区

        (1)、堆区(heap):a、堆用来存放动态分配的内存段,它的大小并不固定(自由存储区);b、因为系统使用链表方式存储空闲内存地址,而链表是不连续的并且遍历方向是低地址向高地址,因此堆也是向高地址扩展的数据结构;c、使用new/malloc函数进行内存分配,被分配在堆区上,利用delete/free函数进行释放内存,也就是说需要程序员手动分配和释放,因此速度较慢,但是使用起来最方便。

int* func()
{
    int* a = new int(10);
    return a;
}

int main() {
    int *p = func();
    cout << *p << endl;

    delete p;

    system("pause");
    return 0;
}

        (2)、栈区(stack):a、主要存放的是函数中所创建的一些变量(当然不包括static静态变量),以及函数的返回地址,参数,返回值等;b、栈区存放的内存由操作系统自动分配和释放;c、栈和堆不同,栈的大小有限,并且是一块向低地址扩展的连续的内存区域,因此需要注意栈溢出的危险。关于栈溢出,这篇文章中详细介绍C/C++中栈的使用以及栈溢出-CSDN博客

void mySwap01(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

        (3)、代码区:用来存放程序执行代码的一块区域,包括只读存储区和文本区,其中只读存储区存储字符串常量,文本区存储程序的机器代码。

        (4)、全局区(数据区):a、用来存放已经初始化的全局变量或者已经初始化为非0的静态变量,属于静态内存分配。(这里才算是程序的数据,局部变量只能算是函数的数据);b、用来存放未初始化的全局变量或者未初始化的静态变量或者初始化为0的静态的变量(这部分也被称为BSS段,其实也是数据区的一部分)。

int a = 10;   // 全局变量

int main() {
    int p = a;
    cout << p << endl;

    system("pause");
    return 0;
}

        (5)、映射区:存储动态链接库以及调用mmap函数进行的文件映射

启动配置

        (1)、STM32F103的程序存储器、数据存储器、寄存器和I/O端口被组织到一个4GB的线性地址空间,地址空间分为8块,每块512MB,最下面是代码区,代码区始终从地址0x00000000开始,代码区(0x00000000-0xFFFFFFFF)分为启动空间(0x00000000-0x7FFFFFFF)、Flash(0x08000000-0x08xxxxxx)和系统存储区(0x1FFFF000-0x1FFFF800),Flash存储用户编写的程序,系统存储区存放串口下载程序,系统上电后根据启动配置,将Flash或系统存储区映射到启动空间,执行用户程序或串口下载程序。

        (2)、STM32F103系列单片机因为固定的存储器映像,代码区始终从地址0x00000000开始,通过ICode和DCode总线访问,启动之后,CPU从地址0x00000000获取堆栈顶的地址,并从启动存储器的0x00000004指示的地址开始执行代码,而数据区(SRAM)始终从地址0x20000000开始,通过数据总线访问。CPU始终从ICode总线获取复位向量,即启动仅适合于从代码区开始,而常用的程序代码存放在Flash(闪存ROM)中,因此典型的是从Flash启动。

        (3)、系统复位后,SYSCLK(系统时钟)的第四个上升沿,BOOT引脚的值将被锁存,可以通过配置BOOT引脚选择三种不同的启动模式,
        a、BOOT1引脚为x,BOOT0引脚为0,启动模式为从Flash启动:Flash中存放着用户程序,这种启动方式将Flash映射到启动空间(0x00000000),启动后,单片机将执行用户程序,但仍然能够在用户程序原有的地址(0x08000000)访问。拥有两个访问地址。
        b、从系统存储器启动:启动后,将执行串口下载程序,将程序下载到Flash中,程序下载完成后,再配置为从Flash启动,该启动方式仅用于程序下载,并不会执行用户程序。
        c、从内置SRAM启动:内置SRAM一般存放程序运行时产生的临时数据,不存放程序,只能再0x20000000开始的地址区访问SRAM。

执行步骤 

        首先需要明白 单片机内核复位后,做的第一件事情就是 a、从初始地址0x0000 0000 中取出地址所指向的数值,然后赋值给主堆栈指针MSP,这个值就是栈顶地址 b、从初始地址0x0000 0004 中取出地址所指向的数值,然后赋值给程序计数器指针PC,这个值就是复位向量(中断向量表中的复位中断函数 Reset_Handler)。也就是复位中断函数的首地址,可以开启复位中断函数

        这里就可以确定STM32的启动模式,因为芯片厂商会将0x0000 0000和0x0000 0004两个地址映射到其他地址,比如以Flash存储器启动模式开启,此时原来的0x0000 0000地址就被映射到0x0800 0000,那么此时主堆栈指针MSP的值也就等于0x0800 0000所指向的值,同理0x0000 0004地址被映射到0x0800 0004,此时程序计数器指针PC的值也就等于0x0800 0004所指向的值,其他启动模式依次类推。

-----------------------(以Flash存储器启动模式为例,地址起始 0x0800 0000)为例介绍--------------------
        (1)、单片机上电复位
        (2)、主堆栈指针MSP获取地址0x0800 0000所指向的值,为栈顶地址(也就是栈的第一个元素的地址),程序计数器指针PC获取地址0x0800 0004的值,为复位向量(复位中断函数的首地址,可以开启复位中断函数),被定义在启动文件中,全部执行完毕之后,就会执行用户程序main函数(其实这一步做了两个初始化,a、初始化堆栈指针SP=_initial_sp,这个地址就是0x0800 0000对应的值,也是栈顶地址,b、初始化计数器指针PC=Reset_Handler,中断函数的首地址)。
        (3)、如果需要扩展堆和栈,可以进行设置堆和栈的大小。
        (4)、由上述PC指针的复位中断函数地址,就可以跳转到中断函数调用(Reset_Handler)。
        (5)、进入复位中断函数后,将会调用SystemInit()函数,它的主要作用是复位系统寄存器、初始化嵌入式闪存接口、锁相环、更新系统内核的时钟变量。
        (6)、接着就会调用__main函数,进入用户编写程序main()函数中。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
引用\[1\]:在开始菜单中找到 J-Flash 点击运行。如果4. 软件工程配置成功保存后,默认会存在上次保存的工程,直接点击Start J-Flash。打开/选择 烧录文件。烧录文件一般为 xxxx.hex 。点击 Connect 连接单片机,会在下方LOG中输出连接是否成功的信息。确认连接成功后,点击 Auto , 会自动执行擦除、烧录、校验flash的操作,并让程序跑起来。如果在LOG中输出了以下提示信息,则证明烧录完成。此时直接移除烧录线即可。\[1\] 引用\[2\]:从系统存储器启动,这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,这是一块ROM,出厂后无法修改。一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。但是这个下载方式需要以下步骤:Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader; Step2:最后在BootLoader的帮助下,通过串口下载程序到Flash中; Step3:程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动\[2\] 引用\[3\]:STM32单片机使用SEGGER J-Flash 烧录的方法 1. 烧录环境需求 硬件需求: 电脑: 装有Windows 7 及以上操作系统的电脑(32位或64位都可以)烧录工具:J-Link V8 (硬件版本)及以上的Debugger 软件需求: Segger J-Link software V5.00及以上的版本\[3\] 回答: STM32单片机使用SWD烧录的步骤如下: 1. 确保你的电脑上安装了Segger J-Link software V5.00及以上的版本。 2. 连接J-Link V8或更高版本的Debugger到电脑上。 3. 打开J-Flash软件,可以在开始菜单中找到并点击运行。 4. 在J-Flash中选择烧录文件,一般为xxxx.hex格式的文件。 5. 连接单片机,点击Connect按钮,确认连接成功。 6. 点击Auto按钮,J-Flash会自动执行擦除、烧录、校验flash的操作,并让程序跑起来。 7. 如果在LOG中输出了烧录完成的提示信息,即可移除烧录线。 另外,如果你想使用系统存储器启动,需要按照引用\[2\]中的步骤设置BOOT0和BOOT1,并通过串口下载程序到Flash中。下载完成后,将BOOT0设置为GND,手动复位,STM32才可以从Flash中启动。 #### 引用[.reference_title] - *1* *3* [STM32单片机使用SEGGER J-Flash 烧录的方法](https://blog.csdn.net/weixin_38713073/article/details/107200919)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32软件的烧写方式](https://blog.csdn.net/weixin_42295502/article/details/80916124)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一伦明悦

感谢,您的支持是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值