This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-J721E: Ethfw/ Sending a message from client to pc1

Part Number: PROCESSOR-SDK-J721E

hello all, 

when running the ethfw/appclient server , where would be the appropriate place to put the code to send a message back to pc1 after pc1 has made its connection ? 


Sdk 9.0.0.6

  • Hi,

    Sdk 9.0.0.6

    when running the ethfw/appclient server , where would be the appropriate place to put the code to send a message back to pc1 after pc1 has made its connection ? 

    EthFw doesn't have application for sending the Data.

    Please refer to enet_loopback example where it will send some data to CPSW and get back the same. You can also use similar approach for sending data from application like EthFw.

    Best Regards,
    Sudheer

  • hi Sudheer ,

    Thanks for your reply , it should be much simpler than enet_loopback example , it should be a few line of code some where in the client's main.c file , any other suggestion please ..

    Thanks.

  • Hi,

    it should be a few line of code some where in the client's main.c file , any other suggestion please ..
    Please refer to "ethernet_output" API which is lwip stack API, this API will invoke LWIPIF_LWIP_send for sending the data in pbuf to UDMA and to CPSW.

    You can modify refer to those and send custom data.

    Best Regards,
    Sudheer
  • please explain :

    you said,  Please refer to "ethernet_output" API which is lwip stack API, this API will invoke LWIPIF_LWIP_send for sending the data in pbuf to UDMA and to CPSW.

    ethernet_output ?? where is this

    LWIPIF_LWIP_send??  no such a function

    can you please take your time and explain slowly and more accurately please  ..

    Thanks.

  • Hi,

    ethernet_output is used in Proxy ARP at EthFw, as it is giving response behalf of client for ARP request.
    Proxy ARP will send ARP response packet using ethernet_output API.

    If you track the call sequence, ethernet_output  will invoke LWIPIF_LWIP_send for submitting the packet to DMA.

    Probably you need to create a task and invoke ethernet_output  for sending the data, only thing you need will be store the netif (hLwip2Enet->netif)  information from Lwip2Enet_open API call.

    It is not straight forward to send the packets, you need to handle Rings how it was is enet_loopback_example of "EnetLpbk_txTask".

    Best Regards,
    Sudheer

  • Hi

    please be informed I Dont want  to send a packet , I just need to send a "character" using lwip 

    so it should be much easier than what you have mentioned.

    any suggestions please ,

    Thanks.

  • Hi,

    please be informed I Dont want  to send a packet , I just need to send a "character" using lwip 

    If you want to send single character also it 

    you can call ethernet_output from EthApp_initLwip after "EthApp_initNetif"  as 

    ethernet_output(netif, data_buf, ethSrcAddr, ethDstAddr, ether_type);

    In above data_buf should be your data buffer pointer .

    Bellow is sample reference, please refer and make it work. 
    {
    const struct eth_addr *ethSrcAddr = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    const struct eth_addr *ethDstAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint8_t *data_ptr;
    struct pbuf *pbuf;
    uint16_t ether_type;
    
    /* allocate a pbuf for the outgoing packet */
    pbuf = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
    
    data_ptr = pbuf->payload;
    
    // fill data into data_ptr
    ethernet_output(netif, data_buf, ethSrcAddr, ethDstAddr, ether_type);
    
    }


    From TI SDK we don't have any data transmission example in EthFw, As mentioned you can refer to loopback example as pointed above.

    Best Regards,
    Sudheer
  • Hello Sudheer,

    I have tried what you have suggested but unfortunately it didnt work :(

    Instead  I have written the below code and created  a separate task in main function to call it , and I am getting this :

    SYSFW Common Board Configuration with Debug enabled... PASSED
    SYSFW PM Board Configuration... PASSED
    SYSFW Security Board Configuration... PASSED
    =================================================================
     DMSC Firmware Version 9.1.2--v09.01.02 (Kool Koala)
     Firmware revision 0x9
     ABI revision 3.1
    =================================================================
    Sciclient_ccs_init Passed.
    SCISERVER Board Configuration header population... PASSED
    [MAIN_Cortex_R5_0_1] CpswProxy: Local cmd endpt 101, notify endpt 30
    CpswProxy: ETHFW services found at core 3 endpts 101 (ti.ethfw.ethdevice) and 102 (ti.ethfw.notifyservice)
    RTOS-App: Starting lwIP, local interface IP is 192.168.0.51
    CpswProxy: ATTACH_EXT | C2S | virtPort=1
    CpswProxy: ATTACH_EXT | S2C | token=100 rxMtu=1522 features=9 flow=172,7 rxPsil=0x4a00 txPsil=0xca05 macAddr=70:ff:76:1f:0a:4f
    CpswProxy: REGISTER_MAC | C2S | token=100 flowIdx=172,7
    CpswProxy: REGISTER_MAC | S2C | token=100 status=0
    [LWIPIF_LWIP] Enet LLD netif initialized successfully
    [LWIPIF_LWIP_IC] Interface started successfully
    [LWIPIF_LWIP_IC] NETIF INIT SUCCESS
    RTOS-App: Added interface 'ti0', IP is 0.0.0.0
    CpswProxy: REGISTER_REMOTE_TIMER | C2S | token=100 timerId=1 hwPushNum=2
    CpswProxy: REGISTER_REMOTE_TIMER | S2C | token=100 status=0
    RTOS-App: Added interface 'br2', IP is 192.168.0.51
    Assertion "sem != NULL" failed at line 287 in freertos/sys_arch.c

    the client  function to talk to pc1 :

    
    static void startPc1 (void* a0, void* a1)
    {
    
       vTaskDelay(500);   
       ip_addr_t server_ip;
        err_t status;
        err_t err;
    
    //tcpip_init(NULL,NULL);
    
    
    struct netconn *conn;
    conn=netconn_new(NETCONN_TCP);    
    P4_ADDR(&server_ip, 192u, 168u, 0u, 198u); // PC
    
     status= netconn_connect(conn,&server_ip,5000);
    
    if(status == ERR_OK)
    {
      printf("sorrry I could not connect to server....\r\n");
     while(1);
    }
    
    for (int i=0;i<5;i++)
    {
                printf("sending data  to server....\n");
                status = netconn_write(conn,"hello from Ubuntu2",28,NETCONN_NOCOPY); // cr lf 2 bytes
                if(status != ERR_OK)
                {
    
                printf("  sending failed....\r\n");
    
                netconn_delete(conn);
                while(1);
    
                }
                else if(status == ERR_OK) 
                {
                printf(" data sent successfully....\n");
                }
                
                vTaskDelay(1000); // delay 1 second   ????????????????????????
    
    }
    netconn_close(conn);
    netconn_delete(conn);
    
    for(;;)
    {}
    
    }
    

    the main  function:

    int main(void)
    {
        TaskP_Handle task;
        TaskP_Params taskParams;    
        TaskP_Params taskParams2;
    
        int32_t status;
    
        OS_init();
    // tcpip_init(NULL,NULL);
    
        /* Wait for debugger to attach (disabled by default) */
        EthApp_waitForDebugger();
    
        /* Init UDMA LLD based on NAVSS instance */
        status = CpswRemoteApp_openUdma();
        if (status != UDMA_SOK)
        {
            ETHFWTRACE_ERR(status, "Failed to open UDMA LLD");
            localAssert(status == UDMA_SOK);
        }
    
        /* Init Enet LLD and open Enet DMA */
        status = CpswRemoteApp_openEnet();
        if (status != ENET_SOK)
        {
            ETHFWTRACE_ERR(status, "Failed to open Enet LLD");
            localAssert(status == ENET_SOK);
        }
    
        TaskP_Params_init(&taskParams2);
        taskParams2.priority = 1;
        taskParams2.stack = &pc1StackBuf[0];
        taskParams2.stacksize = sizeof(pc1StackBuf);
        taskParams2.name      = "  pc1  loop ";
        TaskP_create(&startPc1, &taskParams2);
    
    
        TaskP_Params_init(&taskParams);
        taskParams.priority = 2;
        taskParams.stack = &g_initTaskStackBuf[0];
        taskParams.stacksize = sizeof(g_initTaskStackBuf);
    
        task = TaskP_create(&CpswRemoteApp_initTask, &taskParams);
    
        if (NULL == task)
        {
            OS_stop();
        }
    
        OS_start();    /* does not return */
        return(0);
    }

    Thanks.

  • Hi,

    Above assertion seems to be some semaphore issue at lwip, it seems the value as NULL.

    By default EthFw will not register callback for TCP/IP packets.

    Please refer to loopback example for transmission of data from App to Network via CPSW. (just avoid loopback enable)

    Best Regards,
    Sudheer

  • Hi,

    I am very sorry.

    As I have pointed you the steps and provided some APIs to refer in EthFW, for sending data from EthFw to outside of Network.

    We tried to support you our level best and this is not supported in SDK by default.

    Best regards,
    Sudheer

  • hi Sudheer

    yes you said use ethernet_output(netif, data_buf, ethSrcAddr, ethDstAddr, ether_type);

  • Hi,

    please provide me  more info on that , where should that line be placed??? and how to use it ??

    Please refer to my update above.

    you can call ethernet_output from EthApp_initLwip after "EthApp_initNetif"  as 

    ethernet_output(netif, data_buf, ethSrcAddr, ethDstAddr, ether_type);

    In above data_buf should be your data buffer pointer .

    Bellow is sample reference, please refer and make it work. 
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    const struct eth_addr *ethSrcAddr = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    const struct eth_addr *ethDstAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint8_t *data_ptr;
    struct pbuf *pbuf;
    uint16_t ether_type;
    /* allocate a pbuf for the outgoing packet */
    pbuf = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
    data_ptr = pbuf->payload;
    // fill data into data_ptr
    ethernet_output(netif, data_buf, ethSrcAddr, ethDstAddr, ether_type);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Best Regards,
    Sudheer

  • yes but this is completely different from what I want,

    I need to send to ip not mac address

    const struct eth_addr *ethSrcAddr = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

    loocks like a mac address to me , plus you didnt tell me where shold i place this code in main.c please.

  • Hi,

    I need to send to ip not mac address

    IP details you can add in pbuf i.e. your custom data.

    loocks like a mac address to me , plus you didnt tell me where shold i place this code in main.c please.

    Yes, ethernet_output API required MAC Address of Source and Destination along with Ethernet Type.

    you can call ethernet_output from EthApp_initLwip after "EthApp_initNetif"  as 

    ethernet_output(netif, data_buf, ethSrcAddr, ethDstAddr, ether_type);

    As pointed in above you can invoke ethernet_output from  EthApp_initLwip after "EthApp_initNetif".
    parameters are as mentioned in sample code.

    Best Regards,
    Sudheer

  • hi Sudheer

    plese can you check if this code is ok after EthApp_initNetif as you mentioned; thanks alot

  • Hi,

    I could not see any code added in E2E. I think it was removed.

    But if you are adding similar to above I have mentioned, it could be fine.

    Best Regards,
    Sudheer

  • Hi Sudheer

    this was the code :

    static void EthApp_initLwip(void *arg)
    {
    sys_sem_t *initSem;
    uint32_t i;
    int array[10]={0};
    uint8_t *data_ptr;
    struct pbuf *pbuf;
    uint16_t ether_type;
    const struct eth_addr ethSrcAddr = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    const struct eth_addr ethDstAddr = {0xA4, 0x3A, 0x1A, 0xA3, 0xFA, 0xA5}; // /Laptop mac address

    /* allocate a pbuf for the outgoing packet */
    pbuf = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);

    data_ptr = pbuf->payload;
    data_ptr="hellow";
    // fill data into data_ptr

    LWIP_ASSERT("arg != NULL", arg != NULL);
    initSem = (sys_sem_t*)arg;

    /* init randomizer again (seed per thread) */
    srand((unsigned int)sys_now()/1000);

    /* init network interfaces */
    for (i = 0U; i < ENET_ARRAYSIZE(gRemoteAppObj.virtNetif); i++)
    {
    EthApp_initNetif(&gRemoteAppObj.virtNetif[i]); /// call after this
    }
    ethernet_output(&gRemoteAppObj.virtNetif[0]), data_ptr, ethSrcAddr, ethDstAddr, eth_type ?? );
     
    THANKS..
  • Hi,

    Above looks fine.

    In place of eth_type use some random number and check on link partner side.

    const struct eth_addr ethDstAddr = {0xA4, 0x3A, 0x1A, 0xA3, 0xFA, 0xA5}; // /Laptop mac address

    We need ALE entry to forward the packet from Host Port to External Port. Default your Laptop MAC address will not register in ALE.
    Better to use Broadcast MAC address, as default EthFw registers Broadcast MAC address with Port Mask of all ports i.e. If broadcast packet reaches ALE it will be forwarded to all switch ports.

    Best Regards,
    Sudheer

  • Hi,

    Use Broadcast MAC address as destination MAC Addresses.

    Forwarding of packets from one Port to other will be based on ALE (Address Lookup Engine), which is HW Module in CPSW.

    If you use specific MAC address, you need to register with ALE to handle the packet.

    Best Regards,
    Sudheer