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.

C6657: Using ethernet in my own application without BIOS

Other Parts Discussed in Thread: SYSBIOS

Hi,

I was wondering how can I send and receive packets over ethernet.

I have tried to port the example given in:

C:\ti\pdk_C6657_1_1_1_4\packages\ti\drv\emac\example\EMACBenchmark

but without success, since I do not wish to work with tasks.

My init function looks as follows:

void eth_init (void)
{
	EMAC_CONFIG_INFO_T          emac_cfg;

#ifdef TWO_PORT_DEV
	port_num                        = 1;
#endif
	open_cfg.master_core_flag       = TRUE;
	open_cfg.mdio_flag              = TRUE;
	open_cfg.loop_back              = FALSE;
	open_cfg.num_of_tx_pkt_desc     = APP_EMAC_INIT_TX_PKTS;
	open_cfg.num_of_rx_pkt_desc     = APP_EMAC_INIT_RX_PKTS;
	open_cfg.max_pkt_size           = APP_EMAC_INIT_PKT_SIZE;
	open_cfg.num_of_chans           = APP_EMAC_NUM_CHANS_PER_CORE;
	open_cfg.p_chan_mac_addr        = &chan_cfg;
	open_cfg.rx_pkt_cb              = app_rx_pkt;
	open_cfg.alloc_pkt_cb           = app_alloc_pkt;
	open_cfg.free_pkt_cb            = app_free_pkt;

	if (port_num == 0)
	{
		open_cfg.phy_addr           = APP_PORT0_PHY_ADDR;
	}
#ifdef TWO_PORT_DEV
else
{
	open_cfg.phy_addr           = APP_PORT1_PHY_ADDR;
}
#endif

	/* Set the channel configuration */
	chan_cfg.chan_num               = chan_num;
	chan_cfg.num_of_mac_addrs       = APP_EMAC_NUM_MACADDRS_PER_CHAN;
	memcpy(mac_addr.addr, tx_mac_addr, EMAC_MAC_ADDR_LENTH);
	chan_cfg.p_mac_addr             = &mac_addr;

	/* Always open the channel 0 on port 0 for receive task */
	if (emac_open(port_num, &open_cfg) == EMAC_DRV_RESULT_OK)
	{
		emac_cfg.mcast_cnt       = 0;
		emac_cfg.p_mcast_list    = NULL;
		emac_cfg.rx_filter       = EMAC_PKTFLT_MULTICAST;
		emac_config(port_num, &emac_cfg);

		/* Enable RX/TX interrupt */
		Osal_emacExitSingleCoreCriticalSection(port_num);
	}
	else
	{
		printf ("Application open EMAC port %d error \n", port_num);
	}

}

And to transmit the packet I use the following:

void Transmit_Pkt(unsigned char* buffer, unsigned int len){
	EMAC_PKT_DESC_T    p_pkt_desc;

	unsigned char send_buf[APP_EMAC_MAX_PKT_SIZE] = {0};

	p_pkt_desc.AppPrivate   = (Uint32)  &p_pkt_desc;
	p_pkt_desc.Flags        = EMAC_PKT_FLAG_SOP | EMAC_PKT_FLAG_EOP;
	p_pkt_desc.ValidLen     = APP_EMAC_TEST_TX_PKT_SIZE;
	p_pkt_desc.DataOffset   = 0;
	p_pkt_desc.PktChannel   = chan_num;
	p_pkt_desc.PktLength    = APP_EMAC_TEST_TX_PKT_SIZE;
	p_pkt_desc.PktFrags     = 1;


	p_pkt_desc.pDataBuffer = send_buf;
	/* Invalidate cache if data in external memory */
	//Osal_emacBeginMemAccess(send_buf, APP_EMAC_TEST_TX_PKT_SIZE);

	// copy data
	memcpy(app_mcb.test_pkt_buf, buffer, len);

	if (multicast)
	{
		/* Fill in the multicast destination address */
		memcpy(p_pkt_desc.pDataBuffer, mcast_mac_addr0, EMAC_MAC_ADDR_LENTH);
	}
	else if (broadcast)
	{
		/* Fill in the broadcast destination address */
		memset(p_pkt_desc.pDataBuffer, 0xff, EMAC_MAC_ADDR_LENTH);
	}
	else
	{
		/* Fill in the unitcast destination address */
		memcpy(p_pkt_desc.pDataBuffer, rx_mac_addr, EMAC_MAC_ADDR_LENTH);
	}

	/* Fill in the source address */
	memcpy(&p_pkt_desc.pDataBuffer[EMAC_MAC_ADDR_LENTH], tx_mac_addr, EMAC_MAC_ADDR_LENTH);

	/* Fill in the Ether Type and Payload */
	memcpy(&p_pkt_desc.pDataBuffer[2*EMAC_MAC_ADDR_LENTH],
			app_mcb.test_pkt_buf,
			APP_EMAC_TEST_TX_PKT_SIZE-2*EMAC_MAC_ADDR_LENTH);

	/* Write back cache to memory if data in external memory */
	//Osal_emacEndMemAccess(p_pkt_desc.pDataBuffer, APP_EMAC_TEST_TX_PKT_SIZE);

	emac_send(port_num, &p_pkt_desc);


}

My transmit function causes exception.

Can you please provide me an example or point out my mistake?

Thanks in advance,

Kfir.

  • Kfir,

    Welcome to the TI E2E forum. I hope you will find many good answers here and in the TI.com documents and in the TI Wiki Pages (for processor issues). Be sure to search those for helpful information and to browse for the questions others may have asked on similar topics (e2e.ti.com). Please read all the links below my signature.

    Please refer below NDK and ethernet FAQ wiki ,

    Thank you for your patience.

    Note: We strongly recommend you to create new e2e thread for your queries instead of following up on an old/closed e2e thread, new threads gets more attention than old threads and can provide link of old threads or information on the new post for clarity and faster response.

  • You can refer NDK helloworld or client examples in older MCSDK package.
    Also we do have NIMU example project in latest processor SDK package.
    I would like to recommend to use the latest processor SDK package.

    C:\ti\pdk_c665x_2_0_2\packages\MyExampleProjects\NIMU_emacExample_EVMC6657C66BiosExampleProject

    With using this example, you can send TCP/UDP packets using sockets.
    C:\ti\pdk_c665x_2_0_2\packages\ti\transport\ndk\nimu\example\helloWorld\src\udpHello.c
  • Hi @Stalin,

    This (from mcsdk_2_01_01_04) example indeed runs without problem.

    But it uses tasks and OS features to set the ETH!

    I would like to do this without the configuration, since uor code does not use the OS, we have an HelloWorld project with main() functions and that's it,

    We have not tasks and task configuration.

    How can this be done?

  • Our NDK stack is based on TI-RTOS(sys/bios) and we do not example without TI-RTOS configuration. Thank you.
  • Please install the latest processor SDK package for C6657 (C665x).
    You can refer to the following EMAC example.
    C:\ti\pdk_c665x_2_0_2\packages\MyExampleProjects\EMAC_evmc6657_C66Loopback_testProject

    However we do have the examples with RTOS setup, you can convert to bare-metal code on your own.
    Let us know if any issues.
  • Hi Titus,

    Thanks for the reference, but I couldn't find the folder specified, All I have is:

    Another question in that regard:


    Does a code that the main function doesn't have BIOS_start, but rather have BIOS_exit(0) instead this is taken from the "HelloWorld" example project in CCS_5.

    It states the following:

    /*
    * normal BIOS programs, would call BIOS_start() to enable interrupts
    * and start the scheduler and kick BIOS into gear. But, this program
    * is a simple sanity test and calls BIOS_exit() instead.
    */

    Creates a task or not for that scenario?

  • I think, you have referred this.
    C:\ti\bios_6_41_04_54\packages\ti\sysbios\examples\generic\hello\hello.c
    In this example, it doesn't create any tasks or no BIOS related stuff, so its using "Bios_exit" in main().

    Edited:
    When you call Bios_start(), it would run the "tasks" as per the priority which you have created in *.cfg or main() before "Bios_start()"

    You have to run the "pdkProjectCreate.bat" script to create the example projects.
    Refer to this wiki page.
    processors.wiki.ti.com/.../Processor_SDK_-_Create_PDK_projects

  • Hi Titus,

    Most thankful for the answer.

    But I cannot seem to be able to use the examples, since even the udpHello example (mentioned above)  is a pre-compiled program that I'm unable to clean/build or rebuild.

    I would be most thankful if you can explain to me what am I doing wrong in my first question.

    Kfir.

  • Able to get the ethernet NDK or PA examples from latest processor SDK ?

    Sorry I didn't get your question, not able to create the example projects ?