嵌入式软件学习记录 - DAY6

发布于:2025-05-20 ⋅ 阅读:(12) ⋅ 点赞:(0)

C/C++ 内存分区详解


一、具体分区

1. 栈区(Stack)
  • 存储内容:函数调用时的局部变量、函数参数、返回地址、寄存器值等。
  • 特点:由编译器自动管理,后进先出(LIFO),分配速度快,空间连续。
  • 示例
    void func() {
        int a = 10;        // 栈上分配
        char arr[20];      // 栈上分配
    }
    
2. 堆区(Heap)
  • 存储内容:通过 malloc/calloc/realloc(C)或 new(C++)动态分配的内存。
  • 特点:手动管理,灵活但易产生碎片,分配速度较慢。
  • 示例
    int* ptr = (int*)malloc(sizeof(int));  // C语言
    int* cpp_ptr = new int(10);            // C++
    
3. 静态存储区(Static Storage Area)
  • 存储内容
    • 全局变量:文件作用域的变量。
    • 静态变量:用 static 修饰的变量(全局或局部)。
  • 细分区域
    • BSS 段(Block Started by Symbol):未初始化或初始化为 0 的静态变量。
    • 数据段(Data Segment):已初始化且初始值非 0 的静态变量。
  • 特点:程序启动时分配,程序结束时释放,默认初始化为 0。
  • 示例
    int global_uninit;          // BSS段(未初始化)
    static int static_uninit;   // BSS段
    int global_init = 10;       // 数据段(已初始化)
    static int static_init = 20; // 数据段
    
4. 代码区(Text Segment)
  • 存储内容:程序的可执行代码(机器指令)、常量(如字符串字面量)。
  • 特点:通常只读,防止程序意外修改自身指令。
  • 示例
    const char* msg = "Hello";  // "Hello" 存储在代码区
                                // msg 变量本身在栈或静态区
    
5. 常量区(只读数据段)
  • 存储内容:字符串字面量、const 修饰的全局变量。
  • 特点:只读,程序运行期间不可修改。
  • 示例
    const int MAX = 100;        // 存储在常量区
    const char* str = "World";  // "World" 在常量区
    
6. 内存映射区(Memory Mapping Segment)
  • 存储内容:通过 mmap 系统调用映射的文件或共享内存。
  • 用途:高效文件操作、进程间通信(IPC)。
  • 示例
    // 将文件映射到内存(伪代码)
    void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
    

二、C++ 额外的内存区域(相比 C)

1. 自由存储区(Free Store)
  • 说明:C++ 中通过 new 和 delete 管理的内存区域,概念上类似堆,但实现可能不同(取决于编译器)。
  • 区别
    • 堆是操作系统层面的内存管理;自由存储区是 C++ 抽象的概念。
    • new 底层可能调用 malloc,但可通过重载 operator new 自定义实现。
2. 线程局部存储(Thread Local Storage, TLS)
  • 存储内容:用 thread_local 修饰的变量,每个线程独立拥有一份副本。
  • 示例
    thread_local int counter = 0;  // 每个线程有自己的 counter
    

三、内存分区对比表

区域 存储内容 生命周期 分配方式 特点
栈区 局部变量、函数参数、返回地址等 函数调用到返回 编译器自动管理 速度快、连续、容量有限
堆区 动态分配的内存(malloc/new 手动分配和释放 手动管理 灵活、碎片、速度慢
BSS 段 未初始化的静态变量和全局变量 程序启动到结束 自动初始化 初始化为 0
数据段 已初始化的静态变量和全局变量 程序启动到结束 自动分配 初始化为指定值
代码区 可执行代码、字符串字面量 程序运行期间 只读 不可修改
内存映射区 文件映射、共享内存 手动映射和解除映射 系统调用(如 mmap 高效文件操作

四、常见问题

  1. 内存泄漏:堆内存未释放,导致持续占用。
  2. 栈溢出:递归过深或局部变量过大,导致栈空间耗尽。
  3. 野指针:访问已释放的堆内存或未初始化的指针。

理解内存分区有助于编写高效、安全的代码,避免常见的内存错误。

单片机基础知识(C51、STM32)

一、单片机的最小系统

单片机的最小系统是指让单片机能够正常工作所需的 最基本电路单元,不同型号的单片机最小系统略有差异,但核心组成部分基本一致。以经典的 51 系列单片机(如 AT89C51) 为例,其最小系统通常包括以下部分:

1. 单片机芯片(核心)
  • 是整个系统的控制中心,负责执行程序、处理数据和控制外设。
  • 例如 AT89C51 芯片,内部集成了 CPU、存储器、定时器、串口等模块。
2. 电源电路
  • 作用:为单片机提供稳定的工作电压(通常为 5V 或 3.3V,取决于芯片型号)。
  • 组成
    • 电源输入端(如 USB 接口、电源适配器)。
    • 滤波电容(如 10μF 电解电容 + 0.1μF 瓷片电容),用于稳定电压、滤除高频干扰。
3. 时钟电路(晶振电路)
  • 作用:为单片机提供工作时钟信号(主频),控制指令执行的时序。
  • 组成
    • 晶振(石英晶体振荡器,常见频率:11.0592MHz、12MHz 等)。
    • 起振电容(2 个 10~30pF 瓷片电容,连接晶振两端并接地)。
  • 原理:晶振与单片机内部电路构成振荡电路,产生周期性时钟信号。
4. 复位电路
  • 作用:使单片机初始化(恢复默认状态),或在程序跑飞时强制重启。
  • 组成
    • 上电复位:由电阻和电容组成(如 10kΩ 电阻 + 10μF 电容),上电时电容充电,产生短暂高电平脉冲触发复位。
    • 按键复位:在上电复位基础上并联按键,按下按键时直接触发复位。
  • 复位信号:通常为高电平有效(不同芯片可能不同)。
5. 程序存储器(可选,取决于单片机类型)
  • 对于无片内 ROM 的单片机(如早期的 8031),需外接 EEPROM 或 FLASH 存储器(如 AT28C64)存储程序。
  • 现代单片机(如 STC89C52、STM32)通常内置 FLASH,无需外接存储器。

二、单片机的内部主要结构

单片机内部集成了多种功能模块,不同厂商和型号的架构可能不同,但基本结构类似。以下是典型单片机的内部组成:

1. 中央处理器(CPU)
  • 核心部件:负责执行指令、处理数据和控制整个系统的运行。
  • 组成
    • 算术逻辑单元(ALU):完成算术运算(加、减、乘、除)和逻辑运算(与、或、非、异或等)。
    • 控制器:产生时序信号,控制指令的读取、解码和执行。
    • 寄存器组:包括累加器(ACC)、程序状态字寄存器(PSW)、数据指针(DPTR)等,用于暂存数据和中间结果。
2. 存储器系统

单片机的存储器通常采用 哈佛结构(程序存储器和数据存储器分开)或 冯诺依曼结构(统一编址)。

  • 程序存储器(ROM/FLASH)
    • 用于存储用户编写的程序代码和常数(如查表数据)。
    • 掉电后数据不丢失(非易失性)。
  • 数据存储器(RAM)
    • 用于存储运行时的临时数据(如变量、堆栈)。
    • 掉电后数据丢失(易失性)。
3. 寄存器组
  • 是 CPU 内部的高速存储单元,用于快速访问数据,包括:
    • 通用寄存器:如 51 单片机的 R0~R7,用于暂存运算数据。
    • 特殊功能寄存器(SFR):用于控制单片机的外设模块(如定时器、串口、中断等),例如:
      • 定时器控制寄存器(TMOD、TCON)。
      • 串口控制寄存器(SCON)。
      • 中断允许寄存器(IE)。
4. 外设模块

单片机内部集成了丰富的外设,用于实现不同功能:

  • 定时器 / 计数器:用于产生定时信号或计数外部事件(如 51 单片机的 T0、T1)。
  • 串行通信接口(UART/USART):用于单片机与其他设备(如 PC、传感器)的异步通信。
  • 并行 I/O 口:如 51 单片机的 P0~P3 口,可配置为输入或输出模式,连接外部设备(如 LED、按键、LCD)。
  • 模拟信号处理模块
    • 模数转换器(ADC):将模拟信号转换为数字信号(如 STM32 的 ADC 模块)。
    • 数模转换器(DAC):将数字信号转换为模拟信号(部分高端单片机具备)。
  • 中断系统:用于处理外部事件(如按键触发、定时器溢出),提高 CPU 效率。
  • 其他模块:SPI、I²C 通信接口,看门狗定时器(WDT),PWM 输出等。
5. 系统总线
  • 是单片机内部各模块之间传输数据、地址和控制信号的通道,包括:
    • 地址总线(AB):传输存储器或外设的地址信号。
    • 数据总线(DB):传输数据信号。
    • 控制总线(CB):传输控制信号(如读 / 写命令、中断请求等)。

三、典型单片机对比(以 51 和 STM32 为例)

特性 51 系列(如 AT89C51) STM32(ARM Cortex-M 系列)
架构 哈佛结构,8 位 CPU 哈佛结构,32 位 ARM Cortex-M 内核
存储器 片内 FLASH(4~64KB),RAM(128~256B) 片内 FLASH(几十 KB~ 几 MB),RAM(几十 KB)
外设 基本定时器、UART、并行 I/O 丰富外设(ADC、DAC、USB、CAN、SDIO 等)
主频 最高约 24MHz 最高可达 200MHz 以上
应用场景 简单控制、低成本场景(如家电、玩具) 中高端嵌入式系统(如工业控制、物联网)

四、总结

  • 最小系统:是单片机运行的基础,核心包括电源、晶振、复位电路和芯片本身。
  • 内部结构:以 CPU 为核心,搭配存储器、寄存器和各类外设模块,通过总线协同工作。
  • 学习建议:初学者可从 51 单片机入手,理解最小系统搭建和寄存器操作,再进阶到 32 位单片机(如 STM32),学习 HAL 库或寄存器编程。

网站公告

今日签到

点亮在社区的每一天
去签到