FLASH与RAM

STM32内的FLASH与RAM

  • FLASH
    • 1、什么是FLASH? FLASH的作用是什么?
    • 2、Nand Flash & Nor Flash
  • RAM
    • 1、什么是RAM? RAM的作用?
  • 内存分区
    • 1、四区分配
    • 2、单片机的程序存储
    • 3、STM32有两部分内存空间
    • 4、为什么会有RAM1和RAM2?
    • 5、怎样将变量存储在CMM内存中?
    • 6、将实时操作系统的数据存放在CCM

单片机的flash和RAM, 相当于电脑的硬盘和内存条

FLASH

1、什么是FLASH? FLASH的作用是什么?

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

2、Nand Flash & Nor Flash

1 )Nand Flash
访问存储的单位空间大小为块(一般是512字节)
2 ) Nor Flash
访问空间为字节, 程序是以字节为单位访问执行代码,
因此, 用户可以直接在 Nor Flash 上运行代码;,这样可以减少内存的容量从而节约了成本; 用户不能直接在 Nand Flash 上运行代码, 因此好多使用 Nand Flash 的开发板, 还需加上一小块 Nor Flash 来运行启动代码,或者加载到内存执行

RAM

1、什么是RAM? RAM的作用?

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

内存分区

1、四区分配

在一个stm32程序代码中,从内存高地址到低地址,依次分布着栈区、堆区、全局区(静态区、常量区)、代码区、其中全局区中高地址分布着.bss段,低地址分布着.data段。
FLASH与RAM_第1张图片

1、栈区(stack):由编译器自动分配释放,存放着局部变量、参数和const修饰的局部变量等。
2、堆区(heap):动态内存分配,malloc请求和free释放,用户申请使用。
malloc函数分配完内存需要注意:
a.检查是否分配成功----若分配成功,返回内存的首地址;若分配不成功,返回NULL,可以通过if语句来判断
b.清空内存中的数据----malloc分配的空间可能存在垃圾值,用memset或bzero函数清空内存
3、全局区(静态区):有.bass段和.data段组成,可读可写。
》.bss:未初始化的全局变量,初始化为0的全局变量。不占用可执行文件空间,其内容有操作系统初始化。
》.data:已经初始化的全局变量、静态变量。const定义的全局变量存放在.rodata段。占用可执行文件空间,其内容有程序初始化。
4、代码区(code):程序执行代码存放在代码区

2、单片机的程序存储

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

  1. Flash 存储code和RO-data
  2. Sram 存储RW-data和ZI-data

3、STM32有两部分内存空间

SRAM 和 CCM
以STM32F407为例,192K的内存包括64K的CCM(仅CPU可访问)、112K的SRAM1(主RAM)和16K的SRAM2(外设使用)

64K的CCM内存只能被内核的D-bus(数据总线)进行访问,.将CCM用作高速运算缓冲。

4、为什么会有RAM1和RAM2?

为了能快速访问数据,DMA和CUP可以分别同时访问RAM1和RAM2,提高读取数据的速度。

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

1) CCM内存的基地址是0x10000000,可以使用__attribute __((at(address)))语句自己分配指定的内存。 int value[10] __ attribute __ ((at(0x10000000)))
2)CCM下的RAM空间非常适合用于RTOS的任务堆栈,但切勿用于DMA。这个RAM空间不支持DMA操作。

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

以freertos为例,为了不修改源代码,我们只能自己定义连接器的存储器映射,修改Keil的Linker选项,我们把Use Memory Layout from Targer Dialog的钩去掉。
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;

你可能感兴趣的:(STM32,单片机,javascript,嵌入式硬件)