cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723 LWIP TCP with RTOS for custom bootloader not working with some buffer sizes

KEKKO96
Associate II

Hello I have a Nucleo-H723ZG and I'm trying to build a custom bootloader with CMSIS v2 that need a TCP connection. Since it needs to receive 1KB of data through TCP I've made the receive array long 1024 bytes, but this size crashes the whole LWIP making the TCP connection impossible and unable to respond to ping.

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "main.h"
#include "my_tcp.h"


static osThreadId_t my_tcp_task = NULL;
const osThreadAttr_t my_tcp_task_attr = {
		.name = "my_TCP_task",
		.stack_size = 128 * 26, //128 * 26
		.priority = (osPriority_t) osPriorityNormal,
};

uint8_t tcp_received_data[PACKET_SIZE];  //Works only with 1012 instead of 1024
const char go_data = 'Y';
const char stop_data = 'N';

static void my_tcp_task(void *args);

void TCP_init(void) {

	memset(tcp_received_data, 0xFF, sizeof(tcp_received_data)); // I need the buffer to be full of 0xFF

	my_tcp_task = osThreadNew(updater_my_tcp_task, NULL, &tcp_updater_task_attr);

}

static void my_tcp_task(void *args) {

	int sock, updater_sock;
	struct sockaddr_in local_addr, remote_addr;
	int updsock_size;
	int nread;

	// Create a new lwip socket
	sock = lwip_socket(AF_INET, SOCK_STREAM, 0);

	// Set local endpoint parameters
	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(UPDATER_TCP_PORT);
	local_addr.sin_addr.s_addr = INADDR_ANY;

	// Bind socket to local address and port
	lwip_bind(sock, (struct sockaddr*) &local_addr, sizeof(local_addr));

	// Put socket in listening mode
	lwip_listen(sock, 0);

	// Manage connection
	while (1) {
	
		// Wait for connection requests and accept it
		updater_sock = lwip_accept(sock, (struct sockaddr*) &remote_addr, (socklen_t*) &updsock_size);

		while (1) {

			// Receive data from connection
			nread = lwip_read(updater_sock, (void*) (&tcp_received_data), sizeof(tcp_received_data));
			
			if (nread <= 0) {
				break;
			}
			
			//Do things...
			
			}

		}
		lwip_close(updater_sock);
		memset(tcp_received_data, 0xFF, sizeof(tcp_received_data));


	}
}

If PACKET_SIZE is 1024 the LWIP stops working (?) but with 1012 works without any problem.

 

Linker:

/*
******************************************************************************
**
**  File        : LinkerScript.ld
**
**  Author      : STM32CubeIDE
**
**  Abstract    : Linker script for STM32H7 series
**                1024Kbytes FLASH and 560Kbytes RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
  ITCMRAM (xrw)    : ORIGIN = 0x00000000,   LENGTH = 64K
  DTCMRAM (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH    (rx)    : ORIGIN = 0x08000000,   LENGTH = 128K
  RAM_D1  (xrw)    : ORIGIN = 0x24000000,   LENGTH = 320K
  RAM_D2  (xrw)    : ORIGIN = 0x30000000,   LENGTH = 32K
  RAM_D3  (xrw)    : ORIGIN = 0x38000000,   LENGTH = 16K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM_D1 AT> FLASH

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss (NOLOAD):
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    /* ETH_CODE: add placement of RX buffer. STM32H72x/H73x has small D2 RAM, so we need to put it there.
     * (NOLOAD) attribute used for .bss section to avoid linker warning (.bss initialized by startup code)
     */
    . = ALIGN(32);
    *(.Rx_PoolSection)					  
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM_D1

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM_D1

  /* ETH_CODE: add placement of DMA descriptors, rest is used by RX_POOL */
  .lwip_sec (NOLOAD) :
  {
    . = ABSOLUTE(0x30000000);
    *(.RxDecripSection) 
    
    . = ABSOLUTE(0x30000100);
    *(.TxDecripSection)
    
  } >RAM_D2
  
  
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

Can someone help me? Thank you.

 

1 ACCEPTED SOLUTION

Accepted Solutions
STea
ST Employee

Hello @KEKKO96 ,

can you test if it is the case when you use CMISIS V1?

as some similar issue was resolved with version 6.10.0 of cubeMX .
Regards 

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

5 REPLIES 5
STea
ST Employee

Hello @KEKKO96 ,

can you test if it is the case when you use CMISIS V1?

as some similar issue was resolved with version 6.10.0 of cubeMX .
Regards 

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Andrew Neil
Evangelist III

@KEKKO96 wrote:

  crashes the whole LWIP


What, exactly, does that mean?

Does it hang in an error handler? Go to a Hard Fault? Or what??

LwIP debugging: 

https://lwip.fandom.com/wiki/Debugging_lwIP

https://www.nongnu.org/lwip/2_1_x/group__debugging__levels.html

 

 

 

It means the bard is not responding to ping and is not visible on the network.

Hi, unfortunately I can't try with cmsis V1, but I just tried increasing to 1024 the reception array (PACKET_SIZE) and it seems to be working now. Hoping that the new version of cubeMX has solved the problem, I will mark your answer as a solution. Thank you.

AntoR
Associate III

Hello

I have the same problem with a lwip configuration with freeRTOS CMSISv2. Basically as I increase the adc buffer, which is now fixed at 64, the protocol crashes and my nucleo-h723zg is no longer reachable on the network. However, the problem seems to be solved when I followed your suggestion to switch to CMSISv1 and changing lines 993,994 and 1012 from osThreadId_t to osThreadId in ehternetif.c. I would like to know more about this anomaly.
Thanks