This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/TM4C1292NCPDT:EEPROM 读/写问题

Guru**** 2392905 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/734749/rtos-tm4c1292ncpdt-eeprom-read-write-issue

器件型号:TM4C1292NCPDT

工具/软件:TI-RTOS

您好!

我的应用程序需要将启动参数存储在 EEPROM 中、它将在程序执行过程中使用、这些值将经常从应用程序软件中更新。

这些值最初在闪存扇区中可用(通过 J-Tag 编程)、并在首次引导时写入 EEPROM、之后固件将使用 EEPROM 存储器中的值。

我之前使用过闪存扇区本身的这些变量。 与闪存相比、EEPROM 的耐久度更高、因此我已将闪存扇区移至 EEPROM 扇区。  

当替换为 EEPROM API 而不是闪存 API 时、我会得到可实现无限循环的硬件异常、而且我还会观察到一些其他任务堆栈使用量正在变满、即使该任务未运行。

之前使用以下代码。

void flashWrite (boot_struct * stFlashData)
{
内转台;

RET = FlashErase (((uint32_t) flash_common_memory_address);
if (ret!=空)
{
system_printf ("闪存未成功擦除\n"\n);
}

RET = FlashProgram (((uint32_t *) stFlashData、
FLASH_common_memory_address、2048);
if (ret!=空)
{
system_printf ("闪存未成功编程\n"\n);
}

system_flush();
} 

boot_struct flashRead (boot_struct * stFlashData)
{
stFlashData =(boot_struct *) flash_common_memory_address);
return * stFlashData;
} 

我将替换为以下 API。

#define EPROM_START_ADDRESS 0x0
#define BOOT_PARAMETER_SIZE 1024

空 EpromWrite (boot_struct * stEpromData)
{
RET = EEPROMMassEras();
if (ret!= 0)
{
System_printf ("EEPROM 擦除失败:错误号-%d\n"、ret);
}

RET = EEPROMProgram ((uint32_t *) stEpromData、EPROM_START_ADDRESS、
boot_parameter_size);
if (ret!= 0)
{
system_printf ("EPROM 数据写入失败:错误号-%d\n"、ret);
}

}


//使用折页 API 读取数据。
EEPROMRead (((uint32_t *) stEpromData、EPRO_START_ADDRESS、
boot_parameter_size); 

我已经使用断点进行了检查、 EEPROM 读取始终成功。 我将能够看到读取数据结构中的值。 在读取完成并尝试执行某些其他例程后、会发生硬件异常。 但当替换为闪存 API 时、其工作正常。

您能帮我找到解决方案吗? EEPROM 写入/读取之前是否存在任何其他依赖项。

我使用以下版本的工具集。

CCS8.1

tirtos_tivac_2_16_01_14

TivaWare_C_Series-2.1.4.178

此致

巴拉

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Bala、
    不能完全确定是什么问题。 您将(uint32_t *) stEpromData 作为第一个参数传递给 EEPROMRead。 您是如何以及在何处定义该指针变量的? 我知道您需要键入(uint32_t *)。 但在最初声明时、它是否可能与字边界对齐? 接下来、如果您查看下面的 API 说明、则会显示 hte pui32Data 必须指向可用存储器的至少 ui32Count 字节。 这是要检查的东西。 为什么不减小 boot_parameter_size? 从像4这样的小值开始并逐渐增加。 尺寸在问题中是否起作用?

    原型:
    无效
    EEPROMRead (uint32_t * pui32Data、
    uint32_t ui32地址、
    uint32_t ui32计数)
    参数:
    pui32Data 是从 EEPROM 读取数据的存储指针。 此指针必须指向
    至少 ui32Count 字节的可用存储器。
    ui32Address 是要从中读取数据的 EEPROM 中的字节地址。 这种情况
    值必须是4的倍数。
    ui32Count 是要从 EEPROM 读取的数据字节数。 此值必须为 A
    4的倍数。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Charles、

    感谢您的快速回复。

    [引用 user="Charles Tsaaaaai">您将(uint32_t *) stEpromData 作为 EEPROMRead 的第一个参数。 您是如何以及在何处定义该指针变量的? 我知道您需要键入(uint32_t *)。 但最初声明时、它是否可能与字边界不对齐?

    它是指定为 uint32_t*的结构指针。 下面是结构定义。 这意味着结构的大小应该是字对齐的。 如何测量该结构的大小或确定它将如何在 cortex-M4控制器中对齐?

    typedef 结构体 BootDataStructure
    {
    bool bUpdateFlag;
    bool bNif;
    bool braif;
    bool bValidatedFlag;
    bool bBootedFlag;
    char cBaseIPAddr[32];
    char cIPAddr[32];
    char cIPMask[32];
    char cIPGateAddr[32];
    char cDomain[32];
    char cTftpIPAddr[32];
    char cCurrentImageName[32];
    char cGoldenImageName[32];
    char cFileName[32];
    字符 cSerialNum[32];
    字符 cPartNum[32];
    char cModuleConfigNum[32];
    uint8_t ui8DiSourceSink;
    uint8_t ui8UsrPgmTaskPrimin;
    uint8_t ui8UsrPgmTaskPriMax;
    uint8_t ui8AIMedian[8];
    uint16_t ui16BootDiLed;
    uint16_t ui16BootDoLed;
    uint16_t ui16DiDebounceM;
    uint16_t ui16AIFormatM;
    uint16_t ui16AoutRangeM;
    uint16_t ui16AinRangeM;
    uint16_t ui16AoutRangeA;
    uint16_t ui16AoutRangeB;
    uint16_t ui16AoutFormatM;
    uint16_t ui16AoutFormatA;
    uint16_t ui16AoutFormatB;
    uint16_t ui16DoSourceSink;
    uint16_t ui16ClkInDIV;
    uint16_t ui16ClkOutDIV;
    uint16_t ui16downloadStatus;
    uint16_t ui16SerBaud;
    uint16_t ui16SerSignal;
    uint16_t ui16CicDecimate[8];
    uint16_t ui16DiDebouncy[12];
    uint16_t ui16AiO 范围[8];
    uint16_t ui16AiO 格式[8];
    uint16_t ui16AinRange0Gain[8];
    uint16_t ui16AinRange1Gain[8];
    uint16_t ui16AinRange2Gain[8];
    uint16_t ui16AinRange3Gain[8];
    uint16_t ui16AinRange0Offset[8];
    uint16_t ui16AinRange1Offset[8];
    uint16_t ui16AinRange2Offset[8];
    uint16_t ui16AinRange3Offset[8];
    uint16_t ui16AoutRange0Gain[6];
    uint16_t ui16AoutRange1Gain[6];
    uint16_t ui16AoutRange2Gain[6];
    uint16_t ui16AoutRange3Gain[6];
    uint16_t ui16AoutRange0Offset[6];
    uint16_t ui16AoutRange1Offset[6];
    uint16_t ui16AoutRange2Offset[6];
    uint16_t ui16AoutRange3Offset[6];
    uint32_t ui32DowmloadCRC;
    uint32_t ui32CurrentImageLocation;
    uint32_t ui32SignatureData;
    }BOOT_STRUCT;
    

    [引用 USER="Charles Tsaaaia]接下来、如果您看一下下面的 API 说明、它说 hte pui32Data 必须指向至少 ui32Count 字节的可用存储器。 [/引用]只有我们尝试写入和读回它的这个结构。 具体操作如下所示。

    在闪存扇区0x0运行的引导加载程序(裸机代码)将数据写入 EEPROM、而运行0x4000的固件(RTOS 代码)将读回。 未尝试在主固件中进行写入。  

    此致

    巴拉

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    问题是我尝试从 EEPROM 读取的数据结构的大小超过了、这会导致另一个任务内存损坏。 此外、数据结构也不会提前进行字对齐。

    现在、通过使数据结构字对齐以及读取和写入结构变量的大小来解决该问题。

    您的快速回复解决了我的问题。 谢谢你。

    此致
    巴拉