Essential knowledge for embedded software development - memory and register mapping (important)

 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;

Guess you like

Origin blog.csdn.net/zywcxz/article/details/131035001