Skip to main content
Explorer II
June 12, 2024
Question

FreeRTOS + LWIP + UDP

  • June 12, 2024
  • 1 reply
  • 2002 views

I'm trying to achieve a UDP communication with STM32H753IIT6 and LAN8720A.

I use STM32CubeIDE 1.14.0.

According to the ST Ethernet and LwIP  example:   Adam BERLINGER edited on ‎2023-12-07 , I create a project, and change the pin layout according to my PCB design. 

In the .ioc, I set the ip addrass as  192.168.0.10 and I did the other things described in the ST example, except for

"(Optional) Adding simple Hello UDP message" . 

Everything's fine at this point : I can ping 192.168.0.10 and get replies.Hamaos_0-1718185156794.png 

Then I want to send some simple Hello UDP messages as the ST Ethernet and LwIP  example describe.

However, after I Modify the StartDefaultTask in main.c , I can't ping the device and get some debug information from uart : 

Hamaos_1-1718185655716.png

Hamaos_0-1718186299828.png

How to deal with "core lock " in the debug information ?

 

This is the StartDefaultTask code modifyied: 

 

 

 

void StartDefaultTask(void *argument)

{

/* init code for LWIP */

 MX_LWIP_Init();



/* USER CODE BEGIN StartDefaultTask */

const char* message = "Hello UDP message!\n\r";

osDelay(1000);

ip_addr_t PC_IPADDR;

 IP_ADDR4(&PC_IPADDR, 192, 168, 0, 1);

struct udp_pcb* my_udp = udp_new();

 udp_connect(my_udp, &PC_IPADDR, 55151);

struct pbuf* udp_buffer = NULL;

/* Infinite loop */

for (;;) {

 osDelay(1000);

/* !! PBUF_RAM is critical for correct operation !! */

 udp_buffer = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM);



if (udp_buffer != NULL) {

memcpy(udp_buffer->payload, message, strlen(message));

 udp_send(my_udp, udp_buffer);

 pbuf_free(udp_buffer);

 }

 }

/* USER CODE END StartDefaultTask */

}

 

 

 

 

 

 

 

@Adam BERLINGER

 

    This topic has been closed for replies.

    1 reply

    ST Employee
    June 21, 2024

    Hello @Hamaos ,

    Try to add the following:

    LOCK_TCPIP_CORE(); after MX_LWIP_Init(); in the default task.
    UNLOCK_TCPIP_CORE(); before your for loop 

    these macros and prototypes are for proper multithreading support
    add in your ethernetif.c the following:

    #undef LWIP_PROVIDE_ERRNO
    #define LWIP_ERRNO_STDINCLUDE
    
    /* ETH_CODE: macro and prototypes for proper (hopefuly?)
     * multithreading support
     */
    #define LOCK_TCPIP_CORE sys_lock_tcpip_core
    #define UNLOCK_TCPIP_CORE sys_unlock_tcpip_core
    
    #define LWIP_ASSERT_CORE_LOCKED sys_check_core_locking
    #define LWIP_MARK_TCPIP_THREAD sys_mark_tcpip_thread
    
    void sys_lock_tcpip_core(void);
    void sys_unlock_tcpip_core(void);
    
    void sys_check_core_locking(void);
    void sys_mark_tcpip_thread(void);
    and:
    /* ETH_CODE: add functions needed for proper multithreading support and check */
    
    static osThreadId_t lwip_core_lock_holder_thread_id;
    static osThreadId_t lwip_tcpip_thread_id;
    
    void sys_lock_tcpip_core(void){
    	sys_mutex_lock(&lock_tcpip_core);
    	lwip_core_lock_holder_thread_id = osThreadGetId();
    }
    
    void sys_unlock_tcpip_core(void){
    	lwip_core_lock_holder_thread_id = 0;
    	sys_mutex_unlock(&lock_tcpip_core);
    }
    
    void sys_check_core_locking(void){
     /* Embedded systems should check we are NOT in an interrupt context here */
    
     LWIP_ASSERT("Function called from interrupt context", (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) == 0);
    
     if (lwip_tcpip_thread_id != 0) {
    	 osThreadId_t current_thread_id = osThreadGetId();
    
    #if LWIP_TCPIP_CORE_LOCKING
    	LWIP_ASSERT("Function called without core lock", current_thread_id == lwip_core_lock_holder_thread_id);
    	/* ETH_CODE: to easily check that example has correct handling of core lock
    	 * This will trigger breakpoint (__BKPT)
    	 */
    #warning Below check should be removed in production code
    	if(current_thread_id != lwip_core_lock_holder_thread_id) __BKPT(0);
    #else /* LWIP_TCPIP_CORE_LOCKING */
    	LWIP_ASSERT("Function called from wrong thread", current_thread_id == lwip_tcpip_thread_id);
    #endif /* LWIP_TCPIP_CORE_LOCKING */
    	LWIP_UNUSED_ARG(current_thread_id); /* for LWIP_NOASSERT */
     }
    }
    void sys_mark_tcpip_thread(void){
    	lwip_tcpip_thread_id = osThreadGetId();
    }

    Hope this helps you.

    Regards