2026/1/7 20:09:50
网站建设
项目流程
做内贸哪个网站好,智能写作网站,济南网站设计公司,网站建设策划书 范文目录
1. 静态布局
1.1 FLASH里存了什么#xff1f;
1.1.1 中断向量表 (Vector Table)
1.1.2 代码段 (.text)
1.1.3 只读数据段 (.rodata)
1.1.4 读写数据段 (.rwdata)
总结#xff1a;
1.2 SRAM里存了什么#xff1f;
1.2.1 已初始化数据段 (.data)
1.2.2 未初始化…目录1. 静态布局1.1 FLASH里存了什么1.1.1 中断向量表 (Vector Table)1.1.2 代码段 (.text)1.1.3 只读数据段 (.rodata)1.1.4 读写数据段 (.rwdata)总结1.2 SRAM里存了什么1.2.1 已初始化数据段 (.data)1.2.2 未初始化数据段 (.bss)1.2.3 堆区 (Heap)1.2.4 栈区 (Stack)总结2. 时间维度上内存的变化过程2.1 硬件复位 - 读取向量表2.2 Reset_Handler 开始执行2.3 .data 段初始化 - 从 FLASH 拷贝到 SRAM2.4 .bss 段清零2.5 进入 main() → RT-Thread 初始化2.6 创建线程 → 调度器启动总结1. 静态布局图1.1-FLASH与SRAM内容总览1.1 FLASH里存了什么向量表MSP初始值 Reset_Handler地址 中断处理函数地址.text 段所有函数的机器码.rodata 段const 常量、字符串.rwdata段 全局变量的初始值副本1.1.1 中断向量表 (Vector Table)中断向量表是系统最先读取的地方决定了程序从哪里开始执行。前两个最重要的字0x08000000: 初始 MSP 值主栈指针、0x08000004: Reset_Handler 地址复位后第一条指令的位置。后续是各种中断处理函数地址NMI_Handler, HardFault_Handler, SysTick_Handler, USART1_IRQHandler...1.1.2 代码段 (.text)代码段存的是所有函数编译后的机器指令CPU 从这里取指令执行。包含内容启动代码 (Reset_Handler, SystemInit)main() 函数及你写的所有函数RT-Thread 内核代码 (rt_thread_create, rt_schedule...)【ps:有用到RT-Thread的情况下】库函数代码 (HAL_GPIO_WritePin, printf...)1.1.3 只读数据段 (.rodata)只读数据段存的是程序运行期间不会改变的数据。典型内容const char *msg Hello;→ 字符串 Hello 存这里const int table[] {1,2,3};→ 常量数组switch-case跳转表浮点常量、查找表1.1.4 读写数据段 (.rwdata)读写数据段存的是已初始化全局变量的初始值启动时会被拷贝到 SRAM。为什么需要这个int counter 100;→ 100 这个初始值存在 FLASH因为 SRAM 掉电丢失每次上电需要从 FLASH 恢复初始值启动代码负责把这块数据拷贝到 SRAM 的 .data 段总结FLASH 是只读的程序存储器存放不变的东西代码、常量、以及变量的初始值模板。CPU 执行代码时从 FLASH 取指令。1.2 SRAM里存了什么.data 段已初始化全局变量从 FLASH 拷贝来.bss 段未初始化全局变量启动时清零堆rt_malloc 动态分配区栈局部变量、函数调用1.2.1 已初始化数据段 (.data).data段存的是有初始值的全局变量和静态变量值从 FLASH 拷贝而来。哪些变量在这里int g_counter 100;→ 全局变量初始值 100static int s_flag 1;→ 静态变量初始值 1char g_name[] LED;→ 初始化的数组特点可读可写程序运行时可以修改这些值1.2.2 未初始化数据段 (.bss).bss段存的是未初始化或初始化为 0 的全局/静态变量启动时被清零。哪些变量在这里int g_value;→ 未初始化默认 0static char buffer[256];→ 未初始化的数组int g_zero 0;→ 显式初始化为 0为什么单独分出来不需要在 FLASH 中存储初始值节省 FLASH 空间1.2.3 堆区 (Heap)动态内存分配区域如果使用了RT-Thread则由 RT-Thread 内存管理器管理。裸机开发则在.s启动文件中进行配置堆区的空间大小。谁使用堆malloc()rt_malloc()/rt_free()rt_thread_create()→ 分配 TCB 线程栈rt_mq_create()→ 消息队列缓冲区rt_sem_create()→ 信号量控制块RT-Thread 堆初始化rt_system_heap_init(heap_begin, heap_end);1.2.4 栈区 (Stack)函数调用的工作区局部变量、返回地址、寄存器保存主栈 (MSP) 用于启动代码执行 (Reset_Handler → main)所有中断处理函数线程栈 (PSP) 用于每个 RT-Thread 线程有独立的栈线程的局部变量、函数调用链栈上存什么int local_var 5;→ 局部变量函数参数、返回地址、保存的寄存器总结SRAM 是可读写的运行时存储器存放会变化的东西全局变量、动态分配的内存、函数调用栈。掉电后内容全部丢失。2. 时间维度上内存的变化过程图2.1-时间维度上内存的变化过程2.1 硬件复位 - 读取向量表CPU 复位所有寄存器清零硬件自动从 0x08000000 读取 4 字节 → 加载到 MSP硬件自动从 0x08000004 读取 4 字节 → 加载到 PCCPU 开始从 PC 指向的地址取指令执行2.2 Reset_Handler 开始执行调用 SystemInit() 配置时钟、Flash等待周期准备进行内存初始化此时还不能使用全局变量因为还没初始化2.3 .data 段初始化 - 从 FLASH 拷贝到 SRAM找到 FLASH 中 .data 初始值的位置找到 SRAM 中 .data 段的位置 (_sdata)逐字节拷贝直到 _edata所有带初始值的全局变量现在有了正确的值2.4 .bss 段清零找到 .bss 段的起始 (_sbss) 和结束 (_ebss)将整个区域填充为 0所有未初始化的全局变量现在是 02.5 进入 main() → RT-Thread 初始化调用 main()RT-Thread 初始化内核rt_system_heap_init() 初始化堆内存管理器现在可以使用 rt_malloc() 了2.6 创建线程 → 调度器启动rt_thread_create() 从堆中分配 TCB 栈初始化线程栈帧rt_thread_startup() 将线程加入就绪队列rt_system_scheduler_start() 启动调度切换到 PSP第一个线程开始运行总结上电后硬件设置 MSP/PC → 启动代码拷贝 .data → 清零 .bss → 初始化堆 → 创建线程 → 运行