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**** 2557070 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1532745/mspm0g3507-how-to-store-data-in-flash

器件型号:MSPM0G3507
主题:SysConfig 中讨论的其他器件

工具/软件:

尊敬的专家:

我需要使用 闪存中的一些存储空间 (~126KB 至 127KB (1KB)) 来存储数据(校准值,客户数据等)。 不过、我仍无法配置它。 请帮我解决这个问题。

感谢你的帮助。

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

    嗨、Kaushika、

    用户需要首先编辑链接器文件、并为数据保留闪存区域、以确保其中没有其他数据存储。 然后、在程序中、可以使用 MSP DriverLib 函数对保留的存储器区域进行保护、取消保护、读取和写入。 如果您还没有、我建议您查看以下资源:

    此致、

    Daniel

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

    谢谢、Daniel。

    下面是这些资源。

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

    您能帮助我编辑或替换 drivers_linker.cmd 吗? 重建时、一切都会发生变化。 如果 关闭“重建“、则会出现很多错误。 我可以替换原始的  driver_linker.cmd 进行闪存分区吗?

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

    是否确保在 SysConfig 的 Project Configuration 下禁用了 Linker File Generation 选项?

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

    是的。 我做到了。 现在我不知道我的 driver_linker.cmd 是否正确? 我与原始闪存分开了 1KB。 不过、我仍处于测试阶段。 我需要将一些数据写入 FLASH2 中所需的地址。 然后、我需要确保在更改代码时数据必须可用。 我的意思是、这些数据应该是永久性的、直到我将其擦除。

    -uinterruptVectors
    --stack_size=512
    
    MEMORY
    {
        FLASH           (RX)  : origin = 0x00000000, length = 0x0001FC00   /* 127KB for app */
        FLASH2          (RX)  : origin = 0x0001FC00, length = 0x00000400  /* 1KB for BSL */
        SRAM            (RWX) : origin = 0x20000000, length = 0x00001000
        BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x00000080
        BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
    
    }
    
    SECTIONS
    {
        .intvecs       : > 0x00000000
        .text          : palign(8) {} > FLASH
        .const         : palign(8) {} > FLASH
        .cinit         : palign(8) {} > FLASH
        .pinit         : palign(8) {} > FLASH
        .rodata        : palign(8) {} > FLASH
        .ARM.exidx     : palign(8) {} > FLASH
        .init_array    : palign(8) {} > FLASH
        .binit         : palign(8) {} > FLASH
        .TI.ramfunc    : load = FLASH, palign(8), run=SRAM, table(BINIT)
    
        .user_data 	   : {} > FLASH2
    
        .vtable :   > SRAM
        .args   :   > SRAM
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM (HIGH)
    
        .BCRConfig  : {} > BCR_CONFIG
        .BSLConfig  : {} > BSL_CONFIG
    }
    

    首先、取消选择 diver_linker.cmd 生成选项并编辑.cmd 文件。 之后、我重新选择该选项。 则 drivers_linker.cmd 保留下来。

    这是.c 代码。

    #include "ti_msp_dl_config.h"
    
    // Define 4 sector-aligned flash addresses (must match flash sector boundaries, e.g. 1KB-aligned)
    #define USER_FLASH_BASE_1  0x0001F000
    #define USER_FLASH_BASE_2  0x0001F400
    #define USER_FLASH_BASE_3  0x0001F800
    #define USER_FLASH_BASE_4  0x0001FC00
    
    // Data blocks to write (2 x 32-bit = 64-bit each block)
    uint32_t userData[4][2] = {
        {0xAAAA1111, 0xBBBB2222},   // Data for address 1
        {0xCCCC3333, 0xDDDD4444},   // Data for address 2
        {0xEEEE5555, 0xFFFF6666},   // Data for address 3
        {0x12345678, 0x9ABCDEF0}    // Data for address 4
    };
    
    // Corresponding flash addresses for each data block
    uint32_t flashAddresses[4] = {
        USER_FLASH_BASE_1,
        USER_FLASH_BASE_2,
        USER_FLASH_BASE_3,
        USER_FLASH_BASE_4
    };
    
    // Flash write function for each 64-bit data block
    void write_flash_block(uint32_t address, uint32_t *data)
    {
        // Unprotect sector
        DL_FlashCTL_unprotectSector(FLASHCTL, address, DL_FLASHCTL_REGION_SELECT_MAIN);
    
        // Erase sector before writing
        DL_FLASHCTL_COMMAND_STATUS status;
        status = DL_FlashCTL_eraseMemoryFromRAM(FLASHCTL, address, DL_FLASHCTL_COMMAND_SIZE_SECTOR);
        if (status != DL_FLASHCTL_COMMAND_STATUS_PASSED) {
            while (1); // Erase failed
        }
    
        // Program 64-bit (2 x 32-bit) word with ECC auto-generated
        status = DL_FlashCTL_programMemoryBlockingFromRAM64WithECCGenerated(
            FLASHCTL,
            address,
            data,
            2,
            DL_FLASHCTL_REGION_SELECT_MAIN
        );
        if (status != DL_FLASHCTL_COMMAND_STATUS_PASSED) {
            while (1); // Write failed
        }
    }
    
    int main(void)
    {
        SYSCFG_DL_init();
    
        // Write each data block to corresponding flash sector
        for (int i = 0; i < 4; i++) {
            write_flash_block(flashAddresses[i], userData[i]);
        }
    
        // Toggle LED to show success
        while (1) {
            DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            delay_cycles(16000000);
        }
    }
    

    然后通过调试检查地址、  

    有数据值存在、但当我刷写新代码时、这些值不再存在。 全部擦除。
    我错了吗? 您能帮我按正确的方式操作吗?  

    最后、我需要在闪存上永久保存一些配置。 不过、我还是在进行地面测试。

    非常感谢您的帮助。

    谢谢你。

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

    关闭“Linker File Generation“、并将修改后的链接器文件直接添加到工程中。 另外、请确保在 C 代码中写入的地址在为用户数据 (FLASH2) 设置的范围内。

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

    我尝试了几次将自定义链接器文件保存到工程中。 但我做不到。 您能给我几个步骤吗? 以及我应该使用哪些命令在闪存中写入数据。

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

    取消选中“Linker File Generation“、并将自定义链接器文件直接放入项目目录。 我相信您重写存储器时遇到的问题是您在 CCS 中配置的工程造成的。 右键点击您的工程文件夹、然后导航至 Properties -> Debug -> Category -> MSPM0 Flash Settings -> Erase Configuration。 您可以在此处调整要擦除的内存、默认设置很可能是擦除所有主内存。 选择“Erase main memory sectors by range“、然后在以下字段中指定您要擦除的范围。  

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

    好的。 谢谢、Daniel。 通过了这一步。  
    我在刷写代码时遇到另一个错误。

    【错误】Cortex-M0P:闪存编程器:映像大小错误。 块的长度为 260、但由于闪存编程器以 64 位进行写入、因此它应该可以被 8 整除

    #include "ti_msp_dl_config.h"
    
    /* Address in main memory to write to */
    #define MAIN_BASE_ADDRESS (0x0001FC00)
    
    /* Array to write 64-bits to flash. Data must be loaded 32-bits at a time,
     * but a single word program is executed. */
    uint32_t gDataArray64[] = {0xABCDEF00, 0x12345678};
    
    /*
     * 8-bit ECC code array that corresponds with the data in
     * gDataArray64MultipleWords1
     */
    uint8_t gECCArray[] = {0x67, 0xF9, 0xF6, 0x68, 0xEB};
    
    volatile DL_FLASHCTL_COMMAND_STATUS gCmdStatus;
    
    /* Codes to understand where error occured */
    #define NO_ERROR 0
    #define ERROR_ERASE 1
    #define ERROR_64BIT_W 2
    
    volatile uint8_t gErrorType = NO_ERROR;
    
    int main(void)
    {
        SYSCFG_DL_init();
    
        /* Erase sector in main memory */
        DL_FlashCTL_unprotectSector(
            FLASHCTL, MAIN_BASE_ADDRESS, DL_FLASHCTL_REGION_SELECT_MAIN);
        gCmdStatus = DL_FlashCTL_eraseMemoryFromRAM(
            FLASHCTL, MAIN_BASE_ADDRESS, DL_FLASHCTL_COMMAND_SIZE_SECTOR);
        if (gCmdStatus != DL_FLASHCTL_COMMAND_STATUS_PASSED) {
            /* If command did not pass, set error flag */
            gErrorType = ERROR_ERASE;
        }
    
    
        if (gErrorType == NO_ERROR) {
            /*
            * Program single flash word (64-bit data) write to flash in main memory
            * with ECC enabled. Data must be loaded 32-bits at a time, but a single
            * word program is executed. The flash controller hardware will handle
            * generating the 8-bit ECC code.
            */
            DL_FlashCTL_unprotectSector(
                FLASHCTL, MAIN_BASE_ADDRESS, DL_FLASHCTL_REGION_SELECT_MAIN);
            gCmdStatus = DL_FlashCTL_programMemoryFromRAM64WithECCGenerated(
                FLASHCTL, (MAIN_BASE_ADDRESS), &gDataArray64[0]);
            if (gCmdStatus != DL_FLASHCTL_COMMAND_STATUS_PASSED) {
                /* If command did not pass, set error flag */
                gErrorType = ERROR_64BIT_W;
            }
        }
    
        /*
         * Signal to check the contents of MAIN_BASE_ADDRESS:
         * DE AD BE EF
         * CA FE BA BE
         * DE AD BE EF
         * CA FE BA BE
         * DE AD BE EF
         * CA FE BA BE
         * DE AD BE EF
         * CA FE BA BE
         * DE AD BE EF
         * CA FE BA BE
         */
    
        /* Set Breakpoint if error status exists on completion */
        if (gErrorType != NO_ERROR) {
            __BKPT(0);
        }
        /* After completion, toggle LED */
        while (1) {
            DL_GPIO_togglePins(GPIO_LEDS_PORT,
                GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
            delay_cycles(16000000);
        }
    }
    
    -u _c_int00
    --stack_size=0x800
    
    MEMORY
    {
        FLASH        (RX)  : origin = 0x00000000, length = 0x0001FC00
        NV_FLASH     (RWX) : origin = 0x0001FC00, length = 0x00000400
        SRAM         (RWX) : origin = 0x20200000, length = 0x00008000
        BCR_CONFIG   (R)   : origin = 0x41C00000, length = 0x00000080
        BSL_CONFIG   (R)   : origin = 0x41C00100, length = 0x00000080
    }
    
    SECTIONS
    {
        .intvecs        :   > FLASH
        .text           :   > FLASH
        .const          :   > FLASH
        .cinit          :   > FLASH
        .pinit          :   > FLASH
        .rodata         :   > FLASH
        .ARM.exidx      :   > FLASH
        .init_array     :   > FLASH
        .TI.ramfunc     :   load = FLASH, run = SRAM, table(BINIT), palign(8)
        .binit          :   > FLASH
    
        .data           :   > SRAM
        .bss            :   > SRAM
        .sysmem         :   > SRAM
        .vtable         :   > SRAM
        .stack          :   > SRAM (HIGH)
    
        .BCRConfig      :   > BCR_CONFIG
        .BSLConfig      :   > BSL_CONFIG
    
    
    }

    代码中是否有任何错误? 请您能指导我吗?

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

    确保保留段的对齐方式、并将.intvecs 设置为从 0x00000000 开始。

    -uinterruptVectors
    --stack_size=512
    
    MEMORY
    {
        FLASH        (RX)  : origin = 0x00000000, length = 0x0001FC00
        NV_FLASH     (RX) : origin = 0x0001FC00, length = 0x00000400
        SRAM         (RWX) : origin = 0x20200000, length = 0x00008000
        BCR_CONFIG   (R)   : origin = 0x41C00000, length = 0x00000080
        BSL_CONFIG   (R)   : origin = 0x41C00100, length = 0x00000080
    }
    
    SECTIONS
    {
        .intvecs        :   > 0x00000000
        .text           :   palign(8) {} > FLASH
        .const          :   palign(8) {} > FLASH
        .cinit          :   palign(8) {} > FLASH
        .pinit          :   palign(8) {} > FLASH
        .rodata         :   palign(8) {} > FLASH
        .ARM.exidx      :   palign(8) {} > FLASH
        .init_array     :   palign(8) {} > FLASH
        .TI.ramfunc     :   load = FLASH, run = SRAM, table(BINIT), palign(8)
        .binit          :   palign(8) {} > FLASH
    
        .data           :   > SRAM
        .bss            :   > SRAM
        .sysmem         :   > SRAM
        .vtable         :   > SRAM
        .stack          :   > SRAM (HIGH)
    
        .BCRConfig      :   > BCR_CONFIG
        .BSLConfig      :   > BSL_CONFIG
    }

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

    谢谢你,丹尼尔!!