Hi everyone,
I want to write data to some sectors of my code located at bank0. I use F021 Flash APIs for this process and get help from the UART bootloader source code previously written by TI (www.ti.com/.../spna192). A separate region named FLASH_API has been opened in the Uart bootloader source code, allowing F021 functions to be located on SRAM (0x08002000). I also performed these operations on my own code, but when I examined it with Memory Browser, these fields were assigned as 0x00, unlike the sample code.
UART bootloader example docs
My code
//***************************************************************************** // // bl_flash.c : The file holds the main control loop of the boot loader. // Author : QJ Wang. qjwang@ti.com // Date : 9-19-2012 // // Copyright (c) 2006-2011 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // //***************************************************************************** #include "bl_config.h" #include "bl_flash.h" #include "F021.h" #include "flash_defines.h" //#define Freq_In_MHz = SYS_CLK_FREQ; //***************************************************************************** // // Returns the size of the ist sector size of the flash in bytes. // //***************************************************************************** uint32_t BLInternalFlashFirstSectorSizeGet(void) { uint32_t firstSectorSize; firstSectorSize = (uint32_t)(flash_sector[0].start) + flash_sector[0].length; return (firstSectorSize); } //***************************************************************************** // // Returns the size of the internal flash in bytes. // // This function returns the total number of bytes of internal flash in the // current part. No adjustment is made for any sections reserved via // options defined in bl_config.h. // // \return Returns the total number of bytes of internal flash. // //***************************************************************************** uint32_t BLInternalFlashSizeGet(void) { uint32_t flashSize; flashSize = (uint32_t)flash_sector[NUMBEROFSECTORS-1].start + flash_sector[NUMBEROFSECTORS-1].length; return (flashSize); } //***************************************************************************** // //! Checks whether a given start address is valid for a download. //! //! This function checks to determine whether the given address is a valid //! download image start address given the options defined in bl_config.h. //! //! \return Returns non-zero if the address is valid or 0 otherwise. // //***************************************************************************** uint32_t BLInternalFlashStartAddrCheck(uint32_t ulAddr, uint32_t ulImgSize) { uint32_t count=0, i; uint32_t ulWholeFlashSize; // // Determine the size of the flash available on the part in use. // ulWholeFlashSize = (uint32_t)flash_sector[NUMBEROFSECTORS-1].start + flash_sector[NUMBEROFSECTORS-1].length; /* 3MB */ /* The start address must be at the begining of the sector */ for (i = 0; i < NUMBEROFSECTORS; i++){ if ((ulAddr >= (uint32_t)(flash_sector[i].start)) && (ulAddr < ((uint32_t)flash_sector[i].start + flash_sector[i].length))) { count++; } } if (count == 0){ return(0); } // // Is the address we were passed a valid start address? We allow: // // 1. Address 0 if configured to update the boot loader. // 2. The start of the reserved block if parameter space is reserved (to // allow a download of the parameter block contents). // 3. The application start address specified in bl_config.h. // // The function fails if the address is not one of these, if the image // size is larger than the available space or if the address is not word // aligned. // if(( #ifdef ENABLE_BL_UPDATE (ulAddr != 0) && #endif (ulAddr != APP_START_ADDRESS)) || ((ulAddr + ulImgSize) > ulWholeFlashSize) || ((ulAddr & 3) != 0)) { return(0); } else { return(1); } } uint32_t Fapi_BlockErase( uint32_t Bank, uint32_t ulAddr, uint32_t Size) { uint8_t i=0, ucStartBank, ucEndBank, ucStartSector, ucEndSector; uint32_t EndAddr, status; EndAddr = ulAddr + Size; for (i = 0; i < NUMBEROFSECTORS; i++){ if ((ulAddr >= (uint32_t)(flash_sector[i].start)) && (ulAddr < ((uint32_t)flash_sector[i].start + flash_sector[i].length))) { ucStartBank = flash_sector[i].bankNumber; ucStartSector = i; break; } } for (i = ucStartSector; i < NUMBEROFSECTORS; i++){ if (EndAddr <= (((uint32_t)flash_sector[i].start) + flash_sector[i].length)) { ucEndBank = flash_sector[i].bankNumber; ucEndSector = i; break; } } status=Fapi_initializeFlashBanks((uint32_t)SYS_CLK_FREQ); /* used for API Rev2.01 */ for (i = ucStartBank; i < (ucEndBank + 1); i++){ Fapi_setActiveFlashBank((Fapi_FlashBankType)i); Fapi_enableMainBankSectors(0xFFFF); /* used for API 2.01*/ while( FAPI_CHECK_FSM_READY_BUSY != Fapi_Status_FsmReady ); } for (i=ucStartSector; i<(ucEndSector+1); i++){ Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, flash_sector[i].start); while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy ); while(FAPI_GET_FSM_STATUS != Fapi_Status_Success); } status = Flash_Erase_Check((uint32_t)ulAddr, Size); return (status); } //Bank here is not used. We calculate the bank in the function based on the Flash-Start-addr uint32_t Fapi_BlockProgram( uint32_t Bank, uint32_t Flash_Address, uint32_t Data_Address, uint32_t SizeInBytes) { register uint32_t src = Data_Address; register uint32_t dst = Flash_Address; uint32_t bytes; if (SizeInBytes < 16) bytes = SizeInBytes; else bytes = 16; if ((Fapi_initializeFlashBanks((uint32_t)SYS_CLK_FREQ)) == Fapi_Status_Success){ (void)Fapi_setActiveFlashBank((Fapi_FlashBankType)Bank); (void)Fapi_enableMainBankSectors(0xFFFF); /* used for API 2.01*/ }else { return (1); } while( FAPI_CHECK_FSM_READY_BUSY != Fapi_Status_FsmReady ); while( FAPI_GET_FSM_STATUS != Fapi_Status_Success ); while( SizeInBytes > 0) { Fapi_issueProgrammingCommand((uint32_t *)dst, (uint8_t *)src, (uint32_t) bytes, 0, 0, Fapi_AutoEccGeneration); while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy ); // while(FAPI_GET_FSM_STATUS != Fapi_Status_Success); src += bytes; dst += bytes; SizeInBytes -= bytes; if ( SizeInBytes < 16){ bytes = SizeInBytes; } } return (0); } uint32_t Fapi_UpdateStatusProgram( uint32_t Bank, uint32_t Flash_Start_Address, uint32_t Data_Start_Address, uint32_t Size_In_Bytes) { register uint32_t src = Data_Start_Address; register uint32_t dst = Flash_Start_Address; unsigned int bytes, status; if (Size_In_Bytes < 16) bytes = Size_In_Bytes; else bytes = 16; Fapi_initializeAPI((Fapi_FmcRegistersType *)F021_CPU0_REGISTER_ADDRESS, (uint32_t)SYS_CLK_FREQ); Fapi_setActiveFlashBank((Fapi_FlashBankType)Bank); Fapi_issueProgrammingCommand((uint32_t *)dst, (uint8_t *)src, (uint32_t) bytes, //8, 0, 0, Fapi_AutoEccGeneration); while( Fapi_checkFsmForReady() == Fapi_Status_FsmBusy ); status = Flash_Program_Check(Flash_Start_Address, Data_Start_Address, Size_In_Bytes); return (status); } uint32_t Flash_Program_Check(uint32_t Program_Start_Address, uint32_t Source_Start_Address, uint32_t No_Of_Bytes) { register uint32_t *src1 = (uint32_t *) Source_Start_Address; register uint32_t *dst1 = (uint32_t *) Program_Start_Address; register uint32_t bytes = No_Of_Bytes; while(bytes > 0) { if(*dst1++ != *src1++) return (1); //error bytes -= 0x4; } return(0); } uint32_t Flash_Erase_Check(uint32_t Start_Address, uint32_t Bytes) { uint32_t error=0; register uint32_t *dst1 = (uint32_t *) Start_Address; register uint32_t bytes = Bytes; while(bytes > 0) { if(*dst1++ != 0xFFFFFFFF){ error = 2; } bytes -= 0x4; } return(error); } uint32_t Fapi_BlockRead( uint32_t Bank, uint32_t Flash_Start_Address, uint32_t Data_Start_Address, uint32_t Size_In_Bytes) { register uint32_t src = Data_Start_Address; register uint32_t dst = Flash_Start_Address; register uint32_t bytes_remain = Size_In_Bytes; int bytes; if (Size_In_Bytes < 16) bytes = Size_In_Bytes; else bytes = 16; Fapi_initializeAPI((Fapi_FmcRegistersType *)F021_CPU0_REGISTER_ADDRESS, (uint32_t)SYS_CLK_FREQ); while( bytes_remain > 0) { Fapi_doMarginReadByByte((uint8_t *)src, (uint8_t *)dst, (uint32_t) bytes, //16 Fapi_NormalRead); src += bytes; dst += bytes; bytes_remain -= bytes; } return (0); } extern void ramWriteEnable() { int a = 10; (void)a; }