AnsweredAssumed Answered

Flash and jump to code

Question asked by Luke on Mar 9, 2016
Latest reply on Mar 9, 2016 by Clive One
I am constructing a program on the STM32F030 and am trying to flash a small segment of code to an available area of flash and them executing it. Although I can get a whole bootloader to work from examples, this is not the solution I am after - all I want to do is flash a method that can be called from my main program and returns a value (using the same stack, heap, etc). Unfortunately though after I flash and try to jump to the code my program is hard faulting and I can't figure out what's going on. I tried to adapt some code I found on these forums but it still faults. My code is something like the following:

#define APPLICATION_ADDRESS     (uint32_t)0x08003000
typedef int (*pFunction)(void);


uint32_t FLASH_If_Erase(uint32_t StartSector) {
  uint32_t flashaddress;

  flashaddress = StartSector;
  while (flashaddress <= (uint32_t) USER_FLASH_LAST_PAGE_ADDRESS)
  {
    if (FLASH_ErasePage(flashaddress) == FLASH_COMPLETE)
    {
      flashaddress += FLASH_PAGE_SIZE;
    }
    else
    {
      /* Error occurred while page erase */
      return (1);
    }
  }
  return (0);
}

uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data, uint16_t DataLength) {
  uint32_t i = 0;

  for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++)
  {
    /* the operation will be done by word */
    if (FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i)) == FLASH_COMPLETE)
    {
     /* Check the written value */
      if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))
      {
        /* Flash content doesn't match SRAM content */
        return(2);
      }
      /* Increment FLASH destination address */
      *FlashAddress += 4;
    }
    else
    {
      /* Error occurred while writing data in Flash memory */
      return (1);
    }
  }
  return (0);
}

void run() {
  FLASH_Unlock();     // Unlock the Program memory
  FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);   // Clear all FLASH flags

static const uint16_t code[] = { 0xF04F, 0x007B, 0x4770, 0x0000 }; // payload

     int16_t size = 2;          // Size of code in words
     uint32_t flashdestination = APPLICATION_ADDRESS;
     uint32_t ramsource = (uint32_t)code;


    FLASH_If_Erase(APPLICATION_ADDRESS);
    if (FLASH_If_Write(&flashdestination, (uint32_t*)ramsource, size)  == 0) {
         uart_print("Flash success\n\r");
     pFunction RunCode;
     uint8_t *Buffer = (uint8_t *)APPLICATION_ADDRESS;
     RunCode = (pFunction)&Buffer[1]; // +1 for Thumb code
     uint32_t v = RunCode();   // Hard fault occurs here...
   }
    else {
         uart_print("Flash failed\n\r");
    }
}


Thoughts?

Outcomes