【STM32】STM32内存映射以及启动过程(超详细过程)

2023-05-16

一、内存映射

1、内存映射图

下图是 STM32F103xCDE 型号的内存映射图。

在这里插入图片描述

2、内存划分

由于 STM32 是 32 位,且其地址总线也为 32 根,所以其理论能够寻找的地址大小为 4GB

从上图可以看出,左边的地址从 0x0000 0000 ~ 0xFFFF FFFF 的 4GB 是 STM32 理论分配的地址空间,STM32 实际上的空间大小 远远小于 4GB 的。4GB 中又划分出了 8 个块,一块占 512MB,分别作为 代码区、SRAM区、外设区、FSMC1区、FSMC2区、FSMC寄存器区、未使用区、Cortex-M3内部外设区。

3、存储器映射

映射其实就是对应的意思。事实上存储器本身并不具备地址,将芯片理论上的地址分配给存储器,这就是存储器映射。STM32 的所有片内外设其实都是存储器,所以所有的这些存储器都需要被映射。

理论上地址起始就是门牌号,存储中的每个字节就是房间,存储器生产出来后,这些房间是没有地址的(门牌号),映射的过程其实就是将这些门牌号分配给这些房间,分配好后,每个门牌号只能访问自己的房间,没有被分配的地址就是保留地址,所谓保留地址的意思就是,没有对应实际存储空间。

在这里插入图片描述

STM32 片内的 FLASH 分成两部分:主存储块、信息块。

  • 主存储块
    • 主Flash:用于存储程序,我们写的程序一般存储在这里。
  • 信息块
    • 系统存储器(系统FLASH):存放在系统存储器自举模式下的启动程序(BootLoader),当使用 ISP 方式加载程序时,就是由这个程序执行。这个区域由芯片厂写入 BootLoader,然后锁死,用户是无法改变这个区域的
    • 选项字节:存储芯片的配置信息及对主存储块(主Flash)的保护信息。

STM32F103VET6 芯片的主Flash 的内存空间范围是 0x0800 0000 ~ 0x0807 FFFF,共 512KB。

在这里插入图片描述

4、寄存器映射

在这里插入图片描述

在 block2 外设区,也就是地址从 0x4000000 ~ 0x5FFFFFF 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。可以找到每个单元的起始地址,然后通过C语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,聪明的工程师就根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射

在这里插入图片描述

5、地址重映射

自举(bootstrap)计算机设备使用硬件加载的程序,用于初始化足够的软件来查找并加载功能完整的操作系统。也用来描述加载自举程序的过程。什么是单片机的自举,单片机的自举就是单片机的启动

而众所周知,单片机在每次上电时都是从 0 地址开始执行,那么这就存在一个问题,我们下载程序时是将代码放在 主Flash ,其地址为 0x0800 0000 ~ 0x0807 FFFF,起始地址并不在 0 地址,那单片机要如何找到代码并执行呢?

在这里插入图片描述

在地址划分的区域可以看出,0x0000 0000 ~ 0x0007 FFFF 这块区域的功能是专门进行地址重映射的,而要进行重映射的区域取决于 BOOT 引脚,通过 BOOT1 和 BOOT0 引脚的电平值,可以选择将0x0000 0000 ~ 0x0007 FFFF 映射到不同的存储器上
这就解释了为什么我们在 keil 中设置好程序的下载地址为 0x8000000,但是单片机上电是确实从 0 开始执行。是因为我们在硬件上设置了 BOOT0=1,BOOT1=X,从而导致了主FLASH 区被映射到了0x0000 0000 ~ 0x0007 FFFF(512KB),故而代码是下载到 0x80000000 往后的存储空间中,却说运行又是从 0x00000000 地址运行的。

5.1 STM32启动模式

在这里插入图片描述

  • 主FLASH启动:将主 Flash 地址 0x0800 0000 映射到 0x0000 0000,这样代码启动之后就相当于从 0x08000000 开始。一般使用 JTAG 或者 SWD 模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。
  • 系统存储器启动:从系统存储器地址 0x1FFF F000 开始执行代码。系统存储器是芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段 Bootloader,就是通常说的 ISP 程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个 ROM 区。启动的程序功能由厂家设置。系统存储器存储的其实就是 STM32 自带的 bootloader 代码。
  • 内置SRAM启动:将 SRAM 地址 0x20000000 映射到 0x00000000,这样代码启动之后就相当于从 0x20000000 开始。内置 SRAM,也就是STM32的内存,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码,用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中

在这里插入图片描述

6、程序烧录方式

6.1 ISP(串口烧录)

  • BOOT0 = 1,BOOT1 = 0
  • 启动地址:0x1FFF F000
  • 使用串口下载程序
  • 系统存储器(系统Flash)启动方式运行内置的 Bootloader,将程序写入主存储区(主Flash)
  • 重启后,需要再将 BOOT0 拉低,从主存储区(主Flash)启动程序

6.2 ICP(SWD/JTAG接口烧录)

  • BOOT0 = 0,BOOT1 = x
  • 启动地址:0x0800 0000
  • 使用 JTAG 或者 SWD 模式下载程序
  • 主闪存存储器(主Flash)启动方式,将程序在主存储区写入
  • 重启后也直接从这启动程序

6.3 IAP

IAP 的原理与上面两种有较大区别,这种方式将主存储区又分成了两个区域(根据实际需要由开发者自行分配),0x0800 0000 起始处的这部分,存储一个开发者自己设计的 Bootloader 程序,另一部分存储真正需要运行的 APP 程序

单片机的 Bootloader 程序,其主要作用就是给单片机升级。在单片机启动时,首先从 Bootloader 程序启动,一般情况不需要升级,就会立即从 Bootloader 程序跳转到存储区另一部分的 APP 程序开始运行

假如 Bootloader 程序时,需要进行升级(比如APP程序运行时,接收到升级指令,可以在 flash 中的特定位置设置一个标志,然后触发重启,重启后进入 Bootloader 程序,Bootloader 程序根据标志位就能判断是否需要升级),则会通过某种方式(比如通过 WIFI 接收升级包,或借助另一块单片机接收升级包,Bootloader 再通过串口或 SPI 等方式从另一块单片机获取升级包数据)先将接收到的程序写入存储区中存储 APP 程序的那个位置,写入完成后再跳转到该位置,即实现了程序的升级
在这里插入图片描述

二、启动过程

STM32 的片内 RAM 分为如下几个段:

在这里插入图片描述

1、概括

启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:

  1. 初始化堆栈指针 SP=_initial_sp
  2. 初始化 PC 指针=Reset_Handler
  3. 初始化中断向量表
  4. 配置系统时钟
  5. 调用 C 库函数 _main 初始化用户堆栈,从而最终调用 main 函数去到 C 的世界

2、栈初始化

// #define Stack_Size      0x00000400
Stack_Size      EQU     0x00000400
// STACK:段名;NOINIT:不初始化;READWRITE:可读可写;ALIGN=3:2^3,即 8 字节对齐
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
// 栈的结束地址,即栈顶地址,需要保存栈顶的地址
__initial_sp
  • EQU宏定义的伪指令,相当于等于,类似与 C 中的 define。
  • AREA:告诉汇编器汇编一个新的代码段或者数据段
  • SPACE:用于分配一定大小的内存空间,单位为字节。这里指定大小等于 Stack_Size。

3、堆初始化

// #define Heap_Size       0x00000200
Heap_Size       EQU     0x00000200
// HEAP:段名;NOINIT:不初始化;READWRITE:可读可写;ALIGN=3:2^3,即 8 字节对齐
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
// 堆的起始地址
__heap_base
Heap_Mem        SPACE   Heap_Size
// 堆的结束地址
__heap_limit

                PRESERVE8
                THUMB
  • PRESERVE8:指定当前文件的堆栈按照 8 字节对齐。
  • THUMB:表示后面指令兼容 THUMB 指令。THUBM 是 ARM 以前的指令集,16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集,THUMB-2 是 32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超集。

4、初始化向量表

4.1 开辟向量表空间

// RESET:段名;DATA:包含数据,不包含指令;READONLY:只读
AREA    RESET, DATA, READONLY
/* 声明 __Vectors、__Vectors_End 和 __Vectors_Size 这三个标号具有全局属性,
可供外部的文件调用 */
EXPORT  __Vectors
EXPORT  __Vectors_End
EXPORT  __Vectors_Size
  • EXPORT声明一个标号可被外部的文件使用,使标号具有全局属性。如果是 IAR 编译器,则使用的是 GLOBAL 这个指令。

4.2 初始化向量表

// __Vectors:向量表起始地址
__Vectors       DCD     __initial_sp               ; 栈顶地址
                DCD     Reset_Handler              ; 复位程序地址
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                // 外部中断开始
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                
				// 限于篇幅,中间代码省略
				
                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
// __Vectors_End:向量表结束地址
__Vectors_End
// 获得向量表大小
__Vectors_Size  EQU  __Vectors_End - __Vectors

向量表从 FLASH 的 0 地址(0x0800 0000)开始放置,以 4 个字节为一个单位,地址 0(0x0800 0000)存放的是栈顶地址,0x04 存放的是复位程序的地址,以此类推。从代码上看,向量表中存放的都是中断服务函数的函数名,可我们知道 C 语言中的函数名就是一个地址。

  • DCD分配一个或者多个以字为单位的内存,以四字节对齐,并要求初始化这些内存。在向量表 中,DCD 分配了一堆内存,并且以 ESR 的入口地址初始化它们。

4.3 复位中断程序初始化

// .text:段名;DATA:包含机器指令;READONLY:只读
AREA    |.text|, CODE, READONLY
                
// Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

复位子程序是系统上电后第一个执行的程序,调用 SystemInit 函数初始化系统时钟,然后调用 C
库函数 _mian,最终调用 main 函数去到 C 的世界。

  • WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用该标号,如果外部文件没有声明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并不是唯一的。
  • IMPORT表示该标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似。这里表示 SystemInit 和 __main 这两个函数均来自外部的文件。
    • SystemInit() :标准库函数,在 system_stm32f10x.c 这个库文件总定义。主要作用是配置系统时钟,这里调用这个函数之后,单片机的系统时钟配被配置为72M。
    • __main:标准的 C 库函数,主要作用是初始化用户堆栈,并在函数的最后调用 main 函数去到 C 的世界。这就是为什么我们写的程序都有一个 main 函数的原因。

在这里插入图片描述

4.4 其他中断程序初始化

/* 初始化默认中断程序(无限循环) */
NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]
                B       .
                ENDP
                
// 限于篇幅,中间代码省略
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

/* 外部中断 */
Default_Handler PROC
                EXPORT  WWDG_IRQHandler            [WEAK]
                EXPORT  PVD_IRQHandler             [WEAK]
                EXPORT  TAMPER_IRQHandler          [WEAK]
                EXPORT  RTC_IRQHandler             [WEAK]
// 限于篇幅,中间代码省略
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandler
                B       .
                ENDP
                ALIGN
  • B跳转到一个标号。这里跳转到一个‘.’,即表示无限循环。
  • PROC:过程(子程序)的开始。
  • ENDP:过程(子程序)的结束。
  • ALIGN:对指令或者数据存放的地址进行对齐,后面会跟一个立即数。缺省表示 4 字节对齐。

4.5 用户堆栈初始化

/* 用户栈和堆初始化, 由 C 库函数 _main 来完成 */
				 // 这个宏在 KEIL 里面开启
				 IF      :DEF:__MICROLIB	
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE
                 // 这个函数由用户自己实现
                 IMPORT  __use_two_region_memory	
                 EXPORT  __user_initial_stackheap
                 
__user_initial_stackheap
                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN
                 ENDIF
                 END

首先判断是否定义了 __MICROLIB ,如果定义了这个宏则赋予标号 __initial_sp(栈顶地址)、
__heap_base(堆起始地址)、__heap_limit(堆结束地址)全局属性,可供外部文件调用。然后堆栈的初始化就由 C 库函数 _main 来完成
如果没有定义 __MICROLIB,则才用双段存储器模式,且声明标号 __user_initial_stackheap 具有全局属性,让用户自己来初始化堆栈

在这里插入图片描述

  • IF,ELSE,ENDIF:汇编的条件分支语句,跟C 语言的if ,else 类似。
  • END:文件结束

参考资料:
https://zhuanlan.zhihu.com/p/511268958
https://zhuanlan.zhihu.com/p/367821312

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【STM32】STM32内存映射以及启动过程(超详细过程) 的相关文章

  • 使用Git小乌龟初始化本地仓库并且创建新的分支提交 删除分支(超详细图文教程,手把手教你做)

    前段时间入了小乌龟的坑 xff0c 最近项目需要多人合作 xff0c 就需要使用分支提交项目 xff0c 这里刚好就使用到了创建分支功能 xff0c 就记录一下使用的完整过程 文章目录 第一步 初始仓库 xff1a 1 1 创建完成项目会多
  • opencv笔试面试必背题目

    算法工程师 xff0c 技术软件类求职opencv必背八股文 更多算法 业务 HR面等笔试题面试题 gt 个性签名自取 xff01 1 opencv中RGB2GRAY是怎么实现的 答 xff1a 以R G B为轴建立空间直角坐标系 xff0
  • 我的新地址 http://www.cppblog.com/flyingxu/

    我的新地址 http www cppblog com flyingxu 这里的文章不会移过去 xff0c 也不会继续更新 xff0c 保持现状 以后会不会重新开始更新 xff0c 也不确定
  • px4+ros+gazebo+ORB_SLAM2室内视觉无人机导航

    px4 43 ros 43 gazebo 43 ORB SLAM2室内视觉无人机导航 一 ros 43 px4环境搭建 我用的ORB SLAM2视觉相机跑图首先要安装ros 43 px4环境 xff0c 我用的阿木实验室的镜像 xff0c
  • pc+tx2通信

    https blog csdn net RNG uzi article details 107285113
  • F4烧写PX4固件

    一 硬件准备 一个f4v3pro或者f4v3s飞控 xff0c 一根USB线 xff0c F450机架 xff0c ET07接收机和配套遥控器 xff0c 20A电调 xff0c 电机 xff0c 格式3s电池 1 无人机组装效果图 上 上
  • C++结构体类型变量

    C 43 43 定义结构体类型变量的方法 1 先声明结构体类型再定义变量名 xff0c 在定义了结构体变量后 xff0c 系统会为之分配内存单元 span class token keyword struct span Student sp
  • pycharm中如何安装tensorflow、cv2

    做卷积神经网络时用到了Python xff0c 记录一下遇到的问题 xff0c 首先 xff0c anaconda和pycharm的安装可按照网上的教程来 tensorflow的安装 但是 xff0c 当配置好解释器之后 xff0c 面临的
  • 【vscode和gitee】如何更改VsCode的gitee远程库地址,并提交到新的仓库中

    如何更改VsCode的gitee远程库地址 xff0c 并提交到新的仓库中 1 查看并更换git远程仓库地址 span class token number 1 span 查看当前remotes span class token funct
  • 【软件评测】03程序语言基础

    仅为学习记录 程序设计语言概述 低级语言 机器语言 xff1a 用二进制代码表示的计算机的指令等 xff0c 所有都是二进制表示 xff0c 计算机可以直接执行 xff0c 而不需要再次进行编译 优点 xff1a 执行效率较高 xff0c
  • 【软件评测】06计算机网络基础知识

    计算机网络基础知识 OSI RM七层模型七层模型TCP IP四层协议冲突域和广播域的区别 常见的协议协议族常见协议及对应端口常用的端口号 域名空间万维网Windows网络相关命令IP地址IP地址IP地址的分类IP地址掩码变长子网掩码特殊含义
  • 【软件评测】07安全性基础知识

    安全性基础知识 安全保护等级安全防护体系数据安全策略安全防护策略防火墙包过滤状态检测代理服务 安全协议 病毒与木马病毒木马 网络攻击访问控制访问控制实现方式身份验证方式 加密技术对称性加密技术非对称性加密技术单向加密PKI签名 43 加密
  • 【软件评测】09知识产权和项目管理基础知识

    仅为学习记录 知识产权 著作权概述 著作权 知识产权是指人们基于自己的智力活动所创造的成果和经营管理活动中的经验知识而依法享有的权利 知识产权的特点 xff1a 无形性 双重性 确认性 独创性 地域性 时间性 版权 xff08 著作权 xf
  • 131. Palindrome Partitioning

    文章目录 1 题目理解2 回溯3 动态规划 1 题目理解 输入 xff1a 字符串s 规则 xff1a 将字符串s分割 xff0c 分割后每一个部分都是一个回文串 输出 xff1a 所有的分割方式 Example 1 Input s 61
  • 【软件评测】10数据库技术

    仅记录学习过程 数据库技术相关术语 术语 数据 描述事物的符号 xff0c 是传递信息的载体信息 事物的状态和事物状态变化的反馈数据库 存放数据的地方 xff0c 统一管理 长期存放在计算机内 有组织 相互关联的数据集合 xff0c 特点是
  • 【软件评测】11软件测试理论

    仅为学习记录 软件测试理论 软件测试基础软件测试软件测试验证与确认软件缺陷 测试质量与保证软件质量质量保证 测试用例测试策略测试的原则软件测试模型V模型W模型H模型敏捷测试模型 软件测试分类回归测试按照关联代码划分按实施主体划分按工程阶段划
  • 数学建模-第六章:最优化方法建模

    最优化方法 数学规划 xff0c 是运筹学的一个分支怎样建立最优化问题的数学模型 决策变量和函数约束或限制条件目标函数 连续变量优化模型 线性规划 标准形式的线性规划模型 线性规划问题转为标准形式 max w 61 7x 43 12y s
  • Linux基础命令总结(超全)

    Linux中一些基础命令 1 pwd xff1a 显示当前所在位置的绝对路径 2 cd 43 路径 xff1a 切换当前工作位置 3 cd xff1a 退回到当前位置 4 cd xff1a 退回到上一层 5 ls xff1a 默认显示当前位
  • C#窗体简单应用

    创建登录页面 xff0c 登录成功跳转测试页面 第一步 xff0c VS创建窗体 第二步 xff0c 进入程序 xff0c 开始编辑 第三步 xff0c 从 视图 找出 工具箱 xff0c 拉出对应控件 xff0c 排布登录页面 第四步 x
  • 四旋翼无人机仿真之hector_quadrotor无人机(ROS + Gazebo)(一)

    这里写自定义目录标题 应用环境hector quadrotor 功能包结构简介hector quadrotor 功能包安装1 安装所需依赖库2 下载 安装hector quadrotor参考文章 应用环境 ubuntu16 04 虚拟机实体

随机推荐

  • 四旋翼无人机仿真之hector_quadrotor无人机(ROS + Gazebo)(三)传感器数据读取与复现(IMU、GPS)

    系列文章目录 文章1 xff1a 四旋翼无人机仿真之hector quadrotor无人机 xff08 ROS 43 Gazebo xff09 文章2 xff1a 四旋翼无人机仿真之hector quadrotor xff08 二 xff0
  • 魔霸新锐2021双系统配置

    https blog csdn net FontThrone article details 104282121 主要参考独立显卡部分 https www bilibili com read cv11300312 xff08 主要参考核心显
  • XTDrone vins-fusion+ego-swarm debug(已解决)

    问题描述 xff1a 低优先级无人机 xff08 除0号无人机以外 xff09 运行撞墙 xff1b 启动时低优先级无人机会异常的飘逸一段距离 xff0c 而rviz里显示的b样条曲线的控制点起点没变 这是刚启动的情况 启动大概不到1秒无人
  • cmake find_packages 搜索路径与 opencv版本管理

    find packages搜索路径 xff1a 设定一个project DIR变量来指定路径 xff0c 找到对应库的 cmake xff0c 例如 xff1a set OpenCV DIR usr share OpenCV 多版本proj
  • 小白理解Kubernetes系列

    初识Kubernetes 从本篇文章开始 xff0c 记录Kubernetes的内容 xff0c Kubernetes相关的知识点包括十三个部分 xff0c 分别是前世今生 组件说明 Pod概念 网络通讯方式 集群安装 资源清单 资源控制器
  • Warning: skipping non-radio button in group

    现象 xff1a 当我们加入一组单选按钮 xff0c 并将它们设置为一组互斥按钮 xff0c 然后又添加其他控件 xff0c 这时按F5编译 xff0c 出现如下警告信息 xff1a Warning skipping non radio b
  • ubuntu蓝牙相关问题(ubuntu 18.04 + ax210)

    装驱动 xff08 ax210的驱动好像要内核5 10以上能用 xff0c 可以参考我之前的博客升级 xff09 span class token function wget span span class token parameter
  • 嵌入式软件面试经典问题

    一 进程与线程 xff08 不同的系统资源管理方式 xff09 1 区别 进程 xff1a 资源分配的基本单位 xff0c 由一个或者多个线程组成 线程 xff1a 调度器进行调度的基本单位 xff0c 一个任务 每个进程都有自己独立的内存
  • ESP8266常用API函数总结(vscode+platformIO)

    1 COMMON 1 includePath ctrl 43 shift 43 p进入命令面板输入C C 43 43 Edit Configurations 在包含文件中选择include文件目录 2 输出监视器 在platformio i
  • C++基础总结

    1 引用和指针区别 引用变量是一个别名 xff0c 相当于定义了一个const类型变量 xff0c 但不分配空间 引用定义时必须初始化 xff0c 指针无要求 初始化时引用一个实体后不能再引用其他的 xff0c 指针可以在任何时候指向任一同
  • 局域网共享文件配置

    1 适用范围 可用于同一网络内的设备进行数据共享 xff08 同一WIFI或网线接同一路由器 xff09 2 共享文件配置步骤 xff1a 1 选择你想共享的文件 xff0c 鼠标右键单击属性 xff08 例如我这文件名为Shared xf
  • C语言细节

    C 1 char数组声明时初始化 2 uin8 t属于无符号字符型 typedef signed char int8 t typedef unsigned char uint8 t typedef short int16 t typedef
  • ESP32 stable_v5.0 API简单汇总

    SDK API https docs espressif com projects esp idf 1 GPIO amp EXTI 头文件位置 xff1a components driver include driver gpio h 二选
  • keil5[使用虚拟端口进行软件仿真串口调试]与[使用开发板串口调试]

    前言 xff1a 做串口调试试验 xff0c 写下此文章 介绍两种方式 xff0c 一种软件仿真 xff0c 一种硬件 1 虚拟端口进行软件仿真串口调试 xff1a 无需硬件 开发板 需要虚拟串口驱动 xff08 一个软件 xff09 xf
  • STM32 FreeRTOS学习——任务创建

    任务创建 任务概念 什么是任务 任务函数没有返回值 xff0c 并且参数是指针类型 很少使用 基本可以不管 void entry task void pvParameters 任务主体 xff0c 无限循环且不能返回值 while 1 任务
  • kinect v2 相机标定

    目录 ubuntu删除命令 相机标定 一些快捷键 准备工作 详细步骤 ubuntu删除命令 ubuntu中删除命令一般使用rm xff0c 但是rm误删之后 xff0c 想恢复比较麻烦 xff0c 所以在这里介绍另外一种删除方法 xff0c
  • 研究生如何读论文

    作为一个准研究生 xff0c 马上就要开始加入到读论文的大军中 xff0c 如何读论文是我们共同关心的问题 xff0c 笔者在这方面做了一些小调查 xff0c 发现台湾清华彭明辉教授的研究生手册非常有启发意义 xff0c 现摘录一下对自己很
  • 嵌入式面试资料整理

    第一章进程线程的基本概念 1 什么是进程 xff0c 线程 xff0c 有什么区别 2 多进程 多线程的优缺点 3 什么时候用进程 xff0c 什么时候用线程 4 多进程 多线程同步 xff08 通讯 xff09 的方法 5 进程线程的状态
  • MSP-EXP430F5529LP_GPIO

    为了能让学习更有动力并且坚持下去 xff0c 突然想到可以用博客的形式来记录自己的学习历程 xff0c 一方面是基于上述原因并且可以留下笔记来方便日后查看 xff0c 另一方面感觉写出来一些东西可以让学习更加具有逻辑性 xff0c 今天就让
  • 【STM32】STM32内存映射以及启动过程(超详细过程)

    一 内存映射 1 内存映射图 下图是 STM32F103xCDE 型号的内存映射图 2 内存划分 由于 STM32 是 32 位 xff0c 且其地址总线也为 32 根 xff0c 所以其理论能够寻找的地址大小为 4GB 从上图可以看出 x