为什么要将32位地址强制转换为16位以存储16位数据

huangapple go评论82阅读模式
英文:

Why should I typecast a 32 bit address to 16 bit to store a 16 bit data

问题

I am working on an STM32 Flash, I came across this function that writes 16-bit data to an address that is 32-bit. Why should I typecast this address like *(__IO uint16_t*)Address = Data; which expands to *(volatile uint16_t *)Address = Data;

static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_FLASH_ADDRESS(Address));
  
  /* If the previous operation is completed, proceed to program the new data */
  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  FLASH->CR |= FLASH_PSIZE_HALF_WORD;
  FLASH->CR |= FLASH_CR_PG;

  *(__IO uint16_t*)Address = Data;
}

I expect *((uint32_t *)Address) = data to be sufficient.

英文:

I am working on an STM32 Flash, I came across this function that writes 16-bit data to an address that is 32-bit. Why should I typecast this address like *(__IO uint16_t*)Address = Data; which expands to *(volatile uint16_t *)Address = Data;

static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_FLASH_ADDRESS(Address));
  
  /* If the previous operation is completed, proceed to program the new data */
  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  FLASH->CR |= FLASH_PSIZE_HALF_WORD;
  FLASH->CR |= FLASH_CR_PG;

  *(__IO uint16_t*)Address = Data;
}

I expect *((uint32_t *)Address) = data to be sufficient.

答案1

得分: 2

指针是一个内存地址。内存地址本身是32位的。不同之处在于它所指向的数据。当你有一个指向32位整数的指针时,编译器会生成加载和存储32位数据的指令。当你有一个指向16位整数的指针时,编译器会生成加载和存储16位数据的指令。想象一个例子:

MemAdd: 0x100 0x101 0x102 0x103
MemVal: 0xFF  0xFF  0xFF  0xFF

指针: 0x100

如果你执行 *(uint32_t*)(Pointer) = 0x1234,0x100-0x103的内存将包含 0x00001234。如果你执行 *(uint16_t*)(Pointer) = 0x1234,0x100-0x103的内存将包含 0xFFFF1234。另外两个字节没有被覆盖。

由于你想要向闪存写入半字,你需要告诉编译器生成用于存储16位值的指令。

英文:

Pointer is a memory address. A memory address itself is 32-bit. It is the data it's pointing to that is different. When you have pointer to 32-bit integer, the compiler generates instructions that load and store 32 bits of data at a time. When you have a pointer to 16-bit integer, the compiler generates instructions that load and store 16 bits of data. Imagine example:

MemAdd: 0x100 0x101 0x102 0x103
MemVal: 0xFF  0xFF  0xFF  0xFF

Pointer: 0x100

if you *(uint32_t*)(Pointer) = 0x1234, the memory at 0x100-0x103 will contain 0x00001234. If you *(uint16_t*)(Pointer) = 0x1234, the memory at 0x100-0x103 will contain 0xFFFF1234. The other two bytes were never overwritten.

Since you want to write half-word to flash, you want to tell the compiler to generate instructions for storing 16-bit value.

答案2

得分: 1

This operation converts it to the pointer to uint16_t and then dereferences it. It is done to force use of 16 bits write/read instructions in the generated code.

void write16(uint32_t addr, uint16_t val)
{
    *(volatile uint16_t *)addr = val;
}

void write8(uint32_t addr, uint16_t val)
{
    *(volatile uint8_t *)addr = val;
}

void write32(uint32_t addr, uint16_t val)
{
    *(volatile uint32_t *)addr = val;
}
write16:
        strh    r1, [r0]        @ movhi
        bx      lr
write8:
        uxtb    r1, r1
        strb    r1, [r0]
        bx      lr
write32:
        str     r1, [r0]
        bx      lr

When programming flash, it is very important as it is not "normal" write to the memory.

英文:

This operation converts it to the pointer to uint16_t and then dereferences it. It is done to force use of 16 bits write/read instructions in the generated code.

void write16(uint32_t addr, uint16_t val)
{
    *(volatile uint16_t *)addr = val;
}

void write8(uint32_t addr, uint16_t val)
{
    *(volatile uint8_t *)addr = val;
}

void write32(uint32_t addr, uint16_t val)
{
    *(volatile uint32_t *)addr = val;
}
write16:
        strh    r1, [r0]        @ movhi
        bx      lr
write8:
        uxtb    r1, r1
        strb    r1, [r0]
        bx      lr
write32:
        str     r1, [r0]
        bx      lr

When programing flash it is very important as it is not "normal" write to the memory.

huangapple
  • 本文由 发表于 2023年3月1日 08:40:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75598629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定