MDK TCP server

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MDK TCP server

955 Views
MikeHazma
Contributor I
I`m writing ethernet TCP server program using CMSIS and MDK-Plus Network.
 
At first, I copied the sample program "cmsis_enet_txrx_transfer.c" to open the ethernet PHY .
And then I combined the TCP server sample code to it. (The sample code link below)
file:///C:/Keil_v5/ARM/PACK/Keil/MDK-Middleware/7.10.0/Doc/Network/html/group__tcp__user__api.html#ga9c559a5589c9476028adde1f8e509624
 
The code I wrote is in below.
The board I'm using is NXP MIMXRT1170-EVKB.
 
 
/*
 * Copyright 2017-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
 
/*  Standard C Included Files */
#include <string.h>
/*  SDK Included Files */
#include "Driver_ETH_MAC.h"
#include "pin_mux.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_enet.h"
#include "fsl_enet_cmsis.h"
#include "fsl_enet_phy_cmsis.h"
#include "fsl_phy.h"
#include "stdlib.h"
#include "fsl_silicon_id.h"
 
#include "fsl_phyrtl8211f.h"
 
#include "rl_net_lib.h"
#include "Net_Config_ETH_0.h"
 
/* TCP Server */
#include "rl_net.h"
 
#include "RTE_Components.h"
#include  CMSIS_device_header
#include "cmsis_os2.h"
 
 
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define EXAMPLE_ENET     Driver_ETH_MAC0
#define EXAMPLE_ENET_PHY Driver_ETH_PHY0
#define ENET_DATA_LENGTH        (1000)
#define ENET_EXAMPLE_LOOP_COUNT (20U)
 
/* @test_ANCHOR*/
 
#ifndef MAC_ADDRESS
#define MAC_ADDRESS                        \
    {                                      \
        0x54, 0x27, 0x8d, 0x00, 0x00, 0x00 \
    }
#else
#define USER_DEFINED_MAC_ADDRESS
#endif
 
/*******************************************************************************
 * Prototypes
 ******************************************************************************/
 
/*******************************************************************************
 * Variables
 ******************************************************************************/
cmsis_enet_mac_resource_t ENET0_Resource;
cmsis_enet_phy_resource_t ENETPHY0_Resource;
static phy_rtl8211f_resource_t g_phy_resource;
uint8_t g_frame[ENET_DATA_LENGTH + 14];
volatile uint32_t g_testTxNum  = 0;
uint8_t g_macAddr[6]           = MAC_ADDRESS;
volatile uint32_t g_rxIndex    = 0;
volatile uint32_t g_rxCheckIdx = 0;
volatile uint32_t g_txCheckIdx = 0;
phy_handle_t phyHandle;
/*******************************************************************************
 * Code
 ******************************************************************************/
uint32_t ENET_GetFreq(void)
{
    return CLOCK_GetRootClockFreq(kCLOCK_Root_Bus);
}
 
void BOARD_InitModuleClock(void)
{
    const clock_sys_pll1_config_t sysPll1Config = {
        .pllDiv2En = true,
    };
    CLOCK_InitSysPll1(&sysPll1Config);
    clock_root_config_t rootCfg = {.mux = 4, .div = 4}; /* Generate 125M root clock. */
    CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg);
}
 
static void MDIO_Init(void)
{
    (void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(ENET_1G)]);
    ENET_SetSMI(ENET_1G, ENET_GetFreq(), false);
}
 
static status_t MDIO_Write(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
{
    return ENET_MDIOWrite(ENET_1G, phyAddr, regAddr, data);
}
 
static status_t MDIO_Read(uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
{
    return ENET_MDIORead(ENET_1G, phyAddr, regAddr, pData);
}
 
void ENET_SignalEvent_t(uint32_t event)
{
    if (event == ARM_ETH_MAC_EVENT_RX_FRAME)
    {
        uint32_t size;
        uint32_t len;
 
        /* Get the Frame size */
        size = EXAMPLE_ENET.GetRxFrameSize();
        /* Call ENET_ReadFrame when there is a received frame. */
        if (size != 0)
        {
            /* Received valid frame. Deliver the rx buffer with the size equal to length. */
            uint8_t *data = (uint8_t *)malloc(size);
            if (data)
            {
                len = EXAMPLE_ENET.ReadFrame(data, size);
                if (size == len)
                {
                    /* Increase the received frame numbers. */
                    if (g_rxIndex < ENET_EXAMPLE_LOOP_COUNT)
                    {
                        g_rxIndex++;
                    }
                }
                free(data);
            }
        }
    }
    if (event == ARM_ETH_MAC_EVENT_TX_FRAME)
    {
        g_testTxNum++;
    }
}
 
/*! @brief Build Frame for transmit. */
static void ENET_BuildBroadCastFrame(void)
{
    uint32_t count  = 0;
    uint32_t length = ENET_DATA_LENGTH - 14;
 
    for (count = 0; count < 6U; count++)
    {
        g_frame[count] = 0xFFU;
    }
    memcpy(&g_frame[6], &g_macAddr[0], 6U);
    g_frame[12] = (length >> & 0xFFU;
    g_frame[13] = length & 0xFFU;
 
    for (count = 0; count < length; count++)
    {
        g_frame[count + 14] = count % 0xFFU;
    }
}
 
// Notify the user application about TCP socket events.
uint32_t tcp_cb_server (int32_t socket, netTCP_Event event,
                        const NET_ADDR *addr, const uint8_t *buf, uint32_t len) {
 
  switch (event) {
    case netTCP_EventConnect:
      // Connect request received
     
      if (addr->addr_type == NET_ADDR_IP4) {
        // IPv4 client
        if (addr->addr[0] == 192  &&
            addr->addr[1] == 168  &&
            addr->addr[2] == 0    &&
            addr->addr[3] == 100) {
          // Accept connection from client at 192.168.0.1
PRINTF("connected\r\n");
          return (1);
        }
      }
      else {
        // IPv6 client
        const uint8_t ip6_addr[NET_ADDR_IP6_LEN] = { 
                         0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                         0x1c, 0x30, 0x6c, 0xff, 0xfe, 0xa2, 0x45, 0x5e };
        if (memcmp (addr->addr, ip6_addr, NET_ADDR_IP6_LEN) == 0) {
          // Accept connection from client at [fe80::1c30:6cff:fea2:455e]
          return (1);
        }
      }
      // Deny connection.
      return (0);
 
    case netTCP_EventEstablished:
      // Connection established
      break;
 
    case netTCP_EventClosed:
      // Connection was properly closed
      break;
 
    case netTCP_EventAborted:
      // Connection is for some reason aborted
      break;
 
    case netTCP_EventACK:
      // Previously sent data acknowledged
      break;
 
    case netTCP_EventData:
      // Data received
      
      if ((buf[0] == 0x01) && (len == 2)) {
        // Switch LEDs on and off
        // LED_out (buf[1]);
      }
      
      break;
  }
  return (0);
}
 
/*!
 * @brief Main function
 */
int main(void)
{
    uint32_t txnumber = 0;
    ARM_ETH_LINK_INFO linkInfo;
 
    /* Hardware Initialization. */
    gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
 
    /* Hardware Initialization. */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    BOARD_InitModuleClock();
 
    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) */
    GPIO_PinInit(GPIO11, 14, &gpio_config);
    /* For a complete PHY reset of RTL8211FDI-CG, this pin must be asserted low for at least 10ms. And
     * wait for a further 30ms(for internal circuits settling time) before accessing the PHY register */
    GPIO_WritePinOutput(GPIO11, 14, 0);
    SDK_DelayAtLeastUs(10000, CLOCK_GetFreq(kCLOCK_CpuClk));
    GPIO_WritePinOutput(GPIO11, 14, 1);
    SDK_DelayAtLeastUs(30000, CLOCK_GetFreq(kCLOCK_CpuClk));
 
    EnableIRQ(ENET_1G_MAC0_Tx_Rx_1_IRQn);
    EnableIRQ(ENET_1G_MAC0_Tx_Rx_2_IRQn);
 
    g_phy_resource.read  = MDIO_Read;
    g_phy_resource.write = MDIO_Write;
 
    ENET0_Resource.base           = ENET_1G;
    ENET0_Resource.GetFreq        = ENET_GetFreq;
    ENETPHY0_Resource.phyAddr     = RTE_ENET_PHY_ADDRESS;
    ENETPHY0_Resource.ops         = &phyrtl8211f_ops;
    ENETPHY0_Resource.opsResource = &g_phy_resource;
 
    MDIO_Init();
 
    PRINTF("\r\nENET example start.\r\n");
 
#ifndef USER_DEFINED_MAC_ADDRESS
    /* Set special address for each chip. */
    SILICONID_ConvertToMacAddr(&g_macAddr);
#endif
 
    /* Initialize the ENET module. */
    EXAMPLE_ENET.Initialize(ENET_SignalEvent_t);
    EXAMPLE_ENET.PowerControl(ARM_POWER_FULL);
    EXAMPLE_ENET.SetMacAddress((ARM_ETH_MAC_ADDR *)g_macAddr);
 
    PRINTF("Wait for PHY init...\r\n");
    while (EXAMPLE_ENET_PHY.PowerControl(ARM_POWER_FULL) != ARM_DRIVER_OK)
    {
        PRINTF("PHY Auto-negotiation failed, please check the cable connection and link partner setting.\r\n");
    }
 
    EXAMPLE_ENET.Control(ARM_ETH_MAC_CONTROL_RX, 1);
    EXAMPLE_ENET.Control(ARM_ETH_MAC_CONTROL_TX, 1);
    PRINTF("Wait for PHY link up...\r\n");
    do
    {
        if (EXAMPLE_ENET_PHY.GetLinkState() == ARM_ETH_LINK_UP)
        {
            linkInfo = EXAMPLE_ENET_PHY.GetLinkInfo();
            EXAMPLE_ENET.Control(ARM_ETH_MAC_CONFIGURE, linkInfo.speed << ARM_ETH_MAC_SPEED_Pos |
                                                            linkInfo.duplex << ARM_ETH_MAC_DUPLEX_Pos |
                                                            ARM_ETH_MAC_ADDRESS_BROADCAST);
PRINTF("Link UP.\r\n");
            break;
        }
    } while (1);
 
#if defined(PHY_STABILITY_DELAY_US) && PHY_STABILITY_DELAY_US
    /* Wait a moment for PHY status to be stable. */
    SDK_DelayAtLeastUs(PHY_STABILITY_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
#endif
PRINTF("PHY status to be stable.\r\n");
 
ENET_BuildBroadCastFrame();
 
 
int32_t tcp_sock;
 PRINTF("Sock defined.\r\n");
 netInitialize ();
 PRINTF("NET Initialized.\r\n");
  // Initialize TCP Socket and start listening on port 2000
  tcp_sock = netTCP_GetSocket (tcp_cb_server);
PRINTF("%d",tcp_sock);
  if (tcp_sock > 0) {
    netTCP_Listen (tcp_sock, 2000);
  }
 
    /* Build broadcast for sending. */
 
 
    /*while (1)
    {
        
        if (g_testTxNum && (g_txCheckIdx != g_testTxNum))
        {
            g_txCheckIdx = g_testTxNum;
            PRINTF("The %d frame transmitted success!\r\n", g_txCheckIdx);
        }
        if (g_rxCheckIdx != g_rxIndex)
        {
            g_rxCheckIdx = g_rxIndex;
            PRINTF("A total of %d frame(s) has been successfully received!\r\n", g_rxCheckIdx);
        }
        
        if (txnumber < ENET_EXAMPLE_LOOP_COUNT)
        {
            txnumber++;
            
            if (EXAMPLE_ENET.SendFrame(&g_frame[0], ENET_DATA_LENGTH, ARM_ETH_MAC_TX_FRAME_EVENT) == ARM_DRIVER_OK)
            {
                SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
            }
            else
            {
                PRINTF(" \r\nTransmit frame failed!\r\n");
            }
        }
    }*/
}
 
 
My code stop at netInitialize (); .
SOme one help me , please.
0 Kudos
Reply
2 Replies

887 Views
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @MikeHazma ,

Hope you are doing well and thanks for your questions!

I checked the internal resources, but unfortunately NXP does not provide similar porting routines. Also, I suggest you to check this thread, it provides some necessary information that should help you .ARM-Keil should have more resources.

Best regards,
Gavin

 

0 Kudos
Reply

713 Views
Sacha
Contributor I

Hello Gavin,

I have the same problem. I have Keil's simple web server demo running on an iMXRT1160-EVK using SDK12.1 (DFP.15), but when migrating to anything from SDK13 onwards I find the same issue. If I transplant the associated enet files from SDK12.1 into the latest DFP19 (SDK.16) then everything appears fine again, so at least we can isolate the issue to the enet files. From SDK.13 onwards there were so many changes to the enet files that it's difficult to work out exactly which change has broken this. Change notes would be good!?

The issue appears to be end in stack corruption which triggers an unaligned error, but that may not be the root cause. I suspect the problems may be due to the changes to buffer data structures as problem 'seems' to happen when ENET_SetTxBufferDescriptors() is called via ENET_Up().

I don't think it is good enough to say that you don't support this type of porting when you provide the fsl_enet_cmsis interface layer in the SDK, which was also updated at the same time as the other enet files. If you don't support third party middleware access, then what is the point in fsl_enet_cmsis etc?

Hopefully we can get some help with determining which of the changes broke the cmsis layer, else I will have to stick with my improvised drivers and never update again.

Regards.

Sacha.

0 Kudos
Reply