cancel
Showing results for 
Search instead for 
Did you mean: 

hi i am using nucleol073rz board , trying the IAP xmodem usart example , not able to load bin file more than 15KB cant find the problem or understand why ? whereas for code less than 15KB it is working.

svii
Associate III

Below is the code snippets , not able to debug as well i suspect the flash is not able to erase completely need some advice on this .

https://github.com/ferenc-nemeth/stm32-bootloader

//////////////////////////////////flash operation////////////////////////////////////////////

flash_status flash_erase(uint32_t address)

{

 HAL_FLASH_Unlock();

 flash_status status = FLASH_ERROR;

 FLASH_EraseInitTypeDef erase_init;

 uint32_t error = 0u;

 erase_init.TypeErase = FLASH_TYPEERASE_PAGES;

 erase_init.PageAddress = address;

 /* Calculate the number of pages from "address" and the end of flash. */

 erase_init.NbPages = ((FLASH_APP_END_ADDRESS - address) / FLASH_PAGE_SIZE);    

 /* Do the actual erasing. */

 if (HAL_OK == HAL_FLASHEx_Erase(&erase_init, &error))

 {

  status = FLASH_OK;

 }

 HAL_FLASH_Lock();

 return status;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

flash_status flash_write(uint32_t address, uint32_t *data, uint32_t length)

{

 flash_status status = FLASH_OK;

 HAL_FLASH_Unlock();

 /* Loop through the array. */

 for (uint32_t i = 0u; (i < length) && (FLASH_OK == status); i++)

 {

  /* If we reached the end of the memory, then report an error and don't do anything else.*/

  if (FLASH_APP_END_ADDRESS <= address)

  {

   status |= FLASH_ERROR_SIZE;

  }

  else

  {

   /* The actual flashing. If there is an error, then report it. */

   if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data[i]))

   {

    status |= FLASH_ERROR_WRITE;

   }

   /* Read back the content of the memory. If it is wrong, then report an error. */

   if (((data[i])) != (*(volatile uint32_t*)address))

   {

    status |= FLASH_ERROR_READBACK;

   }

   /* Shift the address by a word. */

   address += 4u;

  }

 }

 HAL_FLASH_Lock();

 return status;

}

////////////////////////////////////////////////////////////////////////////////////

#define FLASH_APP_START_ADDRESS ((uint32_t)0x08008000u)

#define FLASH_APP_END_ADDRESS  ((uint32_t)0x08030000u)    

//////////////////////////////////////////////////////////////////////////////////

void xmodem_receive(void)

{

 volatile xmodem_status status = X_OK;

 uint8_t error_number = 0u;

 x_first_packet_received = false;

 xmodem_packet_number = 1u;

 xmodem_actual_flash_address = FLASH_APP_START_ADDRESS;

 /* Loop until there isn't any error (or until we jump to the user application). */

 while (X_OK == status)

 {

  uint8_t header = 0x00u;

  /* Get the header from UART. */

  uart_status comm_status = uart_receive(&header, 1u);

  /* Spam the host (until we receive something) with ACSII "C", to notify it, we want to use CRC-16. */

  if ((UART_OK != comm_status) && (false == x_first_packet_received))

  {

   (void)uart_transmit_ch(X_C);

  }

  /* Uart timeout or any other errors. */

  else if ((UART_OK != comm_status) && (true == x_first_packet_received))

  {

   status = xmodem_error_handler(&error_number, X_MAX_ERRORS);

  }

  else

  {

   /* Do nothing. */

  }

  /* The header can be: SOH, STX, EOT and CAN. */

  switch(header)

  {

   xmodem_status packet_status = X_ERROR;

   /* 128 or 1024 bytes of data. */

   case X_SOH:

   case X_STX:

    /* If the handling was successful, then send an ACK. */

    packet_status = xmodem_handle_packet(header);

    if (X_OK == packet_status)

    {

     (void)uart_transmit_ch(X_ACK);

    }

    /* If the error was flash related, then immediately set the error counter to max (graceful abort). */

    else if (X_ERROR_FLASH == packet_status)

    {

     error_number = X_MAX_ERRORS;

     status = xmodem_error_handler(&error_number, X_MAX_ERRORS);

    }

    /* Error while processing the packet, either send a NAK or do graceful abort. */

    else

    {

     status = xmodem_error_handler(&error_number, X_MAX_ERRORS);

    }

    break;

   /* End of Transmission. */

   case X_EOT:

    /* ACK, feedback to user (as a text), then jump to user application. */

    (void)uart_transmit_ch(X_ACK);

    (void)uart_transmit_str((uint8_t*)"\n\rFirmware updated!\n\r");

    (void)uart_transmit_str((uint8_t*)"Jumping to user application...\n\r");

    flash_jump_to_app();

    break;

   /* Abort from host. */

   case X_CAN:

    status = X_ERROR;

    break;

   default:

    /* Wrong header. */

    if (UART_OK == comm_status)

    {

     status = xmodem_error_handler(&error_number, X_MAX_ERRORS);

    }

    break;

  }

 }

}

//////////////////////////////////////////////////////////////////////////////////////////

please let me know how to remove the 15kB limit.Thanks in advance.

7 REPLIES 7

What are you using to send data?

Using XMODEM-1K ?​

Does the sending software fail or report an error?​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Using teraterm4.85version ,xmodem-1k configuration. When sending a 40kb .bin file the console sends only 38% and hangs ,after which the software waits to receive a file again,this behaviour is consistent all the time,whereas for smaller files lesser than 10kb the software is successful.​

Ok, so presuming you're not the author of the code..

>>..not able to debug as well i suspect the flash is not able to erase completely need some advice on this

You're going to have to add instrumentation (not breakpoints, not single step) to understand the flow, and error/failure conditions.

Using X-MODEM here to do transfers/updates of several 100KB, although using code we wrote/tested ourselves.

At 128-byte packets the 8-bit block count wraps at 32KB.

Watch for resends of the same packet.

The CRC computation could be done significantly faster, I'd watch for timeout issues related to CRC+FLASH to ACK.

Writing, or Erasing Flash whilst executing from flash will cause significant stalling, and overrun data loss if UART peripheral can not be serviced promptly.

Erase here seems to specify the right span, the upper limit seems high enough, make sure the compiler builds all components with the same understanding of FLASH_APP_END_ADDRESS

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dimmykar
Associate II

I have a similar problem with this snippet on my STM32L071CB... I use my flash and USART drivers, but the xmodem module from this snippet is similar in my project. I've tried Tera Term on Windows, tried `sx -kO` with screen or picocom on Linux (-O option disables all timeouts), and also a self-written python-script. Sometimes the 55Kb firmware is transferred successfully and the firmware is installed correctly, but in most cases after the 4th packet (3kb received successfully) all the utilities start sending some kind of garbage... I can't understand the reason why the PC utilities start sending something different from the protocol. This garbage is also not a part of the sending firmware

I am attaching the output of the logic analyzer. Red is what the STM32 sends, yellow is what the utility sends. Byte 0x06 - ACK, byte 0x15 - NAK via XMODEM protocol. The first byte in the packet must be 0x01 or 0x02, not 0xFF or anything.

0693W00000KdaZoQAJ.png0693W00000Kdaa3QAB.png

dimmykar
Associate II

I could say that it is interference on the USART line, but I don't think so. Absolutely always the problem occurs on the 4th packet

The USART baudrate is set to 115200

Seems highly improbable that multiple independent utilities would send junk.

Be aware that the STM32's typically stall real-time execution when writing/erasing flash, this will break interrupts and peripheral service.

The ACK should only be sent after the packet has been checksummed AND written to flash memory, so it acts properly in terms of controlling flow. If the USART is managed/buffered under interrupt, or the flash operations differed into another thread, you're likely to get headaches.

Instrument so you can understand dynamic flow without using a debugger, which will further interfere with the operation of the core, can be invasive.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you for your response!

My USART and FLASH routines are blocking, I don't work with interrupts in this case.

I don't understand why STM32 is to blame. The output in the screenshots is from a logic analyzer, so this is exactly what is happening on the USART bus. The screenshot shows that as soon as the STM32 sends an ACK, the utility sends 0xFF, 0xFC, and so on, which should not happen via the XMODEM-1k protocol. And the USART of the microcontroller should not be to blame here.

The XModem in this snippet is implemented so that a 'C' byte is sent when the firmware is run, until the PC utility starts sending packets. Next, the first byte is checked: if it is 0x00 (SOH) or 0x01 (STX), then the entire packet is received depending on the length - 128 or 1024 bytes, after that the CRC-16 of the packet is calculated, the packet number and CRC are checked and then Flash programming is performed. If this is the first packet, then the STM32 is erased before programming. After completing operations with Flash, the microcontroller sends an ACK and so on until the EOT byte is received. In case of errors, 5 attempts are allowed (NACK is sent), after which the transaction ends with CAN abortion