I'm using a Raspberry Pi to transmit Ethernet data, and a development board (rt1170 evk) to receive it and perform inference using TensorFlow Lite. The Ethernet UDP data is received using lwIP in C, while TensorFlow Lite is used in C++.
When running the code in the lwIP-based project, everything works fine. The Raspberry Pi sends UDP packets, and the receive callback function shows the received data correctly.
However, after creating a C++-based eIQ project to use TensorFlow Lite, the same code no longer works. The build completes successfully and a binary file is generated. But when the code is executed, it fails to receive packets from the Raspberry Pi, and even ping does not work.
I am not sure if this is a project-related issue or if there are some configurations that I am missing. Any help would be appreciated.
Please let me know if you need more information.
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "lwip/opt.h"
#if LWIP_IPV4
extern "C"{
#include "lwip/timeouts.h"
#include "lwip/ip_addr.h"
#include "lwip/init.h"
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#include "netif/ethernet.h"
#include "ethernetif.h"
#include "fsl_enet.h"
#include "lwip/opt.h"
#include "lwip/arch.h"
#include "lwip/api.h"
#include "lwip/raw.h"
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/tcpip.h"
#include "netif/etharp.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/mem.h"
#include "lwip/sys.h"
#include "lwip/udp.h"
#include "lwip/priv/tcp_priv.h"
#ifndef configMAC_ADDR
#include "fsl_silicon_id.h"
#endif
#include "fsl_phy.h"
#include "pin_mux.h"
#include "board.h"
#if BOARD_NETWORK_USE_100M_ENET_PORT
#include "fsl_phyksz8081.h"
#else
#include "fsl_phyrtl8211f.h"
#endif
}
static struct raw_pcb *raw_pcb;
static struct udp_pcb *udp_client_pcb;
static struct udp_pcb *udp_server_pcb;
static ip_addr_t udp_server_ip;
static int send_count = 0;
#define MAX_MESSAGES 10
/* @test_ANCHOR */
/* IP address configuration. */
#define configIP_ADDR0 192
#define configIP_ADDR1 168
#define configIP_ADDR2 1
#define configIP_ADDR3 10
/* Netmask configuration. */
#define configNET_MASK0 255
#define configNET_MASK1 255
#define configNET_MASK2 255
#define configNET_MASK3 0
/* Gateway address configuration. */
#define configGW_ADDR0 192
#define configGW_ADDR1 168
#define configGW_ADDR2 1
#define configGW_ADDR3 1
#if BOARD_NETWORK_USE_100M_ENET_PORT
extern phy_ksz8081_resource_t g_phy_resource;
#define EXAMPLE_ENET ENET
/* Address of PHY interface. */
#define EXAMPLE_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS
/* PHY operations. */
#define EXAMPLE_PHY_OPS &phyksz8081_ops
/* ENET instance select. */
#define EXAMPLE_NETIF_INIT_FN ethernetif0_init
#else
extern phy_rtl8211f_resource_t g_phy_resource;
#define EXAMPLE_ENET ENET_1G
/* Address of PHY interface. */
#define EXAMPLE_PHY_ADDRESS BOARD_ENET1_PHY_ADDRESS
/* PHY operations. */
#define EXAMPLE_PHY_OPS &phyrtl8211f_ops
/* ENET instance select. */
#define EXAMPLE_NETIF_INIT_FN ethernetif1_init
#endif
/* PHY resource. */
#define EXAMPLE_PHY_RESOURCE &g_phy_resource
/*******************************************************************************
* Prototypes
******************************************************************************/
extern "C"{
void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
void set_static_ip(struct netif *netif);
void udp_client_init(void);
void udp_send_hello(void);
static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr);
void ping_init(void);
}
/*******************************************************************************
* Variables
******************************************************************************/
#if BOARD_NETWORK_USE_100M_ENET_PORT
phy_ksz8081_resource_t g_phy_resource;
#else
phy_rtl8211f_resource_t g_phy_resource;
#endif
static phy_handle_t phyHandle;
/*******************************************************************************
* Code
******************************************************************************/
/* ENET clock frequency. */
#define EXAMPLE_CLOCK_FREQ CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)
void BOARD_InitModuleClock(void) {
const clock_sys_pll1_config_t sysPll1Config = {.pllDiv2En = true};
CLOCK_InitSysPll1(&sysPll1Config);
#if BOARD_NETWORK_USE_100M_ENET_PORT
clock_root_config_t rootCfg = {.mux = 4, .div = 10}; /* Generate 50M root clock. */
CLOCK_SetRootClock(kCLOCK_Root_Enet1, &rootCfg);
#else
clock_root_config_t rootCfg = {.mux = 4, .div = 4}; /* Generate 125M root clock. */
CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg);
#endif
}
void IOMUXC_SelectENETClock(void) {
#if BOARD_NETWORK_USE_100M_ENET_PORT
IOMUXC_GPR->GPR4 |= IOMUXC_GPR_GPR4_ENET_REF_CLK_DIR_MASK; /* 50M ENET_REF_CLOCK output to PHY and ENET module. */
#else
IOMUXC_GPR->GPR5 |= IOMUXC_GPR_GPR5_ENET1G_RGMII_EN_MASK; /* bit1:iomuxc_gpr_enet_clk_dir
bit0:GPR_ENET_TX_CLK_SEL(internal or OSC) */
#endif
}
void BOARD_ENETFlexibleConfigure(enet_config_t *config) {
#if BOARD_NETWORK_USE_100M_ENET_PORT
config->miiMode = kENET_RmiiMode;
#else
config->miiMode = kENET_RgmiiMode;
#endif
}
void MDIO_Init(void) {
(void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(EXAMPLE_ENET)]);
ENET_SetSMI(EXAMPLE_ENET, EXAMPLE_CLOCK_FREQ, false);
}
status_t MDIO_Write(uint8_t phyAddr, uint8_t regAddr, uint16_t data) {
return ENET_MDIOWrite(EXAMPLE_ENET, phyAddr, regAddr, data);
}
status_t MDIO_Read(uint8_t phyAddr, uint8_t regAddr, uint16_t *pData) {
return ENET_MDIORead(EXAMPLE_ENET, phyAddr, regAddr, pData);
}
void SysTick_Handler(void) {
time_isr();
}
/* IP, Netmask, Gateway Configuration */
#define configIP_ADDR "192.168.1.10"
#define configNET_MASK "255.255.255.0"
#define configGW_ADDR "192.168.1.1"
/* Setup static IP configuration */
void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
if (p != NULL) {
// PRINTF( p->len);
for (int i = 0; i < p->len; i++) {
PRINTF("%02X ", ((uint8_t *)p->payload)[i]);
}
PRINTF("Received UDP packet from IP %s and port %d\n", ipaddr_ntoa(addr), port);
PRINTF("Data: %s\n", (char *)p->payload); // Assuming payload is a null-terminated string
// Here, you would add your processing logic for the received data
// Free the packet buffer
pbuf_free(p);
}
}
void set_static_ip(struct netif *netif) {
ip4_addr_t ipaddr, netmask, gw;
ip4addr_aton(configIP_ADDR, &ipaddr);
ip4addr_aton(configNET_MASK, &netmask);
ip4addr_aton(configGW_ADDR, &gw);
netif_set_down(netif);
netif_set_addr(netif, &ipaddr, &netmask, &gw);
netif_set_up(netif);
PRINTF("Static IP Address Assigned: %s\n", ip4addr_ntoa(&ipaddr));
}
/* Initialize UDP client */
void udp_client_init(void) {
udp_client_pcb = udp_new();
if (udp_client_pcb == NULL) {
PRINTF("Failed to create UDP PCB.\n");
return;
}
ip4addr_aton("192.168.1.80", &udp_server_ip); // Configure the server IP address
udp_bind(udp_client_pcb, IP4_ADDR_ANY, 1234); // Bind to any IP and port
udp_recv(udp_client_pcb, udp_receive_callback, NULL);
PRINTF("UDP Client initialized and bound to port.\n");
//udp_send_hello();
}
void udp_send_hello(void) {
if (send_count >= MAX_MESSAGES) {
PRINTF("Sent 'Hello UDP' %d times, stopping now.\n", MAX_MESSAGES);
return;
}
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, strlen("Hello UDP") + 1, PBUF_RAM);
if (p != NULL) {
memcpy(p->payload, "Hello UDP", strlen("Hello UDP") + 1);
udp_sendto(udp_client_pcb, p, &udp_server_ip, 1234);
pbuf_free(p);
PRINTF("Sent 'Hello UDP'\n");
send_count++;
}
sys_timeout(1000, (sys_timeout_handler)udp_send_hello, NULL); // Schedule next send in 1 second
}
static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) {
struct pbuf *q;
struct icmp_echo_hdr *iecho;
if (pbuf_header(p, -PBUF_IP_HLEN) == 0) {
iecho = (struct icmp_echo_hdr *)p->payload;
if (iecho->type == ICMP_ER) {
PRINTF("Received PING response from %s\n", ipaddr_ntoa(addr));
} else if (iecho->type == ICMP_ECHO) {
PRINTF("Received PING request from %s\n", ipaddr_ntoa(addr));
// Create a response packet
iecho->type = ICMP_ER;
iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
raw_sendto(pcb, p, addr);
PRINTF("Sent PING response to %s\n", ipaddr_ntoa(addr));
}
}
pbuf_free(p);
return 1;
}
void ping_init(void) {
raw_pcb = raw_new(IP_PROTO_ICMP);
if (raw_pcb != NULL) {
raw_recv(raw_pcb, ping_recv, NULL);
raw_bind(raw_pcb, IP_ADDR_ANY);
}
}
int main(void) {
struct netif netif;
ip4_addr_t ipaddr, netmask, gw;
static int send_count = 0;
IP4_ADDR(&ipaddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3);
IP4_ADDR(&netmask, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3);
IP4_ADDR(&gw, configGW_ADDR0, configGW_ADDR1, configGW_ADDR2, configGW_ADDR3);
ethernetif_config_t enet_config = {.phyHandle = &phyHandle,
.phyAddr = EXAMPLE_PHY_ADDRESS,
.phyOps = EXAMPLE_PHY_OPS,
.phyResource = EXAMPLE_PHY_RESOURCE,
#ifdef configMAC_ADDR
.macAddress = configMAC_ADDR
#endif
};
gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitModuleClock();
IOMUXC_SelectENETClock();
#if BOARD_NETWORK_USE_100M_ENET_PORT
BOARD_InitEnetPins();
GPIO_PinInit(GPIO12, 12, &gpio_config);
GPIO_WritePinOutput(GPIO12, 12, 0);
SDK_DelayAtLeastUs(10000, CLOCK_GetFreq(kCLOCK_CpuClk));
GPIO_WritePinOutput(GPIO12, 12, 1);
SDK_DelayAtLeastUs(6, CLOCK_GetFreq(kCLOCK_CpuClk));
#else
BOARD_InitEnet1GPins();
GPIO_PinInit(GPIO11, 14, &gpio_config);
GPIO_WritePinOutput(GPIO11, 14, 0);
SDK_DelayAtLeastUs(10000, CLOCK_GetFreq(kCLOCK_CpuClk));
GPIO_WritePinOutput(GPIO11, 14, 1);
SDK_DelayAtLeastUs(30000, CLOCK_GetFreq(kCLOCK_CpuClk));
#endif
MDIO_Init();
g_phy_resource.read = MDIO_Read;
g_phy_resource.write = MDIO_Write;
time_init();
#ifndef configMAC_ADDR
(void)SILICONID_ConvertToMacAddr(&enet_config.macAddress);
#endif
enet_config.srcClockHz = EXAMPLE_CLOCK_FREQ;
lwip_init();
if (netif_add(&netif, NULL, NULL, NULL, &enet_config, EXAMPLE_NETIF_INIT_FN, ethernet_input) == NULL) {
PRINTF("Netif add failed\n");
return 1;
}
PRINTF("Network initialized, configuring static IP\n");
IP4_ADDR(&ipaddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3);
IP4_ADDR(&netmask, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3);
IP4_ADDR(&gw, configGW_ADDR0, configGW_ADDR1, configGW_ADDR2, configGW_ADDR3);
PRINTF("Network initialized, configuring static IP\n");
//netif_add(&netif, NULL, NULL, NULL, NULL, EXAMPLE_NETIF_INIT_FN, tcp_input);
netif_set_default(&netif);
set_static_ip(&netif);
netif_set_up(&netif);
PRINTF("\r\n************************************************\r\n");
PRINTF("Static IP configuration example\r\n");
PRINTF("************************************************\r\n");
PRINTF("Hello, World!\n");
ping_init(); // Initialize PING reception
udp_client_init();
PRINTF("Starting UDP client\n");
while (1) {
ethernetif_input(&netif);
sys_check_timeouts();
}
}
#endif
Hi @kibeom
"When running the code in the lwIP-based project, everything works fine.”, “However, after creating a C++-based eIQ project to use TensorFlow Lite, the same code no longer works.."
Thanks for your questions, it is confused by the same code but no longer works. I have tried to understand the problem, but still need more clarification. If possbile, would you please help provide the below info to me, I will send you mail for private channle if needed.
[Hardware]: RT1170 EVK + Raspberry Pi
[Software]: SDK example/version?
[How to reproduce]:
B.R, Sam