【问题标题】:Read a double from 32-bit address flash memory从 32 位地址闪存读取双精度
【发布时间】:2014-02-03 15:45:01
【问题描述】:

我有一个 32 位微控制器,并且刚刚向闪存写入了一个 double。我现在想从内存中读取双精度,但是当微控制器进入硬故障处理程序时,我正在做一些非法的事情。

首先我尝试过:

double Flash_Read64(uint32_t address)
{
    return *((double *) address);
}

但这不起作用。是不是因为地址是 32 位的,而 (double *) 是 64 位的?

然后我尝试了:

double Flash_Read64(uint32_t address)
{
    uint64_t temp;
    double * tempPtr = (double *) &temp;

    //Increment address.
    address += 4;

    //Get MSB.
    temp = (*((uint32_t *) (address)));

    //Shift MSB to upper half.
    temp = (temp << 32);

    //Decrement address.
    address -= 4;

    //Get LSB.
    temp |= (*((uint32_t *) address));

    return *tempPtr;
}

但仍然无法正常工作。

有什么建议吗?

编辑:

bool_t Flash_Write64Address(uint32_t address, double data)
{
    uint32_t MSB, LSB;
    uint32_t * tempPtr = (uint32_t *) &data;

    //Get LSB.
    LSB = tempPtr[0];

    //Write LSB to flash.
    flashStatus = FLASH_ProgramWord(address, LSB);
    if(flashStatus != FLASH_COMPLETE)
    {
        DEBUG("Failed to write to flash at address: %u", (unsigned int) address);
        return FALSE;
    }

    //Increment address.
    address += 4;

    //Get MSB.
    MSB =  tempPtr[1];

    //Write MSB to flash.
    flashStatus = FLASH_ProgramWord(address, MSB);
    if(flashStatus != FLASH_COMPLETE)
    {
        DEBUG("Failed to write to flash at address: %u", (unsigned int) address);
        return FALSE;
    }

    return TRUE;
}

【问题讨论】:

  • 也显示你的写功能。 BTW:你的平台有uint64_t吗?
  • 您系统的小端还是大端?或许你可以先看看this
  • @chux:是的,它有 uint64_t。
  • 是不是因为地址是 32 位而 (double *) 期望是 64 位?,你的系统是 32 位的,你所有的内存寻址都是在 32 位中完成的
  • 我会使用union { double d; uint32_t uint[2] } 进行分解和重建。

标签: c pointers types type-conversion cortex-m3


【解决方案1】:

为了简化和避免对齐问题(我认为这是导致悲伤的对齐问题。)

typedef union {
  double d;
  uint32_t u[2];
} Xlate;

bool_t Flash_Write64Address(uint32_t address, double data) {
   Xlate x;
   x.d = data;
   for (int i=0; i < 2; i++) {
     int flashStatus = FLASH_ProgramWord(address, x.u[i]);
     address += 4;
     if(flashStatus != FLASH_COMPLETE) {
        return FALSE;
     }
   return TRUE;
   }

double Flash_Read64(uint32_t address) {
  Xlate x;
  x.u[0] = *((uint32_t *) address);
  x.u[1] = *((uint32_t *) (address + 4));
  return x.d;
}

[编辑]
我假设address 代表一个四字节对齐的地址(它的至少 2 位是 0)。如果address 没有8-byte alignment(其至少3 位为0)并且double 访问需要它,那么

return *((double *) address);
// or 
return *tempPtr;

会导致总线故障。如果这是真的,上面的代码应该可以处理这个问题。
或者代码可以确保address 具有8-byte alignment。

【讨论】:

  • 感谢您指出内存对齐问题。情况就是这样。从 (address % 2) == 0 的内存位置写入/读取 double 时,它​​可以工作!文档还说内存以 16 位访问,所以这是有道理的。谢谢你!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
  • 1970-01-01
相关资源
最近更新 更多