cancel
Showing results for 
Search instead for 
Did you mean: 

LoRaWAN FUOTA example migrate to STM32WLE5

meloon
Associate II

 

Hi

I'm trying to migrate and run LoRaWAN FUOTA example on STM32WLE5 custom hardware. I tried to use solution from: https://community.st.com/t5/stm32-mcus-wireless/how-to-migrate-from-stm32wl55-to-stm32wle5/m-p/190815
but replacing STM32WL55JCIX_FLASH.ld file was too complex, because it contains a lot of flash setions related with KMS. I'm not sure if this is needed, because WL55 differs from WLE5 only by extra CM0 core.
Code starts with no issues, connecting to AWS IoT Core, joining multicast group. Problem happened when FUOTA starts and first packet is receiver. Device gets into hard fault, there is "unaligned memory error", when 48-bytes of firmware is coppied to flash memory using LDRD command. It happens because source address is 0x200071EF which is not 8-byte aligned. I fixed that with very simple coppying to another buffer. Now full firmware can be written to flash memory, but update process is still unsuccesfull, there are many flash_write errors and device reboots with an old firmware. I'm still trying to debug what's happening at the end, but maybe someone has tried to run FUOTA on stat uC and have some solution?

unaligned memory fixunaligned memory fixFlash write errorFlash write errorLDRD unaligned memoryLDRD unaligned memory

9 REPLIES 9
VitorBFreitas
Associate II

It seems like you're encountering a similar issue to what I experienced. I observed that this problem occurs only when a fragment is being written across two flash pages. To address it, I resolved the issue by adjusting the fragment sizes to either 64 bytes or 128 bytes in the application server.

You're right, there is a bug when fragment is written across two flash pages, I fixed that in code, there was wrong variable used in checking if flash page is empty. Example code runs on STM32WLE5 (RAK3172SiP actually), but I need few more days to get into code and publish what I've changed to make it works.

VitorBFreitas
Associate II

Great! Please don't forget to share your solution. I'm currently experiencing issues with flash writing the redundancy fragments of FUOTA, and your fix may be of great assistance.

In LoRaWAN_End_Node/Core/Src/flash_if.c
line 156 added code

 

/* USER CODE BEGIN FLASH_IF_Write_1 */
  memcpy(buffer, pSource, uLength);
  //APP_LOG(TS_OFF, VLEVEL_M, "\r\n....   FLASH_IF_WRITE: addr: 0x%x, size: %d\r\n", pDestination, uLength);

  if (IS_FLASH_MAIN_MEM_ADDRESS((uint32_t)pDestination))
  {
    ret_status = FLASH_IF_INT_Write(pDestination, (void *)buffer, uLength);
  }

  return ret_status;

  /* USER CODE END FLASH_IF_Write_1 */

 

 It fixes hard fault "unaligned memory error"

line ~256, changed from

 

 

if (FLASH_IF_INT_IsEmpty(pDestination, length) != FLASH_IF_MEM_EMPTY)

 

to

 

if (FLASH_IF_INT_IsEmpty(uDest, length) != FLASH_IF_MEM_EMPTY)

 

 It fixes writing to flash across two pages, without that change checking if memory is empty was done in previous page, but next page was erased.

line ~280 after 

 

if (FLASH_IF_INT_Erase((void *)page_address, FLASH_PAGE_SIZE) != FLASH_IF_OK)

 

I've added 

 

if(HAL_FLASH_Unlock() != HAL_OK)
{
    ret_status =  -7;
    break;
}

 

It is neccesary, because FLASH_IF_INT_Erase function is locking flash memory, but it has to be unlocked durning FLASH_IF_INT_Write. 
Check that solution, it works on my custom board.

VitorBFreitas
Associate II

Thanks for responding quickly. Unfortunately, these solutions don't address the issue of recovering FUOTA fragments. However, at least now it's possible to send fragments in sizes other than 64 and 128 bytes. :beaming_face_with_smiling_eyes:

Have you tried matching the parameters found in the frag_decoder_if.h file with your LNS?

 

 

#define FRAG_MAX_NB                                 2151
/*!
  * Maximum number of extra frames that can be handled.
  *
  * \remark This parameter has an impact on the memory footprint.
  * \note FRAG_MAX_NB * 0.10 (with redundancy = 10 %)
  */
#define FRAG_MAX_REDUNDANCY                         216

 

If you're using AWS, you can modify the size of the fragments and the redundancy percentage. By default is 50%, I set it to 10 in order to match the configuration of the FW. 

I'm trying to get FUOTA done using FW_WL_V1.3.0, stmcubeide 1.12.1 in the EU868 band but still having a hardfault interrupt. Fragment size of 64B. 

@meloon thank you for this post!

I'm having the same problem as you, a hardfault interrupt but I'm using the nucleo-wl55 board. Once I get it run, I move to the RAK3172. 

Which version of the FW_WL_Vx.x.x are you using? I'm using FW_WL_V1.3.0 but no success. The nucleo stops after receiving the first fragment. 

Did you have to modify anything else in the FUOTA project? 

Yes, I'm using AWS and tried to match the parameters; unfortunately, it doesn't work. I identified the issue as being caused by the end-device continually receiving redundant fragments even when it has already filled all the firmware image gaps. Consequently, it attempts to write the exceeding fragments into flash memory, but since the address has already been written, it erases the page it's trying to write. For now, I'm working around it by locking the write to already written addresses when it starts receiving redundant fragments.

I;m using WL_V1.3.0. Your problem sounds like you have a hardfault related with "unaligned memory error". Check if that change in LoRaWAN_End_Node/Core/Src/flash_if.c wll help:

 

static uint8_t buffer[400];

FLASH_IF_StatusTypedef FLASH_IF_Write(void *pDestination, const void *pSource, uint32_t uLength)
{
  FLASH_IF_StatusTypedef ret_status = FLASH_IF_ERROR;
  /* USER CODE BEGIN FLASH_IF_Write_1 */
  memcpy(buffer, pSource, uLength);

  if (IS_FLASH_MAIN_MEM_ADDRESS((uint32_t)pDestination))
  {
	  ret_status = FLASH_IF_INT_Write(pDestination, (void *)buffer, uLength);
  }

  return ret_status;
  /* USER CODE END FLASH_IF_Write_1 */
  if (IS_FLASH_MAIN_MEM_ADDRESS((uint32_t)pDestination))
  {
    ret_status = FLASH_IF_INT_Write(pDestination, pSource, uLength);
  }
  /* USER CODE BEGIN FLASH_IF_Write_2 */

  /* USER CODE END FLASH_IF_Write_2 */
  return ret_status;
}

 

 I didn't change FRAG_MAX_REDUNDANCY parameter, 10% is enough. FUOTA example takes a lot off FLASH memory, there is only a few kB left.