1. Memory Mapping
Memory mapping is a computer memory management technique that maps a portion of a computer's memory into the processor's address space. In this way, the processor can directly access the address mapped in memory without complex addressing calculations. Memory mapping can be used to access a computer's physical memory, device registers, hardware devices, and more. In memory mapping, different addresses are mapped to different actual memory locations or hardware devices, which simplifies the management and operation of memory.
The memory is a device that can store data and has no address information. The process of assigning addresses to the memory is called memory mapping.
Review a little knowledge first:
1 Byte = 8 bit(位)
1 Kilobyte (KB) = 1,024 Bytes
1 Megabyte (MB) = 1,024 KB
1 Gigabyte (GB) = 1,024 M
1 Terabyte (TB) = 1,024 G
The memory size of the single-chip microcomputer we are talking about is bytes, not bits.
Assuming a certain chip has 19 address lines: A0-A18, and data lines: D0-D15 (16 bits, two bytes), the number of labels that can be accessed by it is 2^19 bytes, 512 KB Address, 512K*2 = 1024bit = 1M. Next, we map its memory.
address range | 0-512K |
map 1 | 0-512K(0x0-0x80000) |
map 2 | 1-512K(0x0-0x80000) |
map 3 | 100k-612K |
map 3 | 512K-1024K |
Division of memory functions (F1 as an example)
ST divides the 4GB (2^32) address space into 8 blocks
ST's 4GB address space can be divided into 8 blocks, each block is 512MB.
The specific distribution is as follows:
1. Block 0 (Code(FLASH)): 0x00000000 ~ 0x1FFFFFF (mainly used to store code)
2. Block 1 (SRAM): 0x20000000 ~ 0x3FFFFFFF
3. Block 2 (on-chip peripherals): 0x40000000 ~ 0x5FFFFFF (most important)
4 . Block 3 (FSMC Bank1&2): 0x60000000 ~ 0x7FFFFFF
5. Block 4 (FSMC Bank3&4): 0x80000000 ~ 0x9FFFFFFF
6. Block 5 (FSMC Register): 0xA0000000 ~ 0xBFFFFFF
7. Block 6 (not used): 0 xC0000000 ~ 0xDFFFFFFF
8. Block 7 (Cortex M3 internal peripherals): 0xE0000000 ~ 0xFFFFFFFF
Each block has an address space of 512MB, which can be used to store different programs, data, and kernel codes. This block method facilitates the memory management of the operating system and application programs, and improves the stability and performance of the system.
2. Register mapping (important)
The register is a special memory inside the single chip microcomputer, which can realize the control of various functions of the single chip microcomputer.
To put it simply: the register is the control mechanism inside the microcontroller.
What is register map?
Registers are special memories, and the process of naming register addresses is called register mapping.
For example, the address of one of our registers is 0x4001080C, we name the register GPIOA_ODR (register name), this process is called register mapping.
How to manipulate registers directly
*(unsigned int*)(0x4001080C) = 0XFFFF;
That is, all the bits of GPIOA_ODR are 1, that is, PA0-PA15 are all 1.
Define a name and then operate
# define GPIO_ODR *(unsigned int *)(0X4001080C)
GPIO_ODR = 0XFFFF;
3. Register mapping calculation
Question 1: How to find and calculate the register address?
Question 2: How to map?
solve one
For the convenience of writing code and using it, our register address is divided into three parts:
1. Bus base address (BUS_BASE_ADDR)
2. The offset of the peripheral based on the bus base address (PERIPH_OFFSET)
3. The offset of the register relative to the base address of the peripheral (REG_OFFSET)
Register address = BUS_BASE_ADDR+PERIPH_OFFSET+REG_OFFSET
Taking F1 as an example, our bus base address is as follows
bus | base address | Offset |
APB1 | 0X4000 0000 | 0 |
APB2 | 0X4001 0000 | 0X1 0000 |
AHB | 0X4001 8000 | 0X1 8000 |
The base address of the APB1 bus, also called the base address of the peripheral (PERIPH_BASE)
The offset of this table: is the base address of the relative peripheral.
GPIO peripheral base address and offset
belongs to the bus | peripherals | base address | Offset |
APB2 0X4001 0000 |
GPIOA | 0X4001 0800 | 0X0800 |
GPIOB | 0X4001 0C00 | 0X0C00 | |
GPIOC | 0X4001 1000 | 0X1000 | |
GPIOD | 0X4001 1400 | 0X1400 | |
GPIOE | 0X4001 1800 | 0X1800 | |
GPIOF | 0X4001 1C00 | 0X1C00 | |
GPIOG | 0X4001 2000 | 0X2000 |
The offset of this table: is the offset relative to the APB2 peripheral base address (APB2 PERIPH_OFFSET )
GPIO peripheral base address and offset
belongs to the bus | Peripherals | register | address | Offset |
APB2 0X4001 0000 |
GPIO 0X4001 0800 |
GPIOA_CRL | 0X4001 0800 | 0X00 |
GPIOA_CRH | 0X4001 0804 | 0X04 | ||
GPIOA_IDR | 0X4001 0808 | 0X08 | ||
GPIOA_ODR | 0X4001 080C | 0X0C | ||
GPIOA_BSRR | 0X4001 0810 | 0X10 | ||
GPIO_BRR | 0X4001 0814 | 0X14 | ||
GPIO_LCKR | 0X4001 0818 | 0X18 |
GPIO_ODR register address calculation process:
1. Obtain which bus the peripheral is connected to? Check: system structure diagram
2. Obtain the base address of the bus, the base address of the APB2 bus is: 0X4001 0000
3. Obtain the offset of the peripheral address, the offset of GPIOA relative to the APB2 bus is: 0X800
4. Obtain the offset of the register address, the offset of the ODR relative to the base address of the GPIOA peripheral is 0X0C.
Register address = BUS_BASE_ADDR+PERIPH_OFFSET+REG_OFFSET
GPIO_ODR = 0X4001 0000+0X800+0X0C=0X4001 080C
Solution two:
Using the structure can easily realize the mapping of registers
typdef struct
{
_IO uint32_t CRL;
_IO uint32_t CRH;
_IO uint32_t IDR;
_IO uint32_t ODR;
_IO uint32_t BSRR;
_IO uint32_t LCKR;
}GPIO_TypeDef;
Overall mapping:
# define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)
Take the address inside:
&GPIOA->CRL: 0X4001 0800
&GPIOA->CRH:0X4001 0804
&GPIOA->IDR: 0x40010808
&GPIOA->ODR:0X4001 080C
Practical application:
GPIO->ODR= 0XFFFF;