AnsweredAssumed Answered

Query on IAP over UART for STM32F072C8

Question asked by sidekick on Nov 27, 2015
Latest reply on Nov 30, 2015 by sidekick
SOC: STM32F072C8 64kB Flash memory
IDE: KEIL uVision5 for windows
Utilities: fromelf.exe (For converting .hex files into .bin file), ST Programmer (for In-circuit programming using SWD interface) and Hyperterminal [1]
Reference document: AN4065 [2]

I'm trying the IAP (In application programming) on STM32F072C8 over UART by following the AN4065. I'm referring the accompanying software (STSW-STM32116) that contains application template and the IAP driver code [1], however since this
 (STSW-STM32116) software is for STM32F051R8 based evaluation board, I cannot use it as it is and I need to change few things to make it work for my target custom board which has STM32F072C8 SOC.

I'm trying to create a similar main flash memory layout, similar to the one mentioned in the application note (AN4065).ie. the bootloader/IAP driver sits in the bottom, followed by application firmware (At the moment, I'm not keeping old copy of
firmware for fallback)

Overall flow of the IAP driver provided in the software bundle is as follows:
1: After a power reset, control gets transferred to IAP driver, the driver then check if a particular button on the evaluation board is pressed or NOT.
2: If the button is pressed, IAP driver then allows to update the application firmware over UART using YMODEM protocol.
3: After a successful application firmware update, a system reboot would once again transfer control to IAP driver.
4: If this time, the button is not pushed, the IAP driver would find the application firmware that we flashed earlier in step 2 above at address 0x0800 3000 and will make a jump to application firmware.
5: Application firmware starts normal execution.

Since I do not have the particular board and at the moment, I'm only trying to evaluate IAP, I made very few changes in the IAP driver to achieve:
A: Application f/w update (IAP)
B: Jump to application f/w

To achieve (A), I commented out the check for button press and the jump to application firmware from the IAP driver code, and flashed this IAP driver, with the following KEIL uVision IDE settings:
Device: STM32F072C8
Target: IROM1::0x08000000(start), 0x3000(size)
Target: IRAM1::0x20000000(start), 0x4000(size)

<snip from scatter file of IAP driver generated by KEIL uVision>
LR_IROM1 0x08000000 0x00003000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00003000  {  ; load address = execution address
    *.o (RESET, +First)
      .ANY (+RO)
  RW_IRAM1 0x20000000 0x00004000  {  ; RW data
    .ANY (+RW +ZI)
<snip from scatter file of IAP driver generated by KEIL uVision>

The IAP driver compiles and flashes fine and I get greeted by the following message on the hyperterminal after a reboot:
=              (C) COPYRIGHT 2012 STMicroelectronics                 =
=                                                                    =
=  STM32F0xx In-Application Programming Application  (Version 1.0.0) =
=                                                                    =
=                                   By MCD Application Team          =

================== Main Menu ============================

Download Image To the STM32F0xx Internal Flash ------- 1

Upload Image From the STM32F0xx Internal Flash ------- 2

Execute The New Program ------------------------------ 3


Here after selecting '1', I use hyperterminal's "Transfer" Tab to send the .bin file (using fromelf.exe that is distributed with KEIL uVision) of the application firmware. note that using a .hex file also works (I don't get any error message, see below)

<snip from hyper terminal, using a .bin file>
Waiting for the file to be sent ... (press 'a' to abort)

Programming Completed Successfully!
Name: app.bin <-- (application f/w)
Size: 3084 Bytes

<snip from hyper terminal, using a .bin file>

I also tried once, using a .hex file instead and the download seemed to work, see below

<snip from hyper terminal, using a .hex file>
Waiting for the file to be sent ... (press 'a' to abort)

Programming Completed Successfully!
Name: app.hex <-- (This is the hex version of the application f/w)
Size: 3177 Bytes
<snip from hyper terminal, using a .hex file>

Now, just to verify, what's in the memory location at 0x0800 3000 (the application start address), I used the debug session in Keil and used the memory window to probe if there is indeed the application was programmed at address 0x0800 3000, but I see 
only 0xff ...... (Seems like, the application was either not programmed or was programmed at some other address, that I do not know at the moment).

KEIL IDE settings for Application f/w is as follows:
Device: STM32F072C8
Target: IROM1::0x8003000(start), 0xD000(size)
Target: IRAM1::0x21000000(start), 0x4000(size)

<snip from scatter file of application f/w (app.sct) generated by KEIL uVision>
LR_IROM1 0x08003000 0x0000D000  {    ; load region size_region
  ER_IROM1 0x08003000 0x0000D000  {  ; load address = execution address
    *.o (RESET, +First)
      .ANY (+RO)
  RW_IRAM1 0x21000000 0x00004000  {  ; RW data
    .ANY (+RW +ZI)
<snip from scatter file of application f/w (app.sct) generated by KEIL uVision>

Note: Keeping IRAM1 start address as 0x20000000 causes compilation error:

".\STM320518_EVAL\STM320518_EVAL.axf: Error: L6971E: system_stm32f0xx.o(.data) type RW incompatible with main.o(.ARM.__AT_0x20000000) type ZI in er RW_IRAM1."

Hence I've chaned the IRAM1 address to 0x21000000 above.

To generate .bin file from .axf file using KEIL fromelf.exe tool that Convert ELF images into other formats for use by ROM tools or for direct loading into memory.
(For more information, refer DUI0459F_02_mdk_fromelf_user_guide from KEIL)
$ /c/Keil_v5/ARM/ARMCC/bin/fromelf.exe --output app.bin STM320518_EVAL.axf

The application f/w code is as below (basically the same binary_template program which is distributed with the software)
<snip from application f/w>
#include "main.h"
#define APPLICATION_ADDRESS     (uint32_t)0x08003000
static __IO uint32_t TimingDelay;
#if   (defined ( __CC_ARM ))
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
#elif defined   (  __GNUC__  )
__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#elif defined ( __TASKING__ )
__IO uint32_t VectorTable[48] __at(0x20000000);
int main(void)
  uint32_t i = 0;
  /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
  /* Copy the vector table from the Flash (mapped at the base of the application
     load address 0x08003000) to the base address of the SRAM at 0x20000000. */
  for(i = 0; i < 48; i++)
    VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
  /* Enable the SYSCFG peripheral clock*/
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  /* Remap SRAM at 0x00000000 */
  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(SystemCoreClock / 1000))
    /* Capture error */
    while (1);
  while (1)
    /* Toggle LED2 and LED4 */
    /* Insert 50 ms delay */
    /* Toggle LED1 and LED3 */
    /* Insert 100 ms delay */
<snip from application f/w>


To summarize:
It seems that there is some problem with flashing the application using IAP over UART in my case, however the message on the Hyper terminal tells that it was flashed successfully. I think this is a configuration issue but I do not know the problem at the moment.

Thank you for your help.