Tool/software:
Hello TI experts,
I am trying to modify SBL to write firmware (XIP format) to Flash.
The SDK version is MCU+ SDK v10.00.00.20.
I have two problems here, and I would appreciate it if you could answer them.
<No.1>
I cannot write to Flash in the SBL process. (The return value of Flash_write() is an error.)
The steps I took are as follows.
1. I removed the firmware read process from the SBL example[*1] and added a Flash write process.
2. I referred to the OSPI example[*2] for the Flash write process.
*1: examples/drivers/boot/sbl_ospi
*2: examples/ospi/ospi_flash_io
The resulting source code (main.c) is as follows.
The Flash writing process starts on line 135.
/* * Copyright (C) 2018-2022 Texas Instruments Incorporated * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <stdlib.h> #include "ti_drivers_config.h" #include "ti_drivers_open_close.h" #include "ti_board_open_close.h" #include <drivers/sciclient.h> #include <drivers/bootloader/soc/bootloader_soc.h> #include <drivers/bootloader.h> #include <kernel/dpl/ClockP.h> #define DELAY_SEC (1000U) #define APP_OSPI_FLASH_OFFSET_BASE (0x200000U) #define APP_OSPI_DATA_SIZE (2048) static uint8_t gOspiTxBuf[APP_OSPI_DATA_SIZE]; void flashFixUpQspiBoot(void); void ospi_flash_io_fill_buffers(void); /* call this API to stop the booting process and spin, do that you can connect * debugger, load symbols and then make the 'loop' variable as 0 to continue execution * with debugger connected. */ void loop_forever(void) { volatile uint32_t loop = 1; while(loop) ; } int main(void) { int32_t status; Bootloader_profileReset(); Bootloader_socWaitForFWBoot(); #ifndef DISABLE_WARM_REST_WA /* Warm Reset Workaround to prevent CPSW register lockup */ if (!Bootloader_socIsMCUResetIsoEnabled()) { Bootloader_socResetWorkaround(); } #endif Bootloader_profileAddProfilePoint("SYSFW init"); if (!Bootloader_socIsMCUResetIsoEnabled()) { /* Update devGrp to ALL to initialize MCU domain when reset isolation is not enabled */ Sciclient_BoardCfgPrms_t boardCfgPrms_pm = { .boardConfigLow = (uint32_t)0, .boardConfigHigh = 0, .boardConfigSize = 0, .devGrp = DEVGRP_ALL, }; status = Sciclient_boardCfgPm(&boardCfgPrms_pm); Sciclient_BoardCfgPrms_t boardCfgPrms_rm = { .boardConfigLow = (uint32_t)0, .boardConfigHigh = 0, .boardConfigSize = 0, .devGrp = DEVGRP_ALL, }; status = Sciclient_boardCfgRm(&boardCfgPrms_rm); /* Enable MCU PLL. MCU PLL will not be enabled by DMSC when devGrp is set to Main in boardCfg */ Bootloader_enableMCUPLL(); } Bootloader_socOpenFirewalls(); Bootloader_socNotifyFirewallOpen(); System_init(); Bootloader_profileAddProfilePoint("System_init"); Drivers_open(); Bootloader_profileAddProfilePoint("Drivers_open"); #if 0 DebugP_log("\r\n"); DebugP_log("Starting OSPI Bootloader ... \r\n"); #endif /* ROM doesn't reset the QSPI flash. So do a flash reset */ flashFixUpQspiBoot(); status = Board_driversOpen(); DebugP_assert(status == SystemP_SUCCESS); Bootloader_profileAddProfilePoint("Board_driversOpen"); status = Sciclient_getVersionCheck(1); Bootloader_profileAddProfilePoint("Sciclient Get Version"); #if (1) // Flash writing process based on ospi_flash_io exmaple code. uint32_t block; uint32_t page; uint32_t offset = APP_OSPI_FLASH_OFFSET_BASE; if(SystemP_SUCCESS == status) { // Erase block ospi_flash_io_fill_buffers(); DebugP_log("Erase Flash (%x)...", offset); Flash_offsetToBlkPage(gFlashHandle[CONFIG_FLASH0], offset, &block, &page); DebugP_log("block=[%x], page=[%x]\r\n", block, page); status = Flash_eraseBlk(gFlashHandle[CONFIG_FLASH0], block); } if (status == SystemP_SUCCESS) { // Write DebugP_log("Writing to Flash (src: %p, dst: %x)...", gOspiTxBuf, offset); ospi_flash_io_fill_buffers(); status = Flash_write(gFlashHandle[CONFIG_FLASH0], offset, gOspiTxBuf, APP_OSPI_DATA_SIZE); DebugP_log("Done. status=[%d]\r\n", status); } #endif if(status != SystemP_SUCCESS ) { DebugP_log("Some tests have failed!!\r\n"); } Drivers_close(); System_deinit(); return 0; } void flashFixUpQspiBoot(void) { uint32_t gpiobaseAddr, pinnum; /* Get address after translation translate */ gpiobaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CONFIG_GPIO0_BASE_ADDR); pinnum = CONFIG_GPIO0_PIN; /* Drive the GPIO Pin low to assert the reset signal */ GPIO_pinWriteLow(gpiobaseAddr, pinnum); ClockP_usleep(DELAY_SEC); /* Drive the GPIO Pin high to deassert the reset signal */ GPIO_pinWriteHigh(gpiobaseAddr, pinnum); ClockP_usleep(DELAY_SEC); } void ospi_flash_io_fill_buffers(void) { uint32_t i; for(i = 0U; i < APP_OSPI_DATA_SIZE; i++) { gOspiTxBuf[i] = i % 256; } }
The execution result is as follows.
DMSC Firmware Version 10.0.8--v10.00.08 (Fiery Fox) DMSC Firmware revision 0xa DMSC ABI revision 4.0 Erase Flash (200000)...block=[8], page=[0] Writing to Flash (src: 70075008, dst: 200000)...Done. status=[-1] Some tests have failed!!
The Flash writing process has been confirmed to work correctly when running the OSPI example[*2] alone.
The cause of the error in SBL is unknown, so if you have any clues, please let me know.
<No.2>
I want to use the Bootloader module to perform XIP operation on each core,
but when writing the XIP format to Flash, what address should I write the .appimage_xip to?
Should I overwrite it to the same address as the .appimage?
Please tell me the procedure.
Regards,
TAKEDA Taro
Hello,
1. Please change the Region Attributes from the default "NonCached" to "Strongly Ordered" in the SBL_OSPI Sysconfig as shown below:
2. May I know the use case for using XIP image?
The SBL OSPI is generally used to boot the normal appimage.
Regards,
Prashant
Hello Prashant,
Thank you for your reply.
I would like to try it, but please wait until mid-January for a reply due to my vacation.
Regards,
TAKEDA Taro
Hello Prashant,
Sorry, please wait until around February for a response as I have other work that has a higher priority.
Regards,
TAKEDA Taro
Hello Prashant,
Thank you for waiting.
1.
I was able to write to Flash correctly by following your instructions!
Thanks!
2.
> May I know the use case for using XIP image?
> The SBL OSPI is generally used to boot the normal appimage.
In order to minimize the amount of RAM used, I thought about starting the execution binary for each core from ROM.
Also, since switching DIP-SW is troublesome, I would like to give the SBL the function to write the XIP binary received via serial to the Flash.
If you have any examples or tips of how to achieve this, please let me know.
Regards,
TAKEDA Taro
Hello,
In order to minimize the amount of RAM used, I thought about starting the execution binary for each core from ROM.
The ROM only boots the SBL. The SBL would boot the application for each core.
Have you already tried booting the normal appimage? If yes, what is the exact issue you have that you would like to use XIP?
Regards,
Prashant
Hello Prashant,
>Have you already tried booting the normal appimage?
This comment made me realize that there was a serious mistake. Thank you.
It was that I had not assigned the Code and Text sections to Flash in the MEMORY CONFIGURATOR settings in SysConfig.
When I assigned them, the size of the output .appimage_xip increased, so I thought that writing it to Flash would be correct.
However, it did not work.
The function Bootloader_parseMultiCoreAppImage returns an error.
If there are any points I should check to XIP working, please let me know.
Regards,
TAKEDA Taro
Hello Prashant,
Thank you.
After reading this guide, I checked the linker command file (linker.cmd) and it was as intended, so there seems to be no problem with the XIP binary I created.
However, as I mentioned earlier, when I write the serial received XIP file (.appimage_xip) to Flash, it does not work.
Here, the guide has the following sentence
The file containing XIP sections is additionally flashed to the flash using the special flash-xip
command passed to the flash writer
I think I could write to Flash in the same way as the flash writer (probably uart_uniflash.py) in the statement, but I don't know how to write it in code.
Is this idea correct?
Also, if it is correct, please tell me if there is any code to write XIP files to the Flash.
Regards,
TAKEDA Taro
Hello,
The SBL_UART_UNIFLASH uses the following API for writing XIP images to the flash:
You may use the same for your SBL.
Regards,
Prashant