STM32F4内的FLASH和RAM

STM32F4内的FLASH和RAM(CCM)

单片机的flash和RAM,可以简单理解为电脑的硬盘和内存条。

FLASH

什么是FLASH?FLASH的作用?

掉电不丢失数据,能够存储数据的存储器,所以用于存储单片机的程序,单片机重启上电,根据起始地址,flash上的程序。

这里FLSH有分为NANDFLASH和NORFLASH,这两者的主要区别就是,访问存储的单位空间大小不同,一个是块(一般是512字节),一个是字节,程序是以字节单位访问执行代码,所以用户可以直接运行装载在NOR FLASH里面的代码,这样可以减少内存的容量从而节约了成本;用户不能直接运行NAND Flash上的代码,因此好多使用NAND Flash的开发板除了使用NAND Flah以外,还作上了一块小的NOR Flash来运行启动代码,或者加载到内存执行。

RAM

什么是RAM?RAM的作用?

掉电会丢失的存储器,指的就是内存,用于存储相关变量以及执行代码。

在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区、堆区、全局区(静态区)

常量区、代码区,其中全局区中高地址分布着.bss段低地址分布着.data段

内存分区

栈区(stack):由编译器自动分配释放,存放写局部变量、参数和const修饰的局部变量等

堆区(heap):动态内存分配,malloc请求和free释放,用户申请使用。

全局区(静态区) :有.bss段和.data段组成,可读可写。

.data:已经初始化的全局变量、静态变量。const定义的全局变量存放在.rodata段。占用可执行文件空间,其内容有程序初始化。

.bass:未初始化的全局变量、初始化为0 的全局变量。不占用可执行文件空间,其内容有操作系统初始化。

code:程序执行代码存放在代码区

单片机的程序存储分为code(代码存储区)RO-data(只读数据存储区)RW-data(读写数据存储区)ZI-data(零初始化数据区)

Flash 存储 code和RO-data
Sram 存储 RW-data 和ZI-data

STM32F4有两部分内存空间SRAM和CCM

以STM32F407为例,192K的内存包括64K的CCM(仅CPU可访问)、112K的SRAM1(主RAM)和16K的SRAM2(外设使用)
STM32F4内的FLASH和RAM_第1张图片

64K的CCM内存只能被内核的D-bus(数据总线)进行访问,.将CCM用作高速运算缓冲。
为什么会有RAM1和RAM2?
为了能快速访问数据,DMA和CUP可以分别同时访问RAM1和RAM2,提高读取数据的速度。

怎样将变量存储在CMM内存中?

CCM内存的基地址是0x10000000,可以使用__attribute __((at(address)))语句自己分配指定的内存。 int value[10] __ attribute __ ((at(0x10000000)))

CCM下的RAM空间非常适合用于RTOS的任务堆栈,但切勿用于DMA。这个RAM空间不支持DMA操作。

将实时操作系统的数据存放在CCM

以freertos为例,为了不修改源代码,我们只能自己定义连接器的存储器映射,修改Keil的Linker选项,我们把Use Memory Layout from Targer Dialog的钩去掉。
STM32F4内的FLASH和RAM_第2张图片

找到.sct文件,修改为


LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00030000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {  ; RW data
   *(.CCM_RAM)
   heap_4.o(+RW +ZI)
   queue.o(+RW +ZI)
   port.o(+RW +ZI)
   tasks.o(+RW +ZI)
  }
  RW_IRAM3 0xC0000000 0x01000000  {  ; RW data
   *(.SDRAM)
  
  }
}

此时RTOS的堆栈空间都存放在CCM内存。

在变量前加上 __ attribute __((section (".CCM_RAM")))的前缀,指定变量存放在CCM。

/* 定义在CCM RAM里面的变量 */
__attribute__((section (".CCM_RAM"))) uint32_t CCMBuf1[10];
__attribute__((section (".CCM_RAM"))) uint16_t CCMCount;

/* 定义在SDRAM里面的变量 */
__attribute__((section (".SDRAM"))) uint32_t SDRAMBuf1[10];
__attribute__((section (".SDRAM"))) uint32_t SDRAMCount;

你可能感兴趣的:(C语言,单片机,stm32)