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.

EK-TM4C1294XL: TM4C1294NCPDT || OTA Queries

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: TM4C1294NCPDT, , UNIFLASH

Tool/software:

Hi Team,
We are trying to perform OTA in TM4C1294NCPDT Controller. The controller will be connected to the GSM EC21E module via USB or UART. The GSM module's UFS or RAM will contain the upgraded firmware, we can use AT commands to read or download the file bytes to the controller's buffer, once this is done, how do we erase the existing firmware and write our updated firmware in flash?
Please help us to achieve this. Is there a dedicated example available to perform this?
  • Hi,

      I will suggest you refer to the UART bootloader example as a starter. The UART bootloader can be found at C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\boot_serial. This example will download/upgrade the firmware from the UART interface. As you follow the example, the bootloader will call the Updater() function in bl_main,c file. Please go through this function as it implements how to erase the flash and program the firmware chunks by chunks. If you are receiving the firmware through the GSM, it is no different to go through the Updater() function to perform same steps. 

      Also refer to the TM4C Bootloader User's Guide for details. 

  • Hi Charles,

     

    Thanks for the reply, I can able to find the example in below path but I cant able to see the specific .c file. How to analyse and modify the code? 


    SW-EK-TM4C1294XL-2.2.0.295/examples/boards/ek-tm4c1294xl/boot_serial

  • Hi,

      If you downloaded the example then you would see the boot_loader directory in the CCS project with all supported files. See below. 

     In the TivaWare, the bootloader source code is at C:\ti\TivaWare_C_Series-2.2.0.295\boot_loader

  • Hi Charles,

    Thanks for the reply. Can I directly add the bl_main.c file to my blinky project and try performing a basic blinky OTA? Is that the correct way?

    Because in boot serial I dont have these files, I am using TivaWare source code.

  • Can I directly add the bl_main.c file to my blinky project and try performing a basic blinky OTA?

    I'm not clear with your question. The blinky project is a very simple project that just blink the LED. What do you mean you want to perform a basic blinky OTA? I thought you will be receiving a program via the UART that is connected to a GSM. What is the GSM sending to the MCU? Is it another blinky program? You need to have the Updater() copied to the RAM so the CPU can execute out of the RAM to program and erase the flash. 

    I strongly suggest you run the boot_serial (this is a serial bootloader) example along with the boot_demo1 (this is an example application). Get these examples to work first and then I think it will clear up for you on how the bootloader works. Basically, the boot_serial is first loaded to the flash at 0x0 through JTAG interface. After reset, it will find out if there is already a firmware image at 0x4000. If there is a valid firmware then it will just jump to the firmware at 0x4000 and execute the firmware. If there is no valid firmware image then it will try to download the firmware (the boot_demo1 example) from the UART port. The bootloader will copy the bootloader code to the RAM so that CPU will execute from RAM and then program the firmware to the flash using the binary that it receives from the UART port. Run the example and get a feel for it. 

  • Hi Charles,

    Thanks for the reply.

    I have analyzed both the code and tried flashing the boot_serial along with boot_demo1. As per my understanding, I first flashed boot_demo1 which has blink function, and it was stored at 0x00004000 in flash (verified using the .cmd file). Then, I flashed boot_serial, which should be stored at 0x00000000 in flash. Once the flashing was done, I reset the board.

    As per my understanding, if a valid image is present at 0x00004000, the boot_serial should execute this image, but it is not executing, and the LED is not blinking. Please correct me if I am wrong.

  • Hi,

      No, your procedure of running the example is incorrect. The boot_demo1 is the firmware that is to be downloaded from UART by the bootloader. You don't use JTAG to load the boot_demo1. You should use the JTAG to load the boot_serial first. After boot_serial is loaded and running, it will configure UART to download boot_demo1. Again, you want to load the boot_demo1 through the UART interface, not JTAG. That is the whole purpose of bootloading unless you are doing debug to first boot_demo1 using JTAG. When you first load boot_demo1 and later load boot_serial, the loading of boot_serial by JTAG will first erase the entire flash and then program the boot_serial. The boot_demo1 is then wiped out. 


  • Hi Charles,

    I understand your point. I have now flashed the boot_serial at address 0x00000000 using the debugger. I have separately built the boot_demo1, and the binary is available at the following path: /root/workspace_v11/boot_demo1/Debug/boot_demo1.bin.

    How should I send this binary to UART0? Is it possible to upload the binary directly using Minicom at a baud rate of 115200, or do I need to use a custom programmer or script to send the binary?

    If possible, could you please share the steps to upload the binary to UART0?

  • How should I send this binary to UART0? Is it possible to upload the binary directly using Minicom at a baud rate of 115200, or do I need to use a custom programmer or script to send the binary?

    You can use LM flash programmer. See below. 

    Or you can use the command line sflash.exe which you can find at C:\ti\TivaWare_C_Series-2.2.0.295\tools\bin

  • Hi Charles,

    Sorry for the delay.

    I tried sending the binary file using sflash.exe, but it got stuck. I first flashed boot_serial using JTAG.


    MEMORY
    {
    FLASH (RX) : origin = 0x00000000, length = 0x00010000
    SRAM (RWX) : origin = 0x20000000, length = 0x00010000
    }

    Then, I built boot_demo1 and attempted to send the binary using the below command.

    #define APP_BASE 0x00004000
    #define RAM_BASE 0x20000000

    MEMORY
    {
    FLASH (RX) : origin = APP_BASE, length = 0x000fc000
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }

    Command used:

    .\sflash.exe boot_demo1.bin -p 0x00004000 -r 0x20000000 -c 7 -b 115200 -s 1224

    When I use the -h option, I can see the help console, which confirms that the .exe file is executing properly. But I am not sure why it is hunged while giving above command.

  • Hi Charles, 

    I also tried via LM Flash programmer for flashing the bin. First I have flashed the boot_serial and tried to flash boot_demo1. Getting below error.

  • Hi Charles,

    I initially missed the offset 0x4000, but now it is working for me. I am able to flash boot_demo1.bin using the LM Flash Programmer. However, when I press the SW1 button, it goes back into bootloader mode.

    I have one more query. Currently, my program is executing from internal flash at 0x00000000. Now, I receive 1224 bytes of data on UART 0 from GSM module and store it in a buffer called GSM_Buffer[1224]. Is it possible to write this data to 0x00004000 in internal flash and then change the execution address to this new location from the current application with out switching to bootloader?

  • I initially missed the offset 0x4000, but now it is working for me. I am able to flash boot_demo1.bin using the LM Flash Programmer. However, when I press the SW1 button, it goes back into bootloader mode.

    Hi,

      Glad that you got it working. It is part of the application boot_demo1 to allow user to update the firmware again by pressing SW1.

    I have one more query. Currently, my program is executing from internal flash at 0x00000000. Now, I receive 1224 bytes of data on UART 0 from GSM module and store it in a buffer called GSM_Buffer[1224]. Is it possible to write this data to 0x00004000 in internal flash and then change the execution address to this new location from the current application with out switching to bootloader?

    Is 1124 bytes all you have for your new code? 

    How big is your current code residing at 0x0? If it is exceeding more than 0x4000 then you will overwrite it if you were to program some code at 0x4000, isn't?

    Why wouldn't you want to use the bootloader? To program the flash, you will need to run the bootloader code from RAM so it can erase and program new code to flash. If you don't have a bootloader but only your application at 0x0, then somehow you need to move your application to RAM so you could program new code to the flash. I suggest you use the bootloader. 

  • Hi Charles,

    In my case, I am communicating my TM4C controller with the EC21E GSM module using UART 0. My current application is running at address 0x00000000, which reads the ADC value of a 8 pins and sends it to GSM module along with the formatted data via UART 0 AT command, to push the data to the MQTT server.

    If I send a specific AT command along with the server URL and topic, my firmware update binary will be downloaded and stored in the GSM module's local UFS. I will then read that bin file to the TM4C controller via UART 0 using file handling AT commands and store the bin data in a buffer called GSM_Buffer[1224]. At this point, I need to flash this bin file into the internal flash and execute it.

    That's my query—how can I flash the boot_serial first? I need to integrate the code to do this.

    I am unable to track the int main() function in the boot_serial example. Can you please tell me where the execution starts in the which .c file?

  • Hi Charles, 

    Can you please help on this?

  • Hi Charles, 

    My GSM_Buffer[1224] = " µDÇDÃDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅD-éðG„FFVHßøT‘ßøXh ê˜E$Oð

    úóBøÄ?ÜøÄ_ÂóA³@+CÌøÄ?d,èÛ'¿Üø5CÜø5‹CÌø5'5CÜ5‹CÌ5 '¿Üø5CÜø5‹CÌø5hLFEF#@B ÐR '¿Üø<%
    CÜø<%ŠCÌø<%'¿Ü%ŠCÌø%: '¿Üø%
    CÜø%ŠCÌø%h@¥ˆCô@ÌøD¿Üø@CÜø@ˆCÌø@/¿Üø( êÜø(L FðIø Fð*ø(úÐNL%!0F
    JÀó#ôÿQðÿ¡õ01Ò!ð~AAêqAê€Aðph ± pGÀFêôÿQðÿ¡õP1Ò!ð~AAêq"Aê€Aðp`pGÀFæ@'¿Ð4'¿Ðø $CÐø $"êÀø pH€h@ô`¿¿ðø ÿ÷sÿ(Fÿ÷Èÿ8½@ø! pGÿ÷Ø¿pG pG¿þçþçþçþç"

    will be like this which is readed from GSM module via UART 0 of TM4C controller.

  • I am unable to track the int main() function in the boot_serial example. Can you please tell me where the execution starts in the which .c file?

    The bootloader starts with bl_startup_ccs.s file. You can find this file in the bootloader folder at C:\ti\TivaWare_C_Series-2.2.0.295\boot_loader. Follow this file to see how the bootloader initiates the UART interface and programs the application firmware by calling the Updater() function. In order to program the application firmware to the flash, the bootloader needs to first copy itself from the flash to the RAM and let the CPU execute the bootloading code out of RAM. You can not run code out of flash at the same time that you program the flash. 

    My GSM_Buffer[1224] = " µDÇDÃDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅD-éðG„FFVHßøT‘ßøXh ê˜E$Oð

    úóBøÄ?ÜøÄ_ÂóA³@+CÌøÄ?d,èÛ'¿Üø5CÜø5‹CÌø5'5CÜ5‹CÌ5 '¿Üø5CÜø5‹CÌø5hLFEF#@B ÐR '¿Üø<%
    CÜø<%ŠCÌø<%'¿Ü%ŠCÌø%: '¿Üø%
    CÜø%ŠCÌø%h@¥ˆCô@ÌøD¿Üø@CÜø@ˆCÌø@/¿Üø( êÜø(L FðIø Fð*ø(úÐNL%!0F
    JÀó#ôÿQðÿ¡õ01Ò!ð~AAêqAê€Aðph ± pGÀFêôÿQðÿ¡õP1Ò!ð~AAêq"Aê€Aðp`pGÀFæ@'¿Ð4'¿Ðø $CÐø $"êÀø pH€h@ô`¿¿ðø ÿ÷sÿ(Fÿ÷Èÿ8½@ø! pGÿ÷Ø¿pG pG¿þçþçþçþç"

    What is this? Is this a new code or data? It seems to me just data. I can't image your entire firmware is less than 1kB. 

  • Hi Charles, 

    What is this? Is this a new code or data? It seems to me just data. I can't image your entire firmware is less than 1kB. --->>> Yes this is a simple blinky code binary data readed from GSM module for developement.

  • Hi Charles,

    I have started modifying the bl_main.c file for my application. I have a question regarding the offset settings in the LM flasher and slafsh.exe. In these tools, we specify an offset as 0x00004000. However, in my case, I am reading the raw binary data from the GSM module's UFS using the following command via UART 0:

    AT+QFDWL="BLINKY.bin"

    This command retrieves the raw binary data from the specified file. How should I handle the offset value in this scenario? How can I specify the offset address in my case?

    I am attempting to send this command using the SendPacket function in bl_packet.c over UART0. I tried calling this function at the beginning of the updater, but I am unable to send the binary data if I include this line.

    SendPacket("AT+QFDWL=\"BLINKY.bin\"\r\n",26);


    Please help on this once donwload command is sent via UART0 the gsm module will send back the binary datas in UART0, the received data should be stored in flash and need to start booting.

  • Hi charles, 

    Is it possible to hard code my BLINKY's binary data as hex values in updater function as array and write this values in flash 0x00004000 will this works, I am taking this hex values values from binary using hexdump tool.

    unsigned char BLINKY_bin[] = {
    0x00, 0x02, 0x00, 0x20, 0xb5, 0x44, 0x00, 0x00, 0xc7, 0x44, 0x00, 0x00,
    0xc3, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,
    0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x47,
    0x84, 0x46, 0x1f, 0x46, 0x56, 0x48, 0xdf, 0xf8, 0x54, 0x91, 0xdf, 0xf8,
    0x58, 0x81, 0x03, 0x68, 0x09, 0xea, 0x03, 0x03, 0x98, 0x45, 0x1b, 0xd0,
    0x00, 0x24, 0x4f, 0xf0, 0x01, 0x0a, 0x4f, 0xf0, 0x03, 0x0e, 0x0a, 0xfa,
    0x04, 0xf3, 0x19, 0x42, 0x0f, 0xd0, 0xdc, 0xf8, 0xc4, 0x3f, 0x66, 0x00,
    0x0e, 0xfa, 0x06, 0xf5, 0xab, 0x43, 0xcc, 0xf8, 0xc4, 0x3f, 0xdc, 0xf8,
    0xc4, 0x5f, 0xc2, 0xf3, 0x41, 0x13, 0xb3, 0x40, 0x2b, 0x43, 0xcc, 0xf8,
    0xc4, 0x3f, 0x64, 0x1c, 0x08, 0x2c, 0xe8, 0xdb, 0x53, 0x08, 0x27, 0xbf,
    0xdc, 0xf8, 0x00, 0x35, 0x0b, 0x43, 0xdc, 0xf8, 0x00, 0x35, 0x8b, 0x43,
    0xcc, 0xf8, 0x00, 0x35, 0x93, 0x08, 0x27, 0xbf, 0xdc, 0xf8, 0x04, 0x35,
    0x0b, 0x43, 0xdc, 0xf8, 0x04, 0x35, 0x8b, 0x43, 0xcc, 0xf8, 0x04, 0x35,
    0xd3, 0x08, 0x27, 0xbf, 0xdc, 0xf8, 0x08, 0x35, 0x0b, 0x43, 0xdc, 0xf8,
    0x08, 0x35, 0x8b, 0x43, 0xcc, 0xf8, 0x08, 0x35, 0x13, 0x09, 0x27, 0xbf,
    0xdc, 0xf8, 0x18, 0x35, 0x0b, 0x43, 0xdc, 0xf8, 0x18, 0x35, 0x8b, 0x43,
    0xcc, 0xf8, 0x18, 0x35, 0x03, 0x68, 0x4c, 0x46, 0x45, 0x46, 0x23, 0x40,
    0x9d, 0x42, 0x09, 0xd0, 0x52, 0x09, 0x27, 0xbf, 0xdc, 0xf8, 0x3c, 0x25,
    0x0a, 0x43, 0xdc, 0xf8, 0x3c, 0x25, 0x8a, 0x43, 0xcc, 0xf8, 0x3c, 0x25,
    0x7a, 0x08, 0x27, 0xbf, 0xdc, 0xf8, 0x0c, 0x25, 0x0a, 0x43, 0xdc, 0xf8,
    0x0c, 0x25, 0x8a, 0x43, 0xcc, 0xf8, 0x0c, 0x25, 0xba, 0x08, 0x27, 0xbf,
    0xdc, 0xf8, 0x10, 0x25, 0x0a, 0x43, 0xdc, 0xf8, 0x10, 0x25, 0x8a, 0x43,
    0xcc, 0xf8, 0x10, 0x25, 0xfa, 0x08, 0x27, 0xbf, 0xdc, 0xf8, 0x14, 0x25,
    0x0a, 0x43, 0xdc, 0xf8, 0x14, 0x25, 0x8a, 0x43, 0xcc, 0xf8, 0x14, 0x25,
    0x3a, 0x09, 0x27, 0xbf, 0xdc, 0xf8, 0x1c, 0x25, 0x0a, 0x43, 0xdc, 0xf8,
    0x1c, 0x25, 0x8a, 0x43, 0xcc, 0xf8, 0x1c, 0x25, 0x00, 0x68, 0x04, 0x40,
    0xa5, 0x42, 0x14, 0xd0, 0xb8, 0x0a, 0x27, 0xbf, 0xdc, 0xf8, 0x44, 0x05,
    0x08, 0x43, 0xdc, 0xf8, 0x44, 0x05, 0x88, 0x43, 0x17, 0xf4, 0x40, 0x7f,
    0xcc, 0xf8, 0x44, 0x05, 0x19, 0xbf, 0xdc, 0xf8, 0x40, 0x05, 0x08, 0x43,
    0xdc, 0xf8, 0x40, 0x05, 0x88, 0x43, 0xcc, 0xf8, 0x40, 0x05, 0x00, 0x2f,
    0x19, 0xbf, 0xdc, 0xf8, 0x28, 0x05, 0x20, 0xea, 0x01, 0x01, 0xdc, 0xf8,
    0x28, 0x05, 0x01, 0x43, 0xcc, 0xf8, 0x28, 0x15, 0xbd, 0xe8, 0xf0, 0x87,
    0x00, 0x00, 0xff, 0x70, 0x00, 0xe0, 0x0f, 0x40, 0x00, 0x00, 0x05, 0x10,
    0x7c, 0xb5, 0x15, 0x4c, 0x20, 0x46, 0x00, 0xf0, 0x49, 0xf8, 0x20, 0x46,
    0x00, 0xf0, 0x2a, 0xf8, 0x00, 0x28, 0xfa, 0xd0, 0x11, 0x4e, 0x01, 0x21,
    0x30, 0x46, 0x00, 0xf0, 0x85, 0xf8, 0x10, 0x4c, 0x00, 0x25, 0x01, 0x21,
    0x30, 0x46, 0x0a, 0x46, 0x00, 0xf0, 0x8b, 0xf8, 0x00, 0x95, 0x00, 0x98,
    0x84, 0x42, 0x0c, 0xd8, 0x30, 0x46, 0x01, 0x21, 0x2a, 0x46, 0x00, 0xf0,
    0x82, 0xf8, 0x00, 0x95, 0x00, 0x98, 0x84, 0x42, 0xed, 0xd9, 0x00, 0x98,
    0x40, 0x1c, 0x00, 0x90, 0xf8, 0xe7, 0x00, 0x98, 0x40, 0x1c, 0x00, 0x90,
    0xeb, 0xe7, 0xc0, 0x46, 0x0c, 0x08, 0x00, 0xf0, 0x00, 0x40, 0x06, 0x40,
    0x40, 0x0d, 0x03, 0x00, 0x0c, 0x4a, 0xc1, 0x08, 0xc0, 0xf3, 0x07, 0x23,
    0x01, 0xf4, 0xff, 0x51, 0x00, 0xf0, 0xff, 0x00, 0xa1, 0xf5, 0x30, 0x31,
    0xd2, 0x18, 0x21, 0xf0, 0x7e, 0x41, 0x12, 0x0f, 0x41, 0xea, 0x02, 0x71,
    0x41, 0xea, 0x80, 0x01, 0x41, 0xf0, 0x00, 0x70, 0x01, 0x68, 0x00, 0x20,
    0x01, 0xb1, 0x01, 0x20, 0x70, 0x47, 0xc0, 0x46, 0x00, 0xea, 0x0f, 0x40,
    0x0b, 0x4a, 0xc1, 0x08, 0xc0, 0xf3, 0x07, 0x23, 0x01, 0xf4, 0xff, 0x51,
    0x00, 0xf0, 0xff, 0x00, 0xa1, 0xf5, 0x50, 0x31, 0xd2, 0x18, 0x21, 0xf0,
    0x7e, 0x41, 0x12, 0x0f, 0x41, 0xea, 0x02, 0x71, 0x01, 0x22, 0x41, 0xea,
    0x80, 0x01, 0x41, 0xf0, 0x00, 0x70, 0x02, 0x60, 0x70, 0x47, 0xc0, 0x46,
    0x00, 0xe6, 0x0f, 0x40, 0x53, 0x08, 0x27, 0xbf, 0xd0, 0xf8, 0x00, 0x34,
    0x0b, 0x43, 0xd0, 0xf8, 0x00, 0x34, 0x8b, 0x43, 0x92, 0x08, 0xc0, 0xf8,
    0x00, 0x34, 0x27, 0xbf, 0xd0, 0xf8, 0x20, 0x24, 0x11, 0x43, 0xd0, 0xf8,
    0x20, 0x24, 0x22, 0xea, 0x01, 0x01, 0xc0, 0xf8, 0x20, 0x14, 0x70, 0x47,
    0x08, 0x48, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x49, 0x08, 0x68, 0x40, 0xf4,
    0x70, 0x00, 0x08, 0x60, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xf0, 0x1d, 0xf8,
    0x00, 0x20, 0xff, 0xf7, 0x73, 0xff, 0x01, 0x20, 0x00, 0xf0, 0x19, 0xf8,
    0x00, 0x02, 0x00, 0x20, 0x88, 0xed, 0x00, 0xe0, 0x38, 0xb5, 0x01, 0x22,
    0x0c, 0x46, 0x05, 0x46, 0x08, 0x23, 0xff, 0xf7, 0xaf, 0xfe, 0x01, 0x22,
    0x21, 0x46, 0x28, 0x46, 0xff, 0xf7, 0xc8, 0xff, 0x38, 0xbd, 0x40, 0xf8,
    0x21, 0x20, 0x70, 0x47, 0xff, 0xf7, 0xd8, 0xbf, 0x70, 0x47, 0x01, 0x20,
    0x70, 0x47, 0x00, 0xbf, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7
    };
    unsigned int BLINKY_bin_len = 1224;

  • Is it possible to hard code my BLINKY's binary data as hex values in updater function as array and write this values in flash 0x00004000 will this works, I am taking this hex values values from binary using hexdump tool.

    unsigned char BLINKY_bin[] = {
    0x00, 0x02, 0x00, 0x20, 0xb5, 0x44, 0x00, 0x00, 0xc7, 0x44, 0x00, 0x00,
    0xc3, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00, 0xc5, 0x44, 0x00, 0x00,

    No, you can not take the blink.bin as is because the original blink.bin was compiled and linked to start at 0x0, not 0x4000. If you want to have blinky.bin start at 0x4000 then you must rebuild the blinky project and modify the .cmd file so that it is linked to 0x4000. If you look at the boot_demo1 project .cmd file then you will find that the APP_BASE starts at 0x4000. 

    #define APP_BASE 0x00004000
    #define RAM_BASE 0x20000000

    /* System memory map */

    MEMORY
    {
    /* Application stored in and executes from internal flash */
    FLASH (RX) : origin = APP_BASE, length = 0x000fc000
    /* Application uses internal RAM for data */
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000

  • Hi Charles, 

    I have already complied my blinky bin for 0x00004000 only so please tell will this work out, writing binary files hexa value directly to flash will works? I have taken that value by using xxd hexdump tool. 

  • Hi,

      Why don't you first load the modified blinky.out file and view it in the CCS Memory Browser window. See below where I rebuilt blinky to start at 0x4000. As you can see, it is properly programmed to 0x4000 with the SP pointing to 0x20000200 and the Reset Vector pointing to 0x000044B5. 

    Next you can simply just manually force the PC to 0x44B4 and then let it run. Your blinky program is supposed to blink the LED with the program starting at 0x4000. 

    Since you are not using the bootloader but rather your application residing at 0x0 to program another area of the flash, you can use the FlashProgram() API. Refer to below and Peripheral Driver user's guide for details. It will be something like:

    FlashProgram( BLINKY_bin, 0x4000, BLINKY_bin_len);

    If there is already data at 0x4000 then you must first erase the flash using FlashErase() API.

  • Hi Charles, 

    Thanks for the explanation! 

    So please correct me if I am wrong, what your telling is if my current application is stored in flash 0x00000000 and executing, If I am trying to write new blinky binary data into another region of flash using current application, you are telling me to use Flash program api to write my blinky binary hexa data in to flash 0x0000400 instead of using boot loader right? 

    One more thing I can use that hexa data from binary wright? I have taken the hexa values of binary file using hexdump tool! 

    Please share me the link for peripheral driver user guide.

  • So please correct me if I am wrong, what your telling is if my current application is stored in flash 0x00000000 and executing, If I am trying to write new blinky binary data into another region of flash using current application, you are telling me to use Flash program api to write my blinky binary hexa data in to flash 0x0000400 instead of using boot loader right? 

    Yes.

    Please share me the link for peripheral driver user guide.

    You can find it in the TivaWare SDK docs directory or https://www.ti.com/lit/ug/spmu298a/spmu298a.pdf

  • So please correct me if I am wrong, what your telling is if my current application is stored in flash 0x00000000 and executing, If I am trying to write new blinky binary data into another region of flash using current application, you are telling me to use Flash program api to write my blinky binary hexa data in to flash 0x0000400 instead of using boot loader right? 

    Yes.

    Please share me the link for peripheral driver user guide.

    You can find it in the TivaWare SDK docs directory or https://www.ti.com/lit/ug/spmu298a/spmu298a.pdf

  • Hi Charles, 

    Thanks, let me read the document and I will let you know if I am stucked any where. 


    One more Querry, flash and erase is fine how to point new address once copy is done in 0x00004000 for execution? 

  • You can refer to the bl_startup_ccs.s file. You can use the bx r0 instruction to branch to the application entry point. The r0 register will contain the entry point address. In you modified blinky testcase, the r0 register should contain 0x000044B5.

    ;;
    ;; Load the stack pointer from the application's vector table.
    ;;
    .if (APP_START_ADDRESS != VTABLE_START_ADDRESS)
    movw r0, #(APP_START_ADDRESS & 0xffff)
    .if (APP_START_ADDRESS > 0xffff)
    movt r0, #(APP_START_ADDRESS >> 16)
    .endif
    .endif
    ldr sp, [r0]

    ;;
    ;; Load the initial PC from the application's vector table and branch to
    ;; the application's entry point.
    ;;
    ldr r0, [r0, #4]
    bx r0

  • Ok Charles, Let me try this! 

    I can use that attached hexa data array taken from binary file wright? I have taken the hexa values of blinky bin using hexdump tool! I can use that 1224 byte values for flash write?

    Because I am unable to hard code the junk values so only I am using hexa values of binary, for having a trail! 

  • Hi Charles,

    Below is the sample function. Please let me know if this will work. I have taken these hexadecimal values from the Blinky binary, which was compiled for address 0x00004000 using a xxd hexdump tool (xxd -g 4 BLINKY.bin). I am writing them as 32-bit values because the second sector of Flash Memory Bank 0 starts at address 0x00004000 (32-bit).

    int Perform_OTA(void) {


    uint32_t BLINKY_bin[] = {
    0x00020020, 0xb5440000, 0xc7440000, 0xc3440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0x00000000,
    0x00000000, 0x00000000, 0x00000000, 0xc5440000,
    0xc5440000, 0x00000000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0x00000000, 0x00000000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0x00000000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0xc5440000, 0xc5440000, 0xc5440000, 0xc5440000,
    0x2de9f047, 0x84461f46, 0x5648dff8, 0x5491dff8,
    0x58810368, 0x09ea0303, 0x98451bd0, 0x00244ff0,
    0x010a4ff0, 0x030e0afa, 0x04f31942, 0x0fd0dcf8,
    0xc43f6600, 0x0efa06f5, 0xab43ccf8, 0xc43fdcf8,
    0xc45fc2f3, 0x4113b340, 0x2b43ccf8, 0xc43f641c,
    0x082ce8db, 0x530827bf, 0xdcf80035, 0x0b43dcf8,
    0x00358b43, 0xccf80035, 0x930827bf, 0xdcf80435,
    0x0b43dcf8, 0x04358b43, 0xccf80435, 0xd30827bf,
    0xdcf80835, 0x0b43dcf8, 0x08358b43, 0xccf80835,
    0x130927bf, 0xdcf81835, 0x0b43dcf8, 0x18358b43,
    0xccf81835, 0x03684c46, 0x45462340, 0x9d4209d0,
    0x520927bf, 0xdcf83c25, 0x0a43dcf8, 0x3c258a43,
    0xccf83c25, 0x7a0827bf, 0xdcf80c25, 0x0a43dcf8,
    0x0c258a43, 0xccf80c25, 0xba0827bf, 0xdcf81025,
    0x0a43dcf8, 0x10258a43, 0xccf81025, 0xfa0827bf,
    0xdcf81425, 0x0a43dcf8, 0x14258a43, 0xccf81425,
    0x3a0927bf, 0xdcf81c25, 0x0a43dcf8, 0x1c258a43,
    0xccf81c25, 0x00680440, 0xa54214d0, 0xb80a27bf,
    0xdcf84405, 0x0843dcf8, 0x44058843, 0x17f4407f,
    0xccf84405, 0x19bfdcf8, 0x40050843, 0xdcf84005,
    0x8843ccf8, 0x4005002f, 0x19bfdcf8, 0x280520ea,
    0x0101dcf8, 0x28050143, 0xccf82815, 0xbde8f087,
    0x0000ff70, 0x00e00f40, 0x00000510, 0x7cb5154c,
    0x204600f0, 0x49f82046, 0x00f02af8, 0x0028fad0,
    0x114e0121, 0x304600f0, 0x85f8104c, 0x00250121,
    0x30460a46, 0x00f08bf8, 0x00950098, 0x84420cd8,
    0x30460121, 0x2a4600f0, 0x82f80095, 0x00988442,
    0xedd90098, 0x401c0090, 0xf8e70098, 0x401c0090,
    0xebe7c046, 0x0c0800f0, 0x00400640, 0x400d0300,
    0x0c4ac108, 0xc0f30723, 0x01f4ff51, 0x00f0ff00,
    0xa1f53031, 0xd21821f0, 0x7e41120f, 0x41ea0271,
    0x41ea8001, 0x41f00070, 0x01680020, 0x01b10120,
    0x7047c046, 0x00ea0f40, 0x0b4ac108, 0xc0f30723,
    0x01f4ff51, 0x00f0ff00, 0xa1f55031, 0xd21821f0,
    0x7e41120f, 0x41ea0271, 0x012241ea, 0x800141f0,
    0x00700260, 0x7047c046, 0x00e60f40, 0x530827bf,
    0xd0f80034, 0x0b43d0f8, 0x00348b43, 0x9208c0f8,
    0x003427bf, 0xd0f82024, 0x1143d0f8, 0x202422ea,
    0x0101c0f8, 0x20147047, 0x084880f3, 0x08880849,
    0x086840f4, 0x70000860, 0x00bf00bf, 0x00f01df8,
    0x0020fff7, 0x73ff0120, 0x00f019f8, 0x00020020,
    0x88ed00e0, 0x38b50122, 0x0c460546, 0x0823fff7,
    0xaffe0122, 0x21462846, 0xfff7c8ff, 0x38bd40f8,
    0x21207047, 0xfff7d8bf, 0x70470120, 0x704700bf,
    0xfee7fee7, 0xfee7fee7
    };

    uint32_t address = FLASH_START_ADDRESS;

    int32_t result1 = FlashErase(address);

    if (result1 == 0) {
    // Flash block was successfully erased
    } else {
    // Error in erasing flash block
    }

    int32_t result2 = FlashProgram(BLINKY_bin, address, sizeof(BLINKY_bin));

    if (result2 == 0) {
    // Flash programming was successful
    } else {
    // Error in programming flash
    }

    return 0;
    }

    My current application is 11,136 bytes, which is approximately 10.875 KB, and my Blinky application is 1,224 bytes, which is approximately 1.195 KB. So, it should not cause any issues, right? The current application (10 KB) will fit into Bank 0, first sector (0x00000000, 16 KB), and this will not create any issues, right?

    For your refrence I have attached my flash memory bank image below:

  • My current application is 11,136 bytes, which is approximately 10.875 KB, and my Blinky application is 1,224 bytes, which is approximately 1.195 KB. So, it should not cause any issues, right? The current application (10 KB) will fit into Bank 0, first sector (0x00000000, 16 KB), and this will not create any issues, right?

    Your application is less than 0x4000 so should be fine. 

  • Hi Charles, 

    Please confrim for that binary data function.

  • The function looks fine to me. Refer to the example below. 

      

  • Hi Charles, 

    Regarding that hexa value will it works I have taken that from hexdump tool using blinky binary file.

  • I haven't used hexdump but I don't see a problem if you have already compare its output against the expect bin which you can view or dump out of memory browser in CCS. You can do as well in Uniflash.

  • Hi Charles,

    I have verified my modified Blinky binary application (0x00004000) memory address in the memory browser in CCS. The first address (0x00004000) has the value 0x20000200, and the last address (0x000044C4) has the value 0xE7FEE7FE.

    Similarly, I have framed my binary array and correctly written the values to 0x00004000 using my current application running at 0x00000000. However, I received return values of 0 for both the erase and flash APIs. I checked the memory browser after erasing, and the values at 0x00004000 became 0xFFFFFFFF. After writing, the values were correctly placed, similar to the actual Blinky application. The first address (0x00004000) is 0x20000200, and the last address (0x000044C4) is 0xE7FEE7FE.

    I have attached the image below.

    Please help me execute the code from current application 0x00000000, pointing to the new address 0x00004000.

    Blink application 0x00004000:



    My application runs in 0x00000000 and writes values in 0x00004000:


    Below is my current application (0x00000000) startup_ccs.c file please tell me how to modify this current application ccs file to point 0x00004000 address for execution.

    //*****************************************************************************
    //
    // startup_ccs.c - Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2013-2017 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.
    // 
    // This is part of revision 2.1.4.178 of the EK-TM4C1294XL Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // External declaration for the interrupt handler used by the application.
    //
    //*****************************************************************************
    extern void UARTIntHandler(void);
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        UARTIntHandler,                         // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        IntDefaultHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler                       // GPIO Port T
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    
     

    Hi Charles,

    Thanks for the support, 

    Below logic worked for me, once the value is written I am using below line to pointing my code  in main function

    uint32_t app_start_address = 0x00004000;
    uint32_t *vector_table;
    uint32_t stack_pointer, entry_point;

    vector_table = (uint32_t *)app_start_address;

    stack_pointer = vector_table[0];
    __set_MSP(stack_pointer);

    entry_point = vector_table[1];

    ((void (*)(void))entry_point)();

  • Glad that it works for you!

  • Hi Charles,

    I’m facing another issue. My blinky application is working, but I noticed a problem. Every time I power on the board, the code at address 0x00000000 executes first and then calls the code at 0x00004000. How can I overcome this issue?

    I need the code at 0x00004000 to run directly after a successful OTA update, even after a power cycle. Is this possible?

  • Hi Charles,

    This is my function called from main. Please tell me how to boot from 0x00004000 after a power cycle off and on. Is there any API to achieve this? It should not boot from 0x00000000 once OTA is done.


    int Perform_OTA(void) {

    uint32_t BLINKY_bin[] = { -------------Heaxa data---------------};

    uint32_t address = FLASH_START_ADDRESS;

    int32_t result1 = FlashErase(address);

    if (result1 == 0) {

    UART6Write((uint8_t *)"Erase successful\r\n", 16);
    } else {
    UART6Write((uint8_t *)"Erase unsuccessful\r\n", 18);
    }

    int32_t result2 = FlashProgram(BLINKY_bin, address, sizeof(BLINKY_bin));

    if (result2 == 0) {
    UART6Write((uint8_t *)"\r\nFlash successful\r\n\r\n", 20);

    } else {
    UART6Write((uint8_t *)"Flash unsuccessful\r\n", 18);
    }

    uint32_t app_start_address = 0x00004000;
    uint32_t *vector_table;
    uint32_t stack_pointer, entry_point;

    vector_table = (uint32_t *)app_start_address;

    stack_pointer = vector_table[0];
    __set_MSP(stack_pointer);

    entry_point = vector_table[1];

    ((void (*)(void))entry_point)();

    return 0;
    }

  • When the CPU comes out the reset, it  boot from a vector table at address zero. Refer to the Arm Cortex-M4 TRM. https://developer.arm.com/documentation/ka001197/latest/

  • Hi Charles, 

    let me check the document, is there any options to achieve this? 

  • You can change the processor's vector table address. Refer to the device datasheet. You can also refer to the bl_startup file for reference on how to change the vector table address. 

    On system reset, the vector table is fixed at address 0x0000.0000. Privileged software can write to
    the Vector Table Offset (VTABLE) register to relocate the vector table start address to a different

    memory location, in the range 0x0000.0400 to 0x3FFF.FC00 (see “Vector Table” on page 119). Note
    that when configuring the VTABLE register, the offset must be aligned on a 1024-byte boundary.

    Also refer to the Arm TRM on this subject.

    https://developer.arm.com/documentation/107706/0100/Use-case-examples/General-information/What-does-the-program-image-contain-/Relocating-the-vector-table

  • Hi Charles,

    Thanks.

    I have implemented some logic to check if a valid image is present at 0x00004000, My current application should point to it and move the vector table to that new address.

    If a valid image is not found, the OTA process will handle it and point to the new address.

    I have one more query. Why is the boot_demo1 example not executing once I power off and on the board? It is stored in flash at 0x00004000, so why is it not being pointed to after a power cycle? Is it searching for an image at 0x00000000?

  • I have one more query. Why is the boot_demo1 example not executing once I power off and on the board? It is stored in flash at 0x00004000, so why is it not being pointed to after a power cycle? Is it searching for an image at 0x00000000?

    boot_demo1 requires boot_serial (the bootloader) to reside at 0x0. Did you somehow erase the bootloader un-intentionally? You can use the CCS memory browser to view if the bootloader is there at 0x0. After reset, the processor boots from 0x0. If the boot_serial is there, the bootloader will check if the firmware is valid at 0x4000. If a valid firmware is found at 0x4000, then it will jump to 0x4000 to execute the firmware.  Look at the bl_startup file.