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.

AM2612: Problems related to flash erasure AM2612

Part Number: AM2612
Other Parts Discussed in Thread: UNIFLASH, , SYSCONFIG

I am using UniFlash 9.1.0 to erase the flash memory of AM2612. I select "Custom Flasher" in "Settings & Utilities" and use the file "flash_jtag_uniflash.out" for the erasure. After erasure, I also use UniFlash's memory function to read the flash address, specifically 0x60081000. I find that the content of the erased flash memory becomes either 00000000 or FFFFFFEE, instead of the expected FFFFFFFF. This issue prevents the flash memory from booting correctly after I write the program into it. How can I solve this problem?

  • After erasure, I also use UniFlash's memory function to read the flash address, specifically 0x60081000.

    I don't think that memory read of external flash works (TBC by TI) so the numbers you see might be garbage and not representative of the actual flash contents. See this: AM263P4-Q1: UniFlash Feature Request : Memory Read of OSPI Flash - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    This issue prevents the flash memory from booting correctly

    Consider that the cause might not be the flash contents since Memory read does not work.

  • Hi Zhou,

    After erasing via uniflash can you please try to read the flash using the memory browser feature in CCS. For this you can run an OSPI example that has DAC mode enabled in the sysconfig.

    So once flash open is done, on entering the flash address in memory browser, the flash contents will be visible. This step can be used to ensure correct erase of flash

    Once flash is done , the same method can be used to check the flash contents to ensure correct flashing of the code. 

    Can you try this on your setup ?

    Regards,

    Aswin

  • Hi Kier,

          Sorry for the delay due to some matters. I may have missed some information to supplement. I am using our own control board instead of a LaunchPad. This flasher works normally for erasing, programming, and booting on the other 7 boards except this one. We use OSPI (4S)-Quad Read Mode for booting, but only one board encounters an issue during erasing. I ran the qspi_flash_io_am261x test program, and the result shows [Cortex_R5_0] All tests have passed!!, which indicates that my hardware is functioning properly.

  • Hi Zhou, 

    After flashing the contents via uniflash, have you checked the flash dump? Please use the memory browser is CCS with dac enabled for checking the flash dump.

    Also after flashing, when you are trying to boot, what is the osbervation ?

    Regards,

    Aswin

  • Hi Aswin,

        After I erased the flash via UniFlash, I read the address 0x60081000 through UniFlash and got results all showing 0xFFFFFFEE. At this point, I couldn’t connect directly to CCS. After restarting, I connected to CCS and read the address 0x60081000 in the Memory Browser, with all results showing 0x00000000. I am using our own flasher. The code is as follows:

    int main(void)
    {
        int32_t status = SystemP_SUCCESS;
    
        System_init();
        Drivers_open();
        status = Board_driversOpen();
        DebugP_assert(status == SystemP_SUCCESS);
    
        Bootloader_UniflashConfig uniflashConfig;
        Bootloader_UniflashResponseHeader respHeader;
    
        gFlashAttrs = Flash_getAttrs(CONFIG_FLASH0);
        gFlashBuffSize = BOOTLOADER_UNIFLASH_MAX_FILE_SIZE;
        gFlashWriteOpcode = FLASH_OPCODE;
    
        if (status == SystemP_SUCCESS)
        {
            uniflashConfig.flashIndex = CONFIG_FLASH0;
            uniflashConfig.buf = gFileBuf;
            uniflashConfig.bufSize = 0; /* Actual fileSize will be parsed from the header */
            uniflashConfig.verifyBuf = gVerifyBuf;
            uniflashConfig.verifyBufSize = BOOTLOADER_UNIFLASH_VERIFY_BUF_MAX_SIZE;
    
            /* Process the flash commands and return a response */
            Bootloader_uniflashProcessFlashCommands(&uniflashConfig, &respHeader);
            gFlashStatus = respHeader.statusCode;
        }
        /* clear buffer to reset stale data if any */
        memset(gFileBuf, 0, BOOTLOADER_UNIFLASH_MAX_FILE_SIZE);
        OSPI_enableDacMode(gOspiHandle[CONFIG_OSPI0]);
        Drivers_close();
        System_deinit();
    
        return 0;
    }
     
    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM261x@10.00.01"
     * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM261x@10.00.01"
     * @versions {"tool":"1.22.0+3893"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const flash           = scripting.addModule("/board/flash/flash", {}, false);
    const flash1          = flash.addInstance();
    const edma            = scripting.addModule("/drivers/edma/edma", {}, false);
    const edma1           = edma.addInstance();
    const gpio            = scripting.addModule("/drivers/gpio/gpio", {}, false);
    const gpio1           = gpio.addInstance();
    const clock           = scripting.addModule("/kernel/dpl/clock");
    const debug_log       = scripting.addModule("/kernel/dpl/debug_log");
    const dpl_cfg         = scripting.addModule("/kernel/dpl/dpl_cfg");
    const mpu_armv7       = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false);
    const mpu_armv71      = mpu_armv7.addInstance();
    const mpu_armv72      = mpu_armv7.addInstance();
    const mpu_armv73      = mpu_armv7.addInstance();
    const mpu_armv74      = mpu_armv7.addInstance();
    const mpu_armv75      = mpu_armv7.addInstance();
    const default_linker  = scripting.addModule("/memory_configurator/default_linker", {}, false);
    const default_linker1 = default_linker.addInstance();
    const general         = scripting.addModule("/memory_configurator/general", {}, false);
    const general1        = general.addInstance();
    const region          = scripting.addModule("/memory_configurator/region", {}, false);
    const region1         = region.addInstance();
    const section         = scripting.addModule("/memory_configurator/section", {}, false);
    const section1        = section.addInstance();
    const section2        = section.addInstance();
    const section3        = section.addInstance();
    const section4        = section.addInstance();
    const section5        = section.addInstance();
    const section6        = section.addInstance();
    const section7        = section.addInstance();
    const section8        = section.addInstance();
    const section9        = section.addInstance();
    const section10       = section.addInstance();
    const section11       = section.addInstance();
    const section12       = section.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    flash1.device                             = "CUSTOM_FLASH";
    flash1.fname                              = "S25FL128SA";
    flash1.protocol                           = "1s_1s_4s";
    flash1.flashSize                          = 16777216;
    flash1.flashManfId                        = "0x01";
    flash1.flashDeviceId                      = "0x2018";
    flash1.flashBlockSize                     = 65536;
    flash1.cmdBlockErase4B                    = "0xD8";
    flash1.cmdSectorErase4B                   = "0x20";
    flash1.cmdRd                              = "0x6B";
    flash1.cmdWr                              = "0x32";
    flash1.dummyClksRd                        = 8;
    flash1.flashQeType                        = "1";
    flash1.flashDeviceBusyTimeout             = 24000000;
    flash1.flashPageProgTimeout               = 4000;
    flash1.fourByteEnableSeq                  = "0x00";
    flash1.addressByteSupport                 = "0";
    flash1.enable4BAddr                       = false;
    flash1.quirks                             = "NULL";
    flash1.$name                              = "CONFIG_FLASH0";
    flash1.cmdExtType                         = "NONE";
    flash1.peripheralDriver.$name             = "CONFIG_OSPI0";
    flash1.peripheralDriver.inputClkFreq      = 83333333;
    flash1.peripheralDriver.OSPI.$assign      = "OSPI0";
    flash1.peripheralDriver.OSPI.CLK.$assign  = "GPIO10";
    flash1.peripheralDriver.OSPI.CSn0.$assign = "GPIO62";
    flash1.peripheralDriver.OSPI.DQS.$assign  = "GPIO9";
    flash1.peripheralDriver.OSPI.D7.$assign   = "GPIO68";
    flash1.peripheralDriver.OSPI.D6.$assign   = "GPIO8";
    flash1.peripheralDriver.OSPI.D5.$assign   = "GPIO67";
    flash1.peripheralDriver.OSPI.D4.$assign   = "GPIO76";
    flash1.peripheralDriver.OSPI.D3.$assign   = "GPIO69";
    flash1.peripheralDriver.OSPI.D2.$assign   = "GPIO7";
    flash1.peripheralDriver.OSPI.D1.$assign   = "GPIO70";
    flash1.peripheralDriver.OSPI.D0.$assign   = "GPIO2";
    flash1.peripheralDriver.child.$name       = "drivers_ospi_v0_ospi_v0_am261x_template0";
    
    edma1.$name                 = "CONFIG_EDMA0";
    edma1.intrEnable            = "FALSE";
    edma1.edmaRmDmaCh[0].$name  = "CONFIG_EDMA_RM0";
    edma1.edmaRmQdmaCh[0].$name = "CONFIG_EDMA_RM1";
    edma1.edmaRmTcc[0].$name    = "CONFIG_EDMA_RM2";
    edma1.edmaRmParam[0].$name  = "CONFIG_EDMA_RM3";
    
    gpio1.pinDir         = "OUTPUT";
    gpio1.defaultValue   = "1";
    gpio1.$name          = "GPIO_OSPI_RST";
    gpio1.GPIO_n.$assign = "GPIO61";
    
    debug_log.enableUartLog            = true;
    debug_log.uartLog.$name            = "CONFIG_UART_LOG";
    debug_log.uartLog.UART.$assign     = "UART0";
    debug_log.uartLog.UART.RXD.$assign = "GPIO27";
    debug_log.uartLog.UART.TXD.$assign = "GPIO28";
    debug_log.uartLog.child.$name      = "drivers_uart_v2_uart_v2_template0";
    
    mpu_armv71.$name             = "CONFIG_MPU_REGION0";
    mpu_armv71.size              = 31;
    mpu_armv71.attributes        = "Device";
    mpu_armv71.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv71.allowExecute      = false;
    
    mpu_armv72.$name             = "CONFIG_MPU_REGION1";
    mpu_armv72.size              = 15;
    mpu_armv72.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv73.$name             = "CONFIG_MPU_REGION2";
    mpu_armv73.baseAddr          = 0x41010000;
    mpu_armv73.size              = 15;
    mpu_armv73.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv74.$name             = "CONFIG_MPU_REGION3";
    mpu_armv74.baseAddr          = 0x70000000;
    mpu_armv74.size              = 21;
    mpu_armv74.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv75.$name    = "CONFIG_MPU_REGION5";
    mpu_armv75.baseAddr = 0x80000000;
    mpu_armv75.size     = 31;
    
    default_linker1.$name = "memory_configurator_default_linker0";
    
    general1.$name        = "CONFIG_GENERAL0";
    general1.linker.$name = "TIARMCLANG0";
    
    region1.$name                                = "MEMORY_REGION_CONFIGURATION0";
    region1.memory_region.create(11);
    region1.memory_region[0].type                = "TCMA";
    region1.memory_region[0].$name               = "R5F_VECS";
    region1.memory_region[0].size                = 0x40;
    region1.memory_region[0].auto                = false;
    region1.memory_region[1].type                = "TCMA";
    region1.memory_region[1].$name               = "R5F_TCMA";
    region1.memory_region[1].size                = 0x7FC0;
    region1.memory_region[2].type                = "TCMB";
    region1.memory_region[2].size                = 0x8000;
    region1.memory_region[2].$name               = "R5F_TCMB";
    region1.memory_region[3].$name               = "SBL";
    region1.memory_region[3].auto                = false;
    region1.memory_region[3].size                = 0x40000;
    region1.memory_region[4].$name               = "OCRAM";
    region1.memory_region[4].auto                = false;
    region1.memory_region[4].manualStartAddress  = 0x70040000;
    region1.memory_region[4].size                = 0x40000;
    region1.memory_region[5].type                = "FLASH";
    region1.memory_region[5].auto                = false;
    region1.memory_region[5].manualStartAddress  = 0x60100000;
    region1.memory_region[5].size                = 0x80000;
    region1.memory_region[5].$name               = "FLASH";
    region1.memory_region[6].$name               = "USER_SHM_MEM";
    region1.memory_region[6].auto                = false;
    region1.memory_region[6].manualStartAddress  = 0x70150000;
    region1.memory_region[6].size                = 0x4000;
    region1.memory_region[6].isShared            = true;
    region1.memory_region[6].shared_cores        = ["r5fss0-1"];
    region1.memory_region[7].$name               = "LOG_SHM_MEM";
    region1.memory_region[7].auto                = false;
    region1.memory_region[7].manualStartAddress  = 0x70154000;
    region1.memory_region[7].size                = 0x4000;
    region1.memory_region[7].isShared            = true;
    region1.memory_region[7].shared_cores        = ["r5fss0-1"];
    region1.memory_region[8].type                = "CUSTOM";
    region1.memory_region[8].$name               = "RTOS_NORTOS_IPC_SHM_MEM";
    region1.memory_region[8].auto                = false;
    region1.memory_region[8].manualStartAddress  = 0x72000000;
    region1.memory_region[8].size                = 0x3E80;
    region1.memory_region[8].isShared            = true;
    region1.memory_region[8].shared_cores        = ["r5fss0-1"];
    region1.memory_region[9].type                = "CUSTOM";
    region1.memory_region[9].$name               = "MAILBOX_HSM";
    region1.memory_region[9].auto                = false;
    region1.memory_region[9].manualStartAddress  = 0x44000000;
    region1.memory_region[9].size                = 0x3CE;
    region1.memory_region[9].isShared            = true;
    region1.memory_region[9].shared_cores        = ["r5fss0-1"];
    region1.memory_region[10].type               = "CUSTOM";
    region1.memory_region[10].$name              = "MAILBOX_R5F";
    region1.memory_region[10].auto               = false;
    region1.memory_region[10].manualStartAddress = 0x44000400;
    region1.memory_region[10].size               = 0x3CE;
    region1.memory_region[10].isShared           = true;
    region1.memory_region[10].shared_cores       = ["r5fss0-1"];
    
    section1.load_memory                  = "R5F_VECS";
    section1.group                        = false;
    section1.$name                        = "Vector Table";
    section1.output_section.create(1);
    section1.output_section[0].$name      = ".vectors";
    section1.output_section[0].palignment = true;
    
    section2.load_memory                  = "OCRAM";
    section2.$name                        = "Text Segments";
    section2.output_section.create(5);
    section2.output_section[0].$name      = ".text.hwi";
    section2.output_section[0].palignment = true;
    section2.output_section[1].$name      = ".text.cache";
    section2.output_section[1].palignment = true;
    section2.output_section[2].$name      = ".text.mpu";
    section2.output_section[2].palignment = true;
    section2.output_section[3].$name      = ".text.boot";
    section2.output_section[3].palignment = true;
    section2.output_section[4].$name      = ".text:abort";
    section2.output_section[4].palignment = true;
    
    section3.load_memory                  = "OCRAM";
    section3.$name                        = "Code and Read-Only Data";
    section3.output_section.create(2);
    section3.output_section[0].$name      = ".text";
    section3.output_section[0].palignment = true;
    section3.output_section[1].$name      = ".rodata";
    section3.output_section[1].palignment = true;
    
    section4.load_memory                  = "OCRAM";
    section4.$name                        = "Data Segment";
    section4.output_section.create(1);
    section4.output_section[0].$name      = ".data";
    section4.output_section[0].palignment = true;
    
    section5.load_memory                             = "OCRAM";
    section5.$name                                   = "Memory Segments";
    section5.output_section.create(3);
    section5.output_section[0].$name                 = ".bss";
    section5.output_section[0].output_sections_start = "__BSS_START";
    section5.output_section[0].output_sections_end   = "__BSS_END";
    section5.output_section[0].palignment            = true;
    section5.output_section[1].$name                 = ".sysmem";
    section5.output_section[1].palignment            = true;
    section5.output_section[2].$name                 = ".stack";
    section5.output_section[2].palignment            = true;
    
    section6.load_memory                              = "OCRAM";
    section6.$name                                    = "Stack Segments";
    section6.output_section.create(5);
    section6.output_section[0].$name                  = ".irqstack";
    section6.output_section[0].output_sections_start  = "__IRQ_STACK_START";
    section6.output_section[0].output_sections_end    = "__IRQ_STACK_END";
    section6.output_section[0].input_section.create(1);
    section6.output_section[0].input_section[0].$name = ". = . + __IRQ_STACK_SIZE;";
    section6.output_section[1].$name                  = ".fiqstack";
    section6.output_section[1].output_sections_start  = "__FIQ_STACK_START";
    section6.output_section[1].output_sections_end    = "__FIQ_STACK_END";
    section6.output_section[1].input_section.create(1);
    section6.output_section[1].input_section[0].$name = ". = . + __FIQ_STACK_SIZE;";
    section6.output_section[2].$name                  = ".svcstack";
    section6.output_section[2].output_sections_start  = "__SVC_STACK_START";
    section6.output_section[2].output_sections_end    = "__SVC_STACK_END";
    section6.output_section[2].input_section.create(1);
    section6.output_section[2].input_section[0].$name = ". = . + __SVC_STACK_SIZE;";
    section6.output_section[3].$name                  = ".abortstack";
    section6.output_section[3].output_sections_start  = "__ABORT_STACK_START";
    section6.output_section[3].output_sections_end    = "__ABORT_STACK_END";
    section6.output_section[3].input_section.create(1);
    section6.output_section[3].input_section[0].$name = ". = . + __ABORT_STACK_SIZE;";
    section6.output_section[4].$name                  = ".undefinedstack";
    section6.output_section[4].output_sections_start  = "__UNDEFINED_STACK_START";
    section6.output_section[4].output_sections_end    = "__UNDEFINED_STACK_END";
    section6.output_section[4].input_section.create(1);
    section6.output_section[4].input_section[0].$name = ". = . + __UNDEFINED_STACK_SIZE;";
    
    section7.load_memory                  = "OCRAM";
    section7.$name                        = "Initialization and Exception Handling";
    section7.output_section.create(3);
    section7.output_section[0].$name      = ".ARM.exidx";
    section7.output_section[0].palignment = true;
    section7.output_section[1].$name      = ".init_array";
    section7.output_section[1].palignment = true;
    section7.output_section[2].$name      = ".fini_array";
    section7.output_section[2].palignment = true;
    
    section8.load_memory                 = "USER_SHM_MEM";
    section8.type                        = "NOLOAD";
    section8.$name                       = "User Shared Memory";
    section8.group                       = false;
    section8.output_section.create(1);
    section8.output_section[0].$name     = ".bss.user_shared_mem";
    section8.output_section[0].alignment = 0;
    
    section9.load_memory                 = "LOG_SHM_MEM";
    section9.$name                       = "Log Shared Memory";
    section9.group                       = false;
    section9.type                        = "NOLOAD";
    section9.output_section.create(1);
    section9.output_section[0].$name     = ".bss.log_shared_mem";
    section9.output_section[0].alignment = 0;
    
    section10.load_memory                 = "RTOS_NORTOS_IPC_SHM_MEM";
    section10.type                        = "NOLOAD";
    section10.$name                       = "IPC Shared Memory";
    section10.group                       = false;
    section10.output_section.create(1);
    section10.output_section[0].$name     = ".bss.ipc_vring_mem";
    section10.output_section[0].alignment = 0;
    
    section11.load_memory                 = "MAILBOX_HSM";
    section11.type                        = "NOLOAD";
    section11.$name                       = "SIPC HSM Queue Memory";
    section11.group                       = false;
    section11.output_section.create(1);
    section11.output_section[0].$name     = ".bss.sipc_hsm_queue_mem";
    section11.output_section[0].alignment = 0;
    
    section12.load_memory                 = "MAILBOX_R5F";
    section12.$name                       = "SIPC R5F Queue Memory";
    section12.group                       = false;
    section12.type                        = "NOLOAD";
    section12.output_section.create(1);
    section12.output_section[0].$name     = ".bss.sipc_secure_host_queue_mem";
    section12.output_section[0].alignment = 0;
    

    Alternatively, could you provide me with a demo program that can erase the flash correctly? 

    I cannot upload my syscfg file and can only copy its content in text format as follows:

  • Hi Zhou,

    After restarting in dev boot mode you can run an ospi example with DAC enabled in sysconfig (ospi_flash_io). After board drivers open, then only you should check the flash via the memory browser. 

    Let me know if you have any confusion, I will provide with detailed steps to do this.

    Regarding flash erase, what is actually required ? For flash erase you can check the flash erase API in ospi_flash_io example for instance. The example does demonstrate the erasure of flash

    Regards,

    Aswin

  • Hi Aswin,

         You mean that after I erase the flash via UniFlash, I should restart in dev boot mode and run the OSPI flash IO example to check if the flash is erased?
    I will try this and see the result.
    My actual goal is to program the code into the flash and get it to boot. However, based on my experience with other AM261 boards (from previous projects, which were also our custom boards), a small number of boards had a bug: if the flash was not fully erased to 0xFFFFFFFF but to 0xFFFFFFEE after using UniFlash for erasure, no amount of debugging would fix the flash issue on those boards.
    But currently, all AM261 boards in this project are encountering this problem—even though the flash-related part of the schematic is identical to that of the previous project. That’s why I want to resolve this issue completely.
    Best regards.
  • Hi Zhou,

    The uniflash memory reader might not give accurate view in all cases. In your case since you mentioned that you see 0xFFFFFFEE, to  double confirm this, I mentioned the other way of using the memory browser. 

    To view flash content via memory browser, you need to have DAC enabled. In the earlier method, I suppose you checked the flash after simply connecting to the target. This would not suffice. You would need to run an example to turn DAC ON and then see the flash address space via memory browser. Same way after flashing the contents, the flash area can be checked to see if it has been flashed properly.

    What does previous project mean here, which device was this ? 

    Also to remove any doubts with the flasher, can you please try with the custom flasher in the SDK. Please follow the below steps to adapt the flasher to your flash part,

    1. Open the jtag_uniflash project in CCS, It is in this path: tools/flasher/jtag_uniflash.

    2: Adapt the flash and ospi configuration according to your board. Since the ospi_flash_io example is working in your case, you would only need to align the sysconfig configuation of this project (FLASH and OSPI) to that of the ospi_flash_io project

    3. After this build the project. 

    4. Now, in the unfilash gui application, use this custom flasher, for this tick the custom flasher option and fill in the path and flasher name as shown below.

    Can you please try using custom flasher for flashing and CCS memory browser (with DAC enabled) for validating the results of flash operations?

    Regards,

    Aswin

  •      You mean that after I erase the flash via UniFlash, I should restart in dev boot mode and run the OSPI flash IO example to check if the flash is erased?

    Yes you are correct. You can run the example and pause after  flash has been opened. Since DAC is kept as enabled in sysconfig, you can enter the flash address in memory browser and see the state of flash.

  • Hi Aswin, 

         Thank you very much. The problem has been resolved. I copied the configuration of my syscfg file into the flasher_jtag_uniflash_am261x_lp project in the SDK, set a breakpoint before Drivers_close(), and then checked via CCS address reading. The address 0x60081000 has all become 0xFFFFFFFF. When I read it using UniFlash, it also showed 0xFFFFFFFF. Sure enough, after doing this, I can successfully program the flash.
    I guess the example program also has a flash erasure function? It’s possible that my previous flasher was unstable.
    Additionally, I would like to ask: besides UniFlash, is there any example that can replace UniFlash for programming the flash? Because there are examples that can replace UniFlash for erasing the flash.
    Best regards
  • Hi Zhou,

    The flasher is the code that works behind the scene for erasing as well flashing (writing) the external flash in the UniFlash GUI tool.

    By using the flasher_jtag_uniflash_am261x_lp project's output file as custom flasher, you can also flash your application using the UniFlash GUI tool. 

    If you want an alternative for Uniflash for flashing/erasing the external flash,  please refer to this project

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/10_02_00_15/exports/docs/api_guide_am261x/EXAMPLES_DRIVERS_SBL_JTAG_UNIFLASH.html

    This is a ccs project that can be used to flash application images via JTAG. 

    Also you can check uart uniflash tool

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/10_02_00_15/exports/docs/api_guide_am261x/TOOLS_FLASH.html#TOOLS_FLASH_UART_UNIFLASH

    Regards,

    Aswin

  • Hi Aswin,

        I tried to use the example program from examples/drivers/boot/sbl_jtag_uniflash that you mentioned earlier to program the flash. After entering my file address, when I input the flash offset as 0x81000, why does the console display the function address as 0x70040020? If I enter 1 and press Enter, the program immediately prompts a verification error. The complete console output is as follows:

    [Cortex_R5_0]  
     
     ==================
     JTAG Uniflash Menu
     ==================
     
     1: Erase Complete Flash
     2: Write File to Flash and Verify
     3: Verify file in Flash
     
     x: Exit
     
     Enter Choice: 3
    
     Enter file name along with path to write or verify : C:/A01Projects/A03github/LV_am261x/LV/LV_Release/LV_AM2612.appimage
     Enter flash offset (in hex format) : 0x81000
     Enter below command in CCS scripting console to load the file data to memory.
     AFTER the file load is done, enter '1' to continue ...
    
     loadRaw(0x70040020, 0, "C:/A01Projects/A03github/LV_am261x/LV/LV_Release/LV_AM2612.appimage", 32, false);
    1
     [FLASH WRITER] Verify Failed !!!

    Is the flash programming error caused by the incorrect first address? If so, how should I modify it? I noticed that 0x70040020 comes from 

    uint8_t gFileBuf[FILE_MAX_SIZE] __attribute__((aligned(128), section(".bss.filebuf")));.

    If the first address is correct, why can't the program be programmed into the flash? How to solve this problem? (I also cannot program the program using Uniflash. Even if Uniflash shows successful programming, the hex content read from 0x60081000 via CCS is obviously abnormal.) Thank you.

    Best regards

  • Hi zhou, 

    Apologies for the delay as I was OOO.

    1. I assume that the flash configurations are correct as discussed in the previous replies. 

    When using SBL JTAG uniflash, which boot mode is the board in ? Is it dev boot mode or ospi boot mode ?

    Depending on the boot mode, the procedure for flashing is different. If it is dev boot mode, then the procedure is straight forward.

    2. When you enter the flash offset and hit enter, the application asks to paste a load Raw command. Was the loadRaw command executed from the scripting console?

    Inside the project, when the command 3 is given the operation type is chosen as flash verify. Based on the optype a command is issued which needs to be executed on the scripting console.

    The address that is printed in the loadRaw command is actually the address of a buffer in RAM which holds the data. This is not the address to which flashing would be done. 

    3. What is the issue that is faced while flashing from uniFlash ? Is the tools showing successful flashing ? Is the correct flasher being used ? The one that was used for erasure. Also did you try to flash the image multiple times using uniflash. There is a chance that the tool may not succeed in flashing the first time after flash erasure. 

    Regards,

    Aswin

  • Hi Aswin,

         My board is in Dev mode. Sorry, I might not have checked carefully. I need to copy the load Raw command provided by the program. I tried doing this: first copied the load Raw command prompted by the program, then entered 1, but got the same result.

    [Cortex_R5_0]  
     
     ==================
     JTAG Uniflash Menu
     ==================
     
     1: Erase Complete Flash
     2: Write File to Flash and Verify
     3: Verify file in Flash
     
     x: Exit
     
     Enter Choice: 2
    Enter file name along with path to write or verify : C:/A01Projects/A03github/LV_am261x/LV/LV_Release/LV_AM2612.appimage
    Enter flash offset (in hex format) : 0x81000
    Enter below command in CCS scripting console to load the file data to memory.
    AFTER the file load is done, enter '1' to continue ...
     
    loadRaw(0x70040020, 0, "C:/A01Projects/A03github/LV_am261x/LV/LV_Release/LV_AM2612.appimage", 32, false);
    loadRaw(0x70040020, 0, "C:/A01Projects/A03github/LV_am261x/LV/LV_Release/LV_AM2612.appimage", 32, false);
    1
    [FLASH WRITER] Write Failed !!!

    When flashing the flash via UniFlash, the progress bar doesn't even move forward before an error occurs. I've tried several times, and the issue remains the same. The file I used to erase the flash is the "flasher_jtag_uniflash_am261x_lp" project in the SDK. The error message is as follows:

    [11/13/2025, 5:28:37 PM] [ERROR] Cortex_R5_0: Error Code 40000001
    [11/13/2025, 5:28:37 PM] [ERROR] Cortex_R5_0: Error Loading the data...
    [11/13/2025, 5:28:37 PM] [ERROR] Cortex_R5_0: Run failed...
    [11/13/2025, 5:28:37 PM] [ERROR] Cortex_R5_0: File Loader: Memory write failed: Algorithm indicated it failed to flash the data
    [11/13/2025, 5:28:38 PM] [INFO] Cortex_R5_0: Writing 1 chunk at offset 0x0
    [11/13/2025, 5:28:38 PM] [ERROR] Cortex_R5_0: Error Code 40000001
    [11/13/2025, 5:28:38 PM] [ERROR] Cortex_R5_0: Error Loading the data...
    [11/13/2025, 5:28:38 PM] [ERROR] Cortex_R5_0: Run failed...

    Best regards

  • Hi zhou, 

    I would like to confirm once again if the flash configurations are aligned. Are you able to run the ospi_flash_io example on the custom board ?

    Once that is done, if the flash configuration of the flashers are also aligned then there should not be an issue.

    Additionally, Can we get on a call and check the issue ?

    Regards,

    Aswin

  • Hi Aswin, 

         Sorry, I actually didn’t see your message from 6 days ago—probably because there was no notification from TI or I missed it. Coincidentally, I’ve also been busy with other things this week, so I may need to tackle this issue next week. I tried running the ospi_flash_io example before and it worked, but I’ll give it another try. I also hope to schedule a call to resolve this problem, though it will have to wait until next week. Thank you.

    Best regards.

  • Hi Zhou,

    No problem. We can have the call next week and see the issue. Meanwhile can you please tell which is the flash part is being used ?

    Also, is it possible for you to share me the sysonfig that is being used. I just wanted to see the flash configurations

    Regards,

    Aswin

  • Hi Aswin

        It's S25FL128SA. Besides, I failed to upload the file on this website, so I'm sharing the modified sysconfig file for flasher_jtag_uniflash_am261x-lp_r5fss0-0 in code format. My sysconfig version is 1.23.0.

    Best regards

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM261x@10.02.00"
     * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM261x@10.02.00"
     * @versions {"tool":"1.23.0+4000"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const flash      = scripting.addModule("/board/flash/flash", {}, false);
    const flash1     = flash.addInstance();
    const ioexp      = scripting.addModule("/board/ioexp/ioexp", {}, false);
    const ioexp1     = ioexp.addInstance();
    const clock      = scripting.addModule("/kernel/dpl/clock");
    const debug_log  = scripting.addModule("/kernel/dpl/debug_log");
    const dpl_cfg    = scripting.addModule("/kernel/dpl/dpl_cfg");
    const mpu_armv7  = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false);
    const mpu_armv71 = mpu_armv7.addInstance();
    const mpu_armv72 = mpu_armv7.addInstance();
    const mpu_armv73 = mpu_armv7.addInstance();
    const mpu_armv74 = mpu_armv7.addInstance();
    const mpu_armv75 = mpu_armv7.addInstance();
    const general    = scripting.addModule("/memory_configurator/general", {}, false);
    const general1   = general.addInstance();
    const region     = scripting.addModule("/memory_configurator/region", {}, false);
    const region1    = region.addInstance();
    const section    = scripting.addModule("/memory_configurator/section", {}, false);
    const section1   = section.addInstance();
    const section2   = section.addInstance();
    const section3   = section.addInstance();
    const section4   = section.addInstance();
    const section5   = section.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    flash1.$name                                    = "CONFIG_FLASH0";
    flash1.device                                   = "CUSTOM_FLASH";
    flash1.fname                                    = "S25FL128SA";
    flash1.skipHwInit                               = true;
    flash1.protocol                                 = "1s_1s_4s";
    flash1.flashSize                                = 16777216;
    flash1.flashManfId                              = "0x01";
    flash1.flashDeviceId                            = "0x2018";
    flash1.cmdBlockErase4B                          = "0xD8";
    flash1.cmdSectorErase4B                         = "0x20";
    flash1.flashQeType                              = "1";
    flash1.flashDeviceBusyTimeout                   = 24000000;
    flash1.flashPageProgTimeout                     = 4000;
    flash1.enable4BAddr                             = false;
    flash1.cmdExtType                               = "NONE";
    flash1.quirks                                   = "NULL";
    flash1.peripheralDriver.$name                   = "CONFIG_OSPI0";
    flash1.peripheralDriver.baudRateDiv             = 8;
    flash1.peripheralDriver.inputClkFreq            = 83333333;
    flash1.peripheralDriver.dacEnable               = true;
    flash1.peripheralDriver.OSPI.$assign            = "OSPI0";
    flash1.peripheralDriver.OSPI.CLK.$assign        = "GPIO10";
    flash1.peripheralDriver.OSPI.CSn0.$assign       = "GPIO62";
    flash1.peripheralDriver.OSPI.DQS.$assign        = "GPIO9";
    flash1.peripheralDriver.OSPI.D7.$assign         = "GPIO68";
    flash1.peripheralDriver.OSPI.D6.$assign         = "GPIO8";
    flash1.peripheralDriver.OSPI.D5.$assign         = "GPIO67";
    flash1.peripheralDriver.OSPI.D4.$assign         = "GPIO76";
    flash1.peripheralDriver.OSPI.D3.$assign         = "GPIO69";
    flash1.peripheralDriver.OSPI.D2.$assign         = "GPIO7";
    flash1.peripheralDriver.OSPI.D1.$assign         = "GPIO70";
    flash1.peripheralDriver.OSPI.D0.$assign         = "GPIO2";
    flash1.peripheralDriver.OSPI.RESET_OUT0.$assign = "GPIO61";
    flash1.peripheralDriver.child.$name             = "drivers_ospi_v0_ospi_v0_am261x_template0";
    
    ioexp1.$name = "CONFIG_IOEXP0";
    
    const i2c               = scripting.addModule("/drivers/i2c/i2c", {}, false);
    const i2c1              = i2c.addInstance({}, false);
    i2c1.$name              = "CONFIG_I2C0";
    ioexp1.peripheralDriver = i2c1;
    i2c1.I2C.$assign        = "I2C0";
    i2c1.I2C_child.$name    = "drivers_i2c_v1_i2c_v1_template0";
    
    debug_log.enableUartLog            = true;
    debug_log.uartLog.$name            = "CONFIG_UART_LOG";
    debug_log.uartLog.UART.$assign     = "UART0";
    debug_log.uartLog.UART.RXD.$assign = "GPIO27";
    debug_log.uartLog.UART.TXD.$assign = "GPIO28";
    debug_log.uartLog.child.$name      = "drivers_uart_v2_uart_v2_template0";
    
    mpu_armv71.$name             = "CONFIG_MPU_REGION0";
    mpu_armv71.size              = 31;
    mpu_armv71.attributes        = "Device";
    mpu_armv71.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv71.allowExecute      = false;
    
    mpu_armv72.$name             = "CONFIG_MPU_REGION1";
    mpu_armv72.size              = 15;
    mpu_armv72.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv73.$name             = "CONFIG_MPU_REGION2";
    mpu_armv73.baseAddr          = 0x41010000;
    mpu_armv73.size              = 15;
    mpu_armv73.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv74.$name             = "CONFIG_MPU_REGION3";
    mpu_armv74.baseAddr          = 0x70000000;
    mpu_armv74.size              = 21;
    mpu_armv74.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv75.$name    = "CONFIG_MPU_REGION5";
    mpu_armv75.baseAddr = 0x80000000;
    mpu_armv75.size     = 31;
    
    general1.$name          = "CONFIG_GENERAL0";
    general1.irq_stack_size = 4096;
    general1.linker.$name   = "TIARMCLANG0";
    
    region1.$name                               = "MEMORY_REGION_CONFIGURATION";
    region1.memory_region.create(6);
    region1.memory_region[0].type               = "TCMA";
    region1.memory_region[0].$name              = "R5F_VECS";
    region1.memory_region[0].auto               = false;
    region1.memory_region[0].size               = 0x100;
    region1.memory_region[1].type               = "TCMA";
    region1.memory_region[1].$name              = "R5F_TCMA";
    region1.memory_region[1].auto               = false;
    region1.memory_region[1].manualStartAddress = 0x100;
    region1.memory_region[1].size               = 0x7F00;
    region1.memory_region[2].type               = "TCMB";
    region1.memory_region[2].size               = 0x8000;
    region1.memory_region[2].$name              = "R5F_TCMB0";
    region1.memory_region[2].manualStartAddress = 0x41010000;
    region1.memory_region[3].$name              = "MSRAM_VECS";
    region1.memory_region[3].auto               = false;
    region1.memory_region[3].manualStartAddress = 0x70002000;
    region1.memory_region[3].size               = 0x100;
    region1.memory_region[4].$name              = "MSRAM_0";
    region1.memory_region[4].auto               = false;
    region1.memory_region[4].manualStartAddress = 0x70002100;
    region1.memory_region[4].size               = 0x3CF00;
    region1.memory_region[5].$name              = "MSRAM_1";
    region1.memory_region[5].auto               = false;
    region1.memory_region[5].size               = 0x10100;
    region1.memory_region[5].manualStartAddress = 0x7003FF00;
    
    section1.load_memory                              = "MSRAM_VECS";
    section1.group                                    = false;
    section1.$name                                    = "Sbl Initialization Code";
    section1.output_section.create(1);
    section1.output_section[0].$name                  = ".sbl_init_code";
    section1.output_section[0].input_section.create(1);
    section1.output_section[0].input_section[0].$name = "*(.vectors). = align(8);";
    
    section2.load_memory                  = "MSRAM_0";
    section2.$name                        = "Text Segments";
    section2.output_section.create(7);
    section2.output_section[0].$name      = ".text";
    section2.output_section[0].palignment = true;
    section2.output_section[1].$name      = ".text.hwi";
    section2.output_section[1].palignment = true;
    section2.output_section[2].$name      = ".text.cache";
    section2.output_section[2].palignment = true;
    section2.output_section[3].$name      = ".text.mpu";
    section2.output_section[3].palignment = true;
    section2.output_section[4].$name      = ".text.boot";
    section2.output_section[4].palignment = true;
    section2.output_section[5].$name      = ".data";
    section2.output_section[5].palignment = true;
    section2.output_section[6].$name      = ".rodata";
    section2.output_section[6].palignment = true;
    
    section3.load_memory                             = "MSRAM_0";
    section3.group                                   = false;
    section3.$name                                   = "Memory Segments";
    section3.output_section.create(3);
    section3.output_section[0].$name                 = ".bss";
    section3.output_section[0].output_sections_start = "__BSS_START";
    section3.output_section[0].output_sections_end   = "__BSS_END";
    section3.output_section[0].palignment            = true;
    section3.output_section[1].$name                 = ".sysmem";
    section3.output_section[1].palignment            = true;
    section3.output_section[2].$name                 = ".stack";
    section3.output_section[2].palignment            = true;
    
    section4.load_memory                              = "MSRAM_0";
    section4.$name                                    = "Stack Segments";
    section4.output_section.create(5);
    section4.output_section[0].$name                  = ".irqstack";
    section4.output_section[0].output_sections_start  = "__IRQ_STACK_START";
    section4.output_section[0].output_sections_end    = "__IRQ_STACK_END";
    section4.output_section[0].input_section.create(1);
    section4.output_section[0].input_section[0].$name = ". = . + __IRQ_STACK_SIZE;";
    section4.output_section[1].$name                  = ".fiqstack";
    section4.output_section[1].output_sections_start  = "__FIQ_STACK_START";
    section4.output_section[1].output_sections_end    = "__FIQ_STACK_END";
    section4.output_section[1].input_section.create(1);
    section4.output_section[1].input_section[0].$name = ". = . + __FIQ_STACK_SIZE;";
    section4.output_section[2].$name                  = ".svcstack";
    section4.output_section[2].output_sections_start  = "__SVC_STACK_START";
    section4.output_section[2].output_sections_end    = "__SVC_STACK_END";
    section4.output_section[2].input_section.create(1);
    section4.output_section[2].input_section[0].$name = ". = . + __SVC_STACK_SIZE;";
    section4.output_section[3].$name                  = ".abortstack";
    section4.output_section[3].output_sections_start  = "__ABORT_STACK_START";
    section4.output_section[3].output_sections_end    = "__ABORT_STACK_END";
    section4.output_section[3].input_section.create(1);
    section4.output_section[3].input_section[0].$name = ". = . + __ABORT_STACK_SIZE;";
    section4.output_section[4].$name                  = ".undefinedstack";
    section4.output_section[4].output_sections_start  = "__UNDEFINED_STACK_START";
    section4.output_section[4].output_sections_end    = "__UNDEFINED_STACK_END";
    section4.output_section[4].input_section.create(1);
    section4.output_section[4].input_section[0].$name = ". = . + __UNDEFINED_STACK_SIZE;";
    
    section5.group                       = false;
    section5.type                        = "NOLOAD";
    section5.load_memory                 = "MSRAM_1";
    section5.$name                       = "Bss File Buffer";
    section5.output_section.create(1);
    section5.output_section[0].$name     = ".bss.filebuf";
    section5.output_section[0].alignment = 0;
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    i2c1.I2C.SCL.$suggestSolution = "GPIO135";
    i2c1.I2C.SDA.$suggestSolution = "GPIO134";
    

  • Thank you for sharing the flash part and sysconfig.

  • Hi Aswin,

       Sorry for being occupied with another project these days. Would you be available for a brief discussion this Thursday or Friday? Is there any additional testing I need to prepare in advance? Alternatively, could we communicate briefly via email? At least I think it would be more efficient than the website :)

    Best regards

  • Hi Zhou, 

    Is it okay if we can have the discussion on Monday? Would that be feasible ? Yes we can communicate via email.

    Regards,

    Aswin

  • Hi Aswin,
    I'm afraid I'm only available after 3 PM Beijing Time next Monday. Could you please let me know if this time works for you? If not, we can reschedule to another convenient time.
    We may also conduct initial communication via email first. My email address is nanyi.zhou@se.com
    regards
  • Hi Aswin,

       Could you please provide your email address? I have some new test findings to share.

    Regards.

  • Hi Zhou, 

    I have sent you an email. Please check it.

    Regards,

    Aswin