Ti cortex m3 serial port to Ethernet routine analysis 3 -- lwip1.3.2 porting

Source: Internet
Author: User
Tags snmp

The underlying application of Ti cortex m3 serial port to Ethernet routine is LWIP and the version is v1.3.2. For LWIP, a stranger can check it online. It is an open-source TCP/IP protocol written by Adam in Switzerland. Since the serial port to Ethernet routine is based on LWIP, let's see how LWIP is transplanted to TI's cortex m3 hardware. This is the split line -------

For the porting overview, refer to the blog article. The following describes the specific porting code in this format. Http://blog.csdn.net/zhzht19861011/article/details/6615965

1. CC. h file

This file mainly sets the data types used inside LWIP, such as u8_t and u32_t. LWIP can be transplanted to a 32-bit, 16-bit, or even 8-bit architecture microcontroller, these data types are set by row based on your hardware and compiler features. For example, an int type variable represents 2 bytes in both the 8-bit and 16-bit controllers, but 4 bytes in a 32-bit microprocessor, if these basic data types are not correctly set, we can't talk about porting them. The source code of CC. H is as follows:

# Ifndef _ cc_h __# DEFINE _ cc_h _ typedef unsigned char u8_t; // set typedef signed Char s8_t for basic data types; typedef unsigned short u16_t; typedef signed short s16_t; typedef unsigned long u32_t; typedef signed long s32_t; typedef u32_t mem_ptr_t; # ifndef byte_order # define byte_order little_endian # endif # If defined (_ arm __) & defined (_ armcc_version) // The following mainly sets the alignment of struct data of different compilers. LWIP requires /// setup packing macros for Keil/R Vmdk tools // # define pack_struct_begin _ packed # define pack_struct_struct # define pack_struct_end # define pack_struct_field (x) x # Elif defined (_ iar_systems_icc __) /// setup packing macros for IAR tools // # define pack_struct_begin # define pack_struct_struct # define pack_struct_end # define pack_struct_field (X) X # define pack_struct_use_includes # else // setup packing macros for GCC tools // # Define pack_struct_begin # define pack_struct_struct _ attribute _ (_ packed _) # define pack_struct_end # define pack_struct_field (X) X # endif # ifdef debugextern void _ error _ (char * pcfilename, unsigned long ulline); # define lwip_platform_assert (expr) \ {\ If (! (Expr) \ {_ error _ (_ file __, _ line _); \}\}# else # define lwip_platform_assert (expr) # endif/* _ cc_h __*/

2. Ethernet hardware initialization, data receiving and sending functions closely related to hardware

Although Adam has done a lot of work to facilitate LWIP protocol stack porting, Adam cannot write a driver for every NIC due to the diversity of NICs and the emergence of new NICs. Therefore, the Code related to the NIC hardware is left for programmers to write. In fact, Adam has written a hardware-closely related porting code framework in the LWIP protocol stack, which is located in the lwIP-1.3.2/src/netif/ethernetif. C. Stellaris serial port to Ethernet port porting code is also basically written by referring to this code framework. The port code closely related to the hardware of the stellais serial port to Ethernet module is located in stellarisif. C. The code below consists of three parts: the LWIP protocol stack and Ethernet hardware initialization functions, the LWIP protocol stack sends data to the output functions on the network interface, and the input functions that read data from the stellaris Ethernet hardware and send it to the LWIP protocol stack.

2.1 LWIP protocol stack and Ethernet hardware initialization

In the porting code stellarisif. C, the function for initializing the LWIP protocol stack and Ethernet hardware is:

Err_t stellarisif_init (structnetif * netif)

This function first sets the underlying operations related to the protocol stack, specifies the underlying receives callback function, and then initializes the actual network interface chip, and sets the working mode of hardware and the open interruption. The source code is as follows:

/*** Shocould be called at the beginning of the program to set up the * network interface. it callthe function stellarisif_hwinit () to do the * Actual setup of the hardware. * This is called at the beginning of the program to set network interfaces. he calls the stellarisif_hwinit () function * to complete the Ethernet hardware settings. * This function shoshould be passed as a parameter to netif_add (). * This function is passed as a parameter to the netif_add () function. * @ Param netif the LWIP network interface structure for this ethern Etif * @ return err_ OK if the loopif is initialized * err_mem if private data couldn't be allocated * any other err_t on Error */err_tstellarisif_init (struct netif * netif) {lwip_assert ("netif! = NULL ", (netif! = NULL); # If lwip_netif_hostname/* initialize interface hostname */netif-> hostname = "LWIP "; // initialize the interface host name # endif/* lwip_netif_hostname * // ** initialize the SNMP variables and counters inside the struct netif. * The last argument shocould be replaced with your link speed, in units * of bits per second. */netif_init_snmp (netif, snmp_iftype_ethernet_csmacd, 1000000); // initialize the SNMP variable netif-> state = & stellarisif_data; // Private Data pointing to the Ethernet interface, including pbuf Data Link and MAC address netif-> name [0] = ifname0; netif-> name [1] = ifname1;/* We directly use etharp_output () here to save a function call. * You can instead declare your own function an call etharp_output () * from it if you have to do some checks before sending (e.g. if link * is available ...) */netif-> output = etharp_output; // This function is called when the IP layer sends a packet of data to the network interface netif-> linkoutput = stellarisif_output; // This function is called when the ARP module sends a packet of data to the network interface stellarisif_data.ethaddr = (struct eth_addr *) & (netif-> hwaddr [0]); // initialize the MAC address protocol = 0; // initialize the pbuf Data Link stellarisif_data.txq.overflow = 0;/* initialize the hardware */stellarisif_hwinit (netif ); // initialize stellaris Ethernet hardware return err_ OK ;}

1. netif-> output = etharp_output; used to send a packet of data to the network interface, called by the IP layer. This function will eventually call netif-> linkoutput to send data to the network interface.

2. netif-> linkoutput = stellarisif_output; used to send a packet of data to the network interface, which is called by the ARP module. Programmers need to compile the function based on their own hardware platform. This function will be discussed later.

3. stellarisif_hwinit (netif.

/*** In this function, the hardware shoshould be initialized. * called from stellarisif_init (). ** @ Param netif the already initialized LWIP Network Interface Structure * For This ethernetif */static voidstellarisif_hwinit (struct netif * netif) {u32_t temp; // struct stellarisif * stellarisif = netif-> state;/* set the MAC address length of the Ethernet hardware */netif-> hwaddr_len = etharp_hwaddr_len; /* set the Ethernet hardware address */ethernetmacaddrget (eth_base, & (netif-> hwaddr [0]);/* maximum sending unit */netif-> MTU = 1500; /* enable Nic functions, allow Nic broadcast, ARP, and allow hardware links to connect to the NIC * // * don't set netif_flag_etharp if this device is not an Ethernet one */netif-> flags = netif_flag_broadcast | netif_flag_etharp | netif_flag_link_up; /* do whatever else is needed to initialize interface. * // * disable all Ethernet interruptions */ethernetintdisable (eth_base, (eth_int_phy | disable | eth_int_tx | eth_int_txer | eth_int_rx); temp = ethernetintstatus (eth_base, false ); ethernetintclear (eth_base, temp);/* initialize the Ethernet controller */ethernetinitexpclk (eth_base, sysctlclockget ();/** configure the Ethernet controller to run properly. *-enable TX full duplex mode *-enable TX filling *-enable tx crc generation *-enable RX multicast to receive */ethernetconfigset (eth_base, (eth_1__tx_dplxen | eth_1__tx_crcen | eth_1__tx_paden | eth_1__rx_amulen);/* enable Ethernet controller transmitters and receivers */ethernetenable (eth_base ); /* enable Ethernet interruption */intenable (int_eth);/* enable Ethernet Tx and Rx packet interruption */ethernetintenable (eth_base, eth_int_rx | eth_int_tx );}


2.2 stellaris underlying data sending function of Ethernet hardware
As mentioned above, when the ARP module sends data to the network interface, it calls the netif-> linkoutput function. When the IP layer sends data to the network interface, it calls the netif-> output function, however, the actual data sending function at the IP layer is netif-> linkoutput. During Ethernet initialization, The linkoutput pointer has been assigned a value: netif-> linkoutput = stellarisif_output; therefore, the stellaris underlying data sending function of the Ethernet hardware that programmers need to write when porting LWIP is the stellarisif_output () function. Let's take a look at the following source code:

/*** This function with either place the packet into the stellaris transmit FIFO, * or will place the packet in the interface pbuf queue for subsequent * transmission when the transmitter becomes idle. * This function either places the data packet in the stellaris sending cache FIFO or the data packet in the pbuf queue, waiting for * Sending to be carried after the transmitter is empty. ** @ Param netif the LWIP network interface structure for this ethernetif * @ Param p the Mac packet to send (e.g. IP packet including MAC addresses and type) * @ return err_ OK if the packet cocould be sent * an err_t value if the packet couldn't be sent **/static err_tstellarisif_output (struct netif * netif, struct pbuf * P) {struct stellarisif * stellarisif = netif-> state; sys_arch_decl_protect (lev ); /*** This entire function must run within a "critical section" to preserve * the integrity of the transmit pbuf queue. **/sys_arch_protect (lev);/*** bump the reference count on the pbuf to prevent it from being * freed till we are done with it. **/pbuf_ref (p);/*** if the transmitter is idle, and there is nothing on the queue, * Send the pbuf now. **/If (pbuf_queue_empty (& stellarisif-> txq) & (Hwreg (eth_base + mac_o_tr) & mac_tr_newtx) = 0) {stellarisif_transmit (netif, P);}/* otherwise place the pbuf on the transmit queue. */else {/* Add to transmit packet queue */If (! Enqueue_packet (p, & (stellarisif-> txq) {/* if no room on the queue, free the pbuf reference and return error. */pbuf_free (p); sys_arch_unprotect (lev); Return (err_mem) ;}/ * return to prior interrupt state and return. */sys_arch_unprotect (lev); return err_ OK ;}

1. sys_arch_decl_protect (lev);, sys_arch_protect (lev);, sys_arch_unprotect (lev); Because stellaris Ethernet must be in the critical section when sending data, it cannot be interrupted. Therefore, the above macros are used to close and open the total interrupt. Sys_arch_decl_protect (lev) is used to define a 32-bit variable, which is used to save the current interrupt enable information; sys_arch_protect (lev) is used to close the interrupt; sys_arch_unprotect (lev) is used to open the interrupt.

2. pbuf_ref (p); add one of the ref fields of the pbuf parameter structure. This field counts how many pointers direct to this pbuf. These pointers may be application pointers, protocol stack pointers, or pbuf-> next pointers in the data link. Only when ref is 0, to release this pbuf. For a detailed introduction to the structure pbuf see blog: http://blog.csdn.net/zhzht19861011/article/details/6591252

3. stellarisif_transmit (netif, p): send data.


2.3 stellaris underlying Ethernet hardware Data Process
When a packet of data on the network reaches the Ethernet controller, the Ethernet controller is set to receive interruption. In the interrupt service function, call

The stellarisif_receive function (which requires the programmer to write based on the specific hardware) to receive a data packet and then pass

The ethernet_input function analyzes the type of the received data packet. For example, if the data type is 0x8000, it is an IP frame and ip_input is called.

Function to send the received IP packet to the upper layer of the LWIP protocol stack. Stellaris Ethernet hardware interrupt function analysis can be found in the blog

: Http://blog.csdn.net/zhzht19861011/article/details/6221699

3. lwipopts. h file

...


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.