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.

[参考译文] MSPM0G3507:持久存储

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1326828/mspm0g3507-persistent-storage

器件型号:MSPM0G3507

我没有看到一个示例、如何为要在电源循环之间保留的设置留出存储空间?

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

    嘿、Keith、

    要做到这一点、没有一个简单的方法(与 FRAM 不同)。 您很可能需要将其作为存储器中的指针执行此操作、然后当您准备好"保存"该变量的状态时、在指针地址写入闪存。 (闪存写入示例。) 如果您确实需要经常执行此操作、则应考虑使用 EEPROM 示例和较低的32kB 存储器来实现更高的写入周期。  

    现在有一个 TI clang #persistent 声明 可能会有所帮助、因为在重置此属性时不会重新初始化变量。 您仍需要单独处理向非易失性存储器的复制。  

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

    谢谢您的

    讲解。 该示例将内容存储在 MAIN_BASE_ADDRESS (0x00001000) 我怎么知道这是"安全的"?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嘿、Keith、

    闪存写入示例不能保证该区域在代码方面是安全的。 选择地址是因为编译的代码永远不会到达闪存的该区域。 知道程序的性质就能保证安全性。 如果需要确定性更强的方法、我建议自定义链接器文件、以分配一个闪存区域供编写。

    因此、在链接器文件的"Memory"部分中挖出一个特殊段、并确保编译器不会将任何内容放入其中、方法是将该段保留在链接器的"SECTIONS"部分之外。  

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

    我对这件事不熟悉、我曾尝试这么做、但遇到了链接器错误-这是一件好事。 是否有相关的教程?

    另外、Theia 是否有方法了解使用了多少闪存?

    更多详细信息:

    我曾尝试分割出一个8 KB 的部分、这远远超过了我需要的值(96字节)、所以我更改了这个:

    内存
    {
      闪存      (Rx) :origin = 0x00000000、length = 0x00020000
      SRAM       (rwx):origin = 0x20200000,length = 0x00008000
      BCR_CONFIG   (R) :origin = 0x41C00000、length = 0x00000080
      BSL_CONFIG   (R) :origin = 0x41C00100、length = 0x00000080

    为此、请执行以下操作:

    内存
    {
      闪存      (Rx) :origin = 0x00002000、length = 0x0001E000
      SRAM       (rwx):origin = 0x20200000,length = 0x00008000
      BCR_CONFIG   (R) :origin = 0x41C00000、length = 0x00000080
      BSL_CONFIG   (R) :origin = 0x41C00100、length = 0x00000080

    链接器卡住。 我只能改变什么?

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

    添加了:

    我甚至查看了 EEPROM 示例、该示例大概确实细出了闪存部分、但没有区别。 所有符号链接。

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

    Keith、

    对于链接器调整、您还需要将段添加到存储器中。 但请记住、随着中断表加载到存储器的开头、您可能还需要向前移动中断表。

    如下所示:(请注意、我不考虑这里的 ISR 表。)

    MEMORY
    
    {
        App_Write       (RW)  : origin = 0x00000000, length = 0x00002000
        
        FLASH           (RX)  : origin = 0x00002000, length = 0x0001E000
    
        SRAM            (RWX) : origin = 0x20200000, length = 0x00008000
    
        BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x00000080
    
        BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
    
    
    
    }

    对于 EEPROM 示例、我将介绍  、因为他对该示例比较熟悉。 您需要参考类型 A 或 B 的用户指南、以了解它们是如何设置该结构的。  

    MSPM0 EEPROM 类型 A

    MSPM0 EEPROM B 类

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

    好吧、更荒谬的是、当我采用 flashctl 多大小写入示例并在循环中添加32位写入时、它绝不会降落、

    DL_FlashCTL_programMemoryFromRAM32WithECCGenerated ()

    返回的代码*3*不是枚举项之一。

    #include "ti_msp_dl_config.h"
    #include <stdio.h>
    #include <string.h>
    
    
    /* Address in main memory to write to */
    #define MAIN_BASE_ADDRESS (0x00001000)
    
    /* 8-bit data to write to flash */
    uint8_t gData8 = 0x11;
    
    /* 16-bit data to write to flash */
    uint16_t gData16 = 0x2222;
    
    /* 32-bit data to write to flash */
    uint32_t gData32 = 0x33333333;
    
    /* Array to write 64-bits to flash */
    uint32_t gDataArray64[] = {0xABCDEF00, 0x12345678};
    
    volatile DL_FLASHCTL_COMMAND_STATUS gCmdStatus;
    
    /* Codes to understand where error occured */
    #define NO_ERROR 0
    #define ERROR_ERASE 1
    #define ERROR_8BIT_W 2
    #define ERROR_16BIT_W 3
    #define ERROR_32BIT_W 4
    #define ERROR_64BIT_W 5
    
    volatile uint8_t gErrorType = NO_ERROR;
    
    // place to store the variables
    uint8_t Recall8;
    uint16_t Recall16;
    uint32_t Recall32;
    
    int main(void) {
    
      SYSCFG_DL_init();
    
      // Check the Memory
      Recall8 = *(uint8_t *)(MAIN_BASE_ADDRESS);
      Recall16 = *(uint16_t *)(MAIN_BASE_ADDRESS + 8);
      Recall32 = *(uint32_t *)(MAIN_BASE_ADDRESS + 16);
    
      /* Unprotect sector in main memory with ECC generated by hardware */
      DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
                                  DL_FLASHCTL_REGION_SELECT_MAIN);
      /* Erase sector in main memory */
      gCmdStatus = DL_FlashCTL_eraseMemoryFromRAM(FLASHCTL, MAIN_BASE_ADDRESS,
                                                  DL_FLASHCTL_COMMAND_SIZE_SECTOR);
      if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
        /* If command was not successful, set error flag */
        gErrorType = ERROR_ERASE;
      }
    
      if (gErrorType == NO_ERROR) {
        /* 8-bit write to flash in main memory */
        DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
                                    DL_FLASHCTL_REGION_SELECT_MAIN);
        gCmdStatus = DL_FlashCTL_programMemoryFromRAM8WithECCGenerated(
            FLASHCTL, MAIN_BASE_ADDRESS, &gData8);
        if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
          /* If command was not successful, set error flag */
          gErrorType = ERROR_8BIT_W;
        }
      }
    
      if (gErrorType == NO_ERROR) {
        /*
         * 16-bit write to flash in main memory with ECC generated by hardware.
         * The target program address must be a flash word address
         * (8-byte aligned), so we increase the address in increments of 8.
         */
        DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
                                    DL_FLASHCTL_REGION_SELECT_MAIN);
        gCmdStatus = DL_FlashCTL_programMemoryFromRAM16WithECCGenerated(
            FLASHCTL, (MAIN_BASE_ADDRESS + 8), &gData16);
        if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
          /* If command was not successful, set error flag */
          gErrorType = ERROR_16BIT_W;
        }
      }
    
      if (gErrorType == NO_ERROR) {
        /* 32-bit write to flash in main memory with ECC generated by hardware */
        DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
                                    DL_FLASHCTL_REGION_SELECT_MAIN);
        gCmdStatus = DL_FlashCTL_programMemoryFromRAM32WithECCGenerated(
            FLASHCTL, (MAIN_BASE_ADDRESS + 16), &gData32);
        if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
          /* If command was not successful, set error flag */
          gErrorType = ERROR_32BIT_W;
        }
      }
    
      if (gErrorType == NO_ERROR) {
        /*
         * 64-bit write to flash in main memory with ECC generated by hardware.
         * Data must be loaded 32-bits at a time, but a single word program
         * is executed
         */
        DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
                                    DL_FLASHCTL_REGION_SELECT_MAIN);
        gCmdStatus = DL_FlashCTL_programMemoryFromRAM64WithECCGenerated(
            FLASHCTL, (MAIN_BASE_ADDRESS + 24), &gDataArray64[0]);
        if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
          /* If command was not successful, set error flag */
          gErrorType = ERROR_64BIT_W;
        }
      }
    
      /* After successful completion, toggle LED and USER_TEST pin */
      if (gErrorType == NO_ERROR) {
        /*
         * Check the contents of MAIN_BASE_ADDRESS at breakpoint:
         * FF FF FF 11
         * FF FF FF FF
         * FF FF 22 22
         * FF FF FF FF
         * 33 33 33 33
         * FF FF FF FF
         * AB CD EF 00
         * 12 34 56 78
         */
        while (1) {
          DL_GPIO_togglePins(GPIO_LEDS_PORT,
                             GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
    
          // Check the Memory
          Recall8 = *(uint8_t *)(MAIN_BASE_ADDRESS);
          Recall16 = *(uint16_t *)(MAIN_BASE_ADDRESS + 8);
          Recall32 = *(uint32_t *)(MAIN_BASE_ADDRESS + 16);
          delay_cycles(16000000);
    
          gData32 = 31;
    
    
          /* 32-bit write to flash in main memory with ECC generated by hardware */
        DL_FlashCTL_unprotectSector(FLASHCTL, MAIN_BASE_ADDRESS,
                                    DL_FLASHCTL_REGION_SELECT_MAIN);
        gCmdStatus = DL_FlashCTL_programMemoryFromRAM32WithECCGenerated(
            FLASHCTL, (MAIN_BASE_ADDRESS + 16), &gData32);
        if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) {
          /* If command was not successful, set error flag */
          gErrorType = ERROR_32BIT_W;
        }
        }
      }
      /* Unsuccessful example run */
      else {
        /* Check gErrorType value */
        __BKPT(0);
      }
    }