Chapter 4 TCP IP Manual
TCP-IP-Manual
User Manual:
Open the PDF directly: View PDF
.
Page Count: 145
| Download | |
| Open PDF In Browser | View PDF |
Micriµm Empowering Embedded Systems µC/TCP-IP V1.91 User’s Manual www.Micrium.com Disclaimer Specifications written in this manual are believed to be accurate, but are not guaranteed to be entirely free of error. Specifications in this manual may be changed for functional or performance improvements without notice. Please make sure your manual is the latest edition. While the information herein is assumed to be accurate, Micrium assumes no responsibility for any errors or omissions and makes no warranties. Micrium specifically disclaims any implied warranty of fitness for a particular purpose. Copyright notice You may not extract portions of this manual or modify the PDF file in any way without the prior written permission of Micrium. The software described in this document is furnished under a license and may only be used or copied in accordance with the terms of such a license. © 2003-2007 Micriµm, Weston, Florida 33327-1848, U.S.A. Trademarks Names mentioned in this manual may be trademarks of their respective companies. Brand and product names are trademarks or registered trademarks of their respective holders. Registration Please register the software via email. This way we can make sure you will receive updates or notifications of updates as soon as they become available. For registration please provide the following information: • • • • • • • • Your full name and the name of your supervisor Your company name Your job title Your email address and telephone number Company name and address Your company's main phone number Your company's web site address Name and version of the product Please send this information to: licensing@micrium.com Contact address Micrium 949 Crestview Circle Weston, FL 33327-1848 U.S.A. Phone : +1 954 217 2036 FAX : +1 954 217 2037 WEB : www.micrium.com Email : support@micrium.com 2 Manual versions If you find any errors in this document, please inform us and we will make the appropriate corrections for future releases. Manual Version Date By Description V1.54 Rev. A V1.54 Rev. B V1.56 V1.61 V1.70 V1.71 2004/12/09 2004/12/14 2005/01/23 2005/02/10 2005/04/24 2005/05/12 JJL JJL JJL JJL JJL ITJ V1.72 2005/07/11 ITJ V1.73 V1.80 V1.81 V1.82 V1.83 V1.84 V1.84 V1.85 V1.86 V1.87 V1.88 V1.89 V1.90 V1.91 2005/08/04 2005/10/18 2005/10/21 2005/12/13 2005/12/21 2006/04/14 2006/04/26 2006/05/08 2006/08/08 2006/09/20 2006/11/27 2007/03/08 2007/05/24 2007/10/24 ITJ JJL JJL ITJ ITJ ITJ JDH ITJ ITJ JJL ITJ ITJ ITJ ITJ Combined chapters in single document. Added Configuration constants in Chapter 17 Added information about buffers and timers Updated ASCII APIs because they were changed NIC chapter revision Updated Configuration Chapter; Updated Socket error codes; Added Debug Management Chapter Updated NIC Receive/Transmit Sections; Updated Configuration Sections Corrected Socket Receive/Send Functional Descriptions Minor changes to the manual Added Delayed Acknowledge Updated Debug Management Chapter Added information about example file usage Updated Debug Status Functions Corrected Socket API Descriptions Updated Manual Updated Manual Corrected Socket API & Configuration Descriptions Updated Manual Updated Manual 3 Table Of Contents I.1 I.2 I.3 I.4 I.5 I.6 I.7 I.8 I.9 I.10 Introduction................................................................................................................................8 Portable .............................................................................................................................................8 Scalable .............................................................................................................................................8 Coding Standards ..............................................................................................................................9 Third Party Certification ...................................................................................................................9 MISRA C ..........................................................................................................................................9 RTOS ..............................................................................................................................................10 Single Network Interface Controller (NIC).....................................................................................10 µC/TCP-IP Protocols ...................................................................................................................10 Application Protocols......................................................................................................................10 µC/TCP-IP Limitations................................................................................................................11 1.00 1.01 1.01.01 1.01.02 1.02 Getting Started with µC/TCP-IP .....................................................................................12 Installing µC/TCP-IP ...................................................................................................................12 Example #1 .....................................................................................................................................15 BSP (Board Support Package) ........................................................................................................17 Ex1 ..................................................................................................................................................18 Configuration of the Example #1....................................................................................................23 2.01.01 2.01.02 2.01.03 2.01.04 2.01.05 2.01.06 2.01.07 2.01.08 2.01.09 2.02 2.03 2.03.01 2.03.01 2.03.02 2.04 2.04.01 2.04.02 2.04.03 µC/TCP-IP Architecture ......................................................................................................25 Your Application ............................................................................................................................27 LIB (Libraries) ................................................................................................................................27 BSD Socket API Layer ...................................................................................................................27 TCP/IP Layer ..................................................................................................................................27 IF Layer...........................................................................................................................................28 NIC Layer .......................................................................................................................................28 PHY Layer ......................................................................................................................................29 CPU Layer ......................................................................................................................................29 RTOS Layer ....................................................................................................................................29 Block Diagram ................................................................................................................................30 Directories.......................................................................................................................................31 µC/TCP-IP Directories ................................................................................................................31 Support Directories .........................................................................................................................32 Test Code Directories......................................................................................................................33 Task model......................................................................................................................................34 µC/TCP-IP Tasks and Priorities......................................................................................................35 Receiving a Packet ..........................................................................................................................35 Sending a Packet .............................................................................................................................37 4 3.01 3.01.01 3.01.02 3.01.03 3.01.04 Buffer Management..............................................................................................................39 Buffer Statistics...............................................................................................................................40 Buffer Statistics, Getting SMALL buffer statistics .........................................................................41 Buffer Statistics, Getting LARGE buffer statistics .........................................................................42 Buffer Statistics, Resetting the Maximum count of SMALL buffers used .....................................42 Buffer Statistics, Resetting the Maximum count of LARGE buffers used......................................42 4.01 4.01.01 Timer Management ..............................................................................................................43 Timer Statistics ...............................................................................................................................43 Timer Statistics, Getting statistics...................................................................................................44 5.01 5.02 5.03 5.04 ASCII Utilities..........................................................................................................................45 String to MAC address, NetASCII_Str_to_MAC() ........................................................................45 MAC address to String, NetASCII_MAC_to_Str() ........................................................................46 String to IP address, NetASCII_Str_to_IP() ...................................................................................47 IP address to String, NetASCII_IP_to_Str() ...................................................................................48 6.01.01 6.01.02 6.02 6.03.01 6.03.02 6.03.03 6.03.04 6.03.05 6.03.06 6.03.07 6.03.08 6.03.09 6.03.10 6.03.11 6.03.12 6.03.13 BSD v4 Socket Interface ...................................................................................................49 UDP Socket Calls............................................................................................................................50 TCP Socket Calls ............................................................................................................................51 Data Structures................................................................................................................................52 accept() TCP ...............................................................................................................................53 bind() TCP/UDP ......................................................................................................................55 close() TCP/UDP ......................................................................................................................57 connect() TCP/UDP ......................................................................................................................58 inet_addr().......................................................................................................................................60 inet_ntoa() .......................................................................................................................................62 listen() TCP...............................................................................................................................64 recv() TCP/UDP......................................................................................................................66 recvfrom() TCP/UDP......................................................................................................................69 select() TCP/UDP .....................................................................................................................72 send() TCP/UDP .....................................................................................................................74 sendto() TCP/UDP .....................................................................................................................77 socket() TCP/UDP .....................................................................................................................80 7.10 Micriµm Socket Layer .........................................................................................................82 µC/TCP-IP Socket Error Codes...................................................................................................83 5 8.01 8.02 8.02 8.03 8.04 8.05.01 8.05.02 8.05.03 8.05.04 8.05.05 8.05.06 8.05.07 8.05.08.01 8.05.08.02 8.05.09 8.05.10 8.06 8.06.01 8.06.02 8.06.03 NIC Drivers................................................................................................................................84 Directories and Files .......................................................................................................................84 Interfacing to µC/TCP-IP.............................................................................................................85 ISRs, net_bsp_a.asm .......................................................................................................................86 net_bsp.c .........................................................................................................................................87 net_nic.c ..........................................................................................................................................88 net_nic.c, NetNIC_Init() .................................................................................................................89 net_nic.c, NetNIC_IntEn()..............................................................................................................90 net_nic.c, NetNIC_ConnStatusGet()...............................................................................................91 net_nic.c, NetNIC_ISR_Handler()..................................................................................................92 net_nic.c, NetNIC_RxPktGetSize() ................................................................................................93 net_nic.c, NetNIC_RxPkt().............................................................................................................94 net_nic.c, NetNIC_RxPktDiscard() ................................................................................................98 net_nic.c, NetNIC_TxPktPrepare().................................................................................................99 net_nic.c, NetNIC_TxPkt() ...........................................................................................................100 net_nic.c, NetNIC_RxISR_Handler() ...........................................................................................102 net_nic.c, NetNIC_TxISR_Handler() ...........................................................................................104 net_os.c .........................................................................................................................................106 net_os.c, NetOS_NIC_Init()..........................................................................................................106 net_os.c, NetOS_NIC_TxRdyWait() ............................................................................................108 net_os.c, NetOS_NIC_TxRdySignal()..........................................................................................109 9.01 9.01.01 9.01.02 9.02 9.02.01 9.02.02 9.02.03 9.03 9.03.01 9.03.02 9.04 9.04.01 9.04.02 9.05 9.05.01 9.05.02 9.06 9.06.01 9.06.02 9.06.03 9.06.04 9.07 9.07.01 9.07.02 9.07.03 9.08 9.08.01 9.08.02 Configuration Manual ........................................................................................................110 Network Configuration .................................................................................................................111 Network Configuration, NET_CFG_INIT_CFG_VALS..............................................................111 Network Configuration, NET_CFG_OPTIMIZE .........................................................................113 Debug Configuration.....................................................................................................................114 Debug Configuration, NET_DBG_CFG_DBG_INFO_EN..........................................................114 Debug Configuration, NET_DBG_CFG_MEM_CLR_EN ..........................................................114 Debug Configuration, NET_DBG_CFG_TEST_EN ....................................................................114 Argument Checking Configuration...............................................................................................115 Argument Checking Configuration, NET_ERR_CFG_ARG_CHK_EXT_EN ............................115 Argument Checking Configuration, NET_ERR_CFG_ARG_CHK_DBG_EN ...........................115 Counters Configuration.................................................................................................................116 Counters Configuration, NET_CTR_CFG_STAT_EN.................................................................116 Counters Configuration, NET_CTR_CFG_ERR_EN...................................................................116 Timers Configuration....................................................................................................................117 Timers Configuration, NET_TMR_CFG_NBR_TMR .................................................................117 Timers Configuration, NET_TMR_CFG_TASK_FREQ .............................................................117 Network Buffers Configuration ....................................................................................................118 Network Buffers Configuration, NET_BUF_CFG_NBR_SMALL..............................................119 Network Buffers Configuration, NET_BUF_CFG_NBR_LARGE..............................................119 Network Buffers Configuration, NET_BUF_CFG_DATA_SIZE_SMALL ................................119 Network Buffers Configuration, NET_BUF_CFG_DATA_SIZE_LARGE.................................119 NIC (Network Interface Controller) Configuration ......................................................................120 NIC Configuration, NET_NIC_CFG_TX_RDY_INIT_VAL ......................................................120 NIC Configuration, NET_NIC_CFG_INT_CTRL_EN ................................................................120 NIC Configuration, NET_NIC_CFG_RD_WR_SEL ...................................................................120 Network Interface Layer Configuration........................................................................................121 Network Interface Layer Configuration, NET_IF_CFG_TYPE ...................................................121 Network Interface Layer Configuration, NET_IF_CFG_ADDR_FLTR_EN...............................121 6 9.09 9.09.01 9.09.02 9.09.03 9.09.04 9.10 9.10.01 9.10.02 9.11 9.12 9.12.01 9.12.02 9.12.03 9.13 9.13.01 9.13.02 9.13.03 9.13.04 9.13.05 9.13.06 9.13.07 9.14 9.14.01 9.14.02 9.14.03 9.14.04 9.14.05 9.14.06 9.14.07 9.14.08 9.14.09 9.14.10 9.14.11 9.14.12 9.15 9.15.01 9.15.02 9.16 9.16.01 9.16.02 ARP (Address Resolution Protocol) Configuration ......................................................................122 ARP Configuration, NET_ARP_CFG_HW_TYPE......................................................................122 ARP Configuration, NET_ARP_CFG_PROTOCOL_TYPE .......................................................122 ARP Configuration, NET_ARP_CFG_NBR_CACHE.................................................................122 ARP Configuration, NET_ARP_CFG_ADDR_FLTR_EN ..........................................................122 ICMP (Internet Control Message Protocol) Configuration ...........................................................123 ICMP Configuration, NET_ICMP_CFG_TX_SRC_QUENCH_EN............................................123 ICMP Configuration, NET_ICMP_CFG_TX_SRC_QUENCH_SIZE.........................................123 Transport Layer Configuration, NET_CFG_TRANSPORT_LAYER_SEL.................................124 UDP (User Datagram Protocol) Configuration .............................................................................125 UDP Configuration, NET_UDP_CFG_APP_API_SEL ...............................................................125 UDP Configuration, NET_UDP_CFG_RX_CHK_SUM_DISCARD_EN...................................125 UDP Configuration, NET_UDP_CFG_TX_CHK_SUM_EN ......................................................126 TCP (Transport Control Protocol) Configuration, NET_TCP_CFG_NBR_CONN .....................127 TCP, NET_TCP_CFG_NBR_CONN ...........................................................................................127 TCP, NET_TCP_CFG_RX_WIN_SIZE_OCTET ........................................................................127 TCP, NET_TCP_CFG_TX_WIN_SIZE_OCTET ........................................................................127 TCP, NET_TCP_CFG_TIMEOUT_CONN_MAX_SEG_SEC ...................................................127 TCP, NET_TCP_CFG_TIMEOUT_CONN_ACK_DLY_MS .....................................................127 TCP, NET_TCP_CFG_TIMEOUT_CONN_RX_Q_MS .............................................................128 TCP, NET_TCP_CFG_TIMEOUT_CONN_TX_Q_MS..............................................................128 BSD v4 Sockets Configuration .....................................................................................................129 BSD v4 Sockets Configuration, NET_SOCK_CFG_FAMILY ....................................................129 BSD v4 Sockets Configuration, NET_SOCK_CFG_NBR_SOCK ..............................................129 BSD v4 Sockets Configuration, NET_SOCK_CFG_BLOCK_SEL.............................................129 BSD v4 Sockets Configuration, NET_SOCK_CFG_ SEL_EN....................................................129 BSD v4 Sockets Configuration, NET_SOCK_CFG_SEL_NBR_EVENTS_MAX......................129 BSD v4 Sockets Configuration, NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX ............130 BSD v4 Sockets Configuration, NET_SOCK_CFG_PORT_NBR_RANDOM_BASE ...............130 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_RX_Q_MS .............................130 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_CONN_REQ_MS ..................130 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_CONN_ACCEPT_MS ...........130 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_CONN_CLOSE_MS..............130 BSD v4 API Configuration, NET_BSD_CFG_API_EN ..............................................................130 Connection Manager Configuration..............................................................................................132 Connection Manager Configuration, NET_CONN_CFG_FAMILY............................................132 Connection Manager Configuration, NET_CONN_CFG_NBR_CONN......................................132 Application-Specific Configuration, app_cfg.h ............................................................................133 Application-Specific Configuration, Operating System Configuration ........................................133 Application-Specific Configuration, uC_CFG_OPTIMIZE_ASM_EN .......................................134 10.01 10.02.01 10.02.02 10.02.03 10.02.04 10.02.05 10.02.06 10.02.07 10.03 Debug Management ...........................................................................................................135 Network Debug Information Constants ........................................................................................135 Check Network Status, NetDbg_ChkStatus() ...............................................................................136 Check Network Resources Lost Status, NetDbg_ChkStatusRsrcLost() .......................................137 Check Network Resources Low Status, NetDbg_ChkStatusRsrcLow() .......................................138 Check Network Buffers Status, NetDbg_ChkStatusBufs()...........................................................139 Check Network Timers Status, NetDbg_ChkStatusTmrs()...........................................................140 Check Network Connections Status, NetDbg_ChkStatusConns() ................................................141 Check TCP Layer Status, NetDbg_ChkStatusTCP() ....................................................................143 Network Debug Monitor Task ......................................................................................................144 µC/TCP-IP Licensing Policy ............................................................................................145 7 Introduction µC/TCP-IP is a compact, reliable, high performance TCP/IP protocol stack. Built from the ground up with Micrium's renowned quality, scalability and reliability, µC/TCP-IP enables the rapid configuration of required network options to minimize your time to market. µC/TCP-IP is the result of many man-years of development. The source code for µC/TCP-IP contains over 100,000 lines of the cleanest, most consistent ANSI C source code you will ever find in a TCP/IP stack implementation. C was chosen because C is still the most predominant language in the embedded industry. Over 50% of the code actually consists of comments. Most global variables and all functions are described. References to RFC (Request For Comments) are referenced in the code when applicable. The code is designed to be used with just about any CPU, RTOS and NIC (Network Interface Controller). I.1 Portable µC/TCP-IP was designed for resource constrained embedded applications. Although µC/TCP-IP can work on some 8 and 16-bit processors, µC/TCP-IP will work best with 32 or 64-bit CPUs. I.2 Scalable The memory footprint of µC/TCP-IP can be adjusted at compile time based on the features you need and the desired level of run-time argument checking. Also, throughout µC/TCP-IP, we keep track of statistics and, some of those can be disabled in order to further reduce the footprint. 8 I.3 Coding Standards Coding standards have been established early in the design of µC/TCP-IP and include the following: - C coding style Naming convention for #define constants, macros, variables and functions Commenting Directory structure These conventions makes µC/TCP-IP the cleanest TCP/IP stack implementation in the industry and makes it easier to attain third party certification as outlined in the next section. I.4 Third Party Certification µC/TCP-IP has been designed from the ground up to be certifiable for use in avionics as well as medical and other safety critical products. A company called Validated Software is preparing a Validation Suite(tm) for µC/TCP-IP to provide all of the documentation necessary to deliver µC/TCP-IP as a pre-certifiable software component for safety critical systems, including avionics RTCA DO-178B and EUROCAE ED-12B, medical FDA 510(k), and IEC 61058 standard for transportation and nuclear systems. The very affordable Validation Suite(tm), is available through Validated Software. It will be immediately certifiable for the highest criticality systems, including DO-178B Level A, Class III medical devices, and SIL3/SIL4 IEC-certified systems. For more information, check out the µC/TCP-IP page on the Validated Software web site (www.ValidatedSoftware.com). If your product is NOT safety critical, you should view the certification as proof that µC/TCP-IP is a very robust and highly reliable TCP/IP stack. I.5 MISRA C The source code for µC/TCP-IP follows the Motor Industry Software Reliability Association (MISRA) C Coding Standards. These standards were created by MISRA to improve the reliability and predictability of C programs in critical automotive systems. Members of the MISRA consortium include Delco Electronics, Ford Motor Company, Jaguar Cars Ltd., Lotus Engineering, Lucas Electronics, Rolls-Royce, Rover Group Ltd., and other firms and universities dedicated to improving safety and reliability in automotive electronics. Full details of this standard can be obtained directly from the MISRA web site, http://www.misra.org.uk. 9 I.6 RTOS µC/TCP-IP assumes the presence of an RTOS. However, we don’t make any assumptions about which RTOS you will be using with µC/TCP-IP. The only requirements from the RTOS are: 1) 2) The RTOS must be able to support multiple tasks The RTOS must provide binary and counting semaphore management services µC/TCP-IP contains an encapsulation layer that allows you to use just about any commercial or open source RTOS. In other words, details about the RTOS you use are hidden from µC/TCP-IP. µC/TCP-IP includes the encapsulation layer for µC/OS-II, The Real-Time Kernel. I.7 Single Network Interface Controller (NIC) The current version of µC/TCP-IP only allows the use of a single NIC for any one product/application. At this time, the single NIC must be an Ethernet controller. Any Ethernet-type NIC may be used provided a driver with the appropriate API and BSP software is provided. Interface to a specific NIC (i.e. chip) is encapsulated in a couple of files and it’s quite easy to adapt different NICs to µC/TCP-IP. We are currently working on adding PPP (Point-to-Point Protocol) support to µC/TCP-IP. µC/TCP-IP Protocols I.8 µC/TCP-IP consists of the following protocols: - I.9 NIC driver Interface (Ethernet) ARP (Address Resolution Protocol) IP (Internet Protocol) ICMP (Internet Control Message Protocol) UDP (User Datagram Protocol) TCP (Transport Control Protocol) Sockets (BSD v4) Application Protocols µC/TCP-IP can work with well known application layer protocols such as DHCP, DNS, TFTP, HTTP servers (web server), FTP servers, SNTP clients, SNMP clients and more. 10 I.10 µC/TCP-IP Limitations By design, we have limited some of the features of µC/TCP-IP. Table I-1 describes those limitations. Supports a single network interface and one host IP address Supports a single default gateway No IP forwarding/routing No IP multicasting No IP transmit fragmentation No IP Security options RFC #1108 No ICMP Address Mask Agent/Server RFC #1122, Section 3.2.2.9 No TCP Urgent Data No TCP Security & Precedence Table I-1, µC/TCP-IP limitations for current software version 11 Chapter 1 Getting Started with µC/TCP-IP This chapter provides examples on how to use µC/TCP-IP. We decided to include this chapter early in the µC/TCP-IP manual so you could start using µC/TCP-IP as soon as possible. In fact, we assume you know little about µC/TCP-IP and networking. Concepts will be introduced as needed. The sample code was compiled using the IAR Embedded Workbench V4.31a (or higher) for the ARM processor. Tests were done using a Cogent CSB337 (ARM9 CPU) board which has an AT91RM9200 EMAC Network Interface Controller (NIC). We selected an ARM processor because of its popularity in the networking world. 1.00 Installing µC/TCP-IP The distribution of µC/TCP-IP is placed in a ZIP file called: uC-TCPIP-Vxyy.zip. The ZIP file contains all the source code and documentation for µC/TCP-IP. Support modules are needed by the protocol stack and provided in the µC/TCP-IP distribution. Support modules are placed in sub-directories as shown in Figure 1-1. Figure 1-1, Test setup 12 \CPU This sub-directory contains CPU specific header files and code. For example, header files would contain definition of CPU registers, I/O ports, timer registers and more. This sub-directory contains other sub-directories for each type of CPU manufacturer and actual CPUs. The subdirectories are organized as follows: \CPU\\ This directory is needed when testing code that uses the protocol stack on an actual target. \EvalBoards This sub-directory contains sample code for evaluation boards. The sub-directories are organized as follows: \EvalBoards\ \ \ \ The distribution contains sample code for the Cogent CSB337 Evaluation Board. \uC-CPU This sub-directory contains CPU specific code which depends on the compiler used. The uC-CPU sub-directory also contains additional sub-directories which are organized as follows: \uC-CPU\ \ The uC-CPU sub-directory (and sub-directory) contains three files: cpu_def.h This file (which is found directly in the uC-CPU directory) declares #define constants for CPU alignment, endianness, and other generic declarations. cpu.h This file is placed in the \uC-CPU\ \ directory and contains type definitions for 8, 16 and 32-bit signed and unsigned numbers. These are needed to be independent of processor and compiler word size definitions. In other words, µC/TCP-IP always uses its own datatypes instead of the C data types. cpu.h also declares other #define values, data types and function prototypes. cpu_a.asm This file is placed in the \uC-CPU\ \ directory and contains code to enable/disable interrupts for the specific CPU. \uC-LIB This sub-directory contains libraries that are common to all modules. The files in this directory are needed if you compile µC/TCP-IP because we use the code found in these files. The directory contains the following files: lib_def.h This file defines such things as TRUE/FALSE but, all #defines in this file starts with DEF_ and thus TRUE/FALSE are actually DEF_TRUE and DEF_FALSE. 13 lib_mem.c and lib_mem.h These files contain code to replace the standard library functions memclr(), memset(), memcpy() and memcmp(). These functions are replaced by Mem_Clr(), Mem_Set(), Mem_Copy() and Mem_Cmp(), respectively. The reason we declared our own functions is for third party certification purposes. Specifically, FAA (Federal Aviation Administration) certification requires that ALL the source code be available to certify a product that is intended to be air worthy. lib_str.c and lib_str.h These files contain code to replace the standard library functions str???() with their equivalent Str_???() functions. Again, this is to simplify third party certification for avionics and medical use. \uC-TCPIP This is the main sub-directory for µC/TCP-IP. This sub-directory contains additional subdirectories for the different components of µC/TCP-IP. Code in \uC-TCPIP is independent of the CPU used and its interrupt structure, the actual hardware (whether memory or I/O mapped), etc. In other words, this code should be able to be used unchanged on a large number of different platforms. µC/TCP-IP assumes the presence of a Real-Time Operating System (RTOS). However, µC/TCP-IP can work with just about any RTOS as long as the RTOS allows you to create tasks, assign priorities to tasks and supports semaphores. Most RTOSs provide these basic functions. 14 1.01 Example #1 Examples #1 is used to show you the basic architecture of µC/TCP-IP and build an empty application. The application also uses µC/OS-II as the RTOS. Figure 1-2 shows the test setup for Example #1. A Windows-based PC and the target system were connected to a 10 Mbps 10-Base-T hub. The PC’s IP address was set to 10.10.10.111 and the target address was hard coded to 10.10.10.64. Cogent CSB337 (ARM9) Board µC/OS-II & µC/TCP-IP Windows-based PC IP = 10.10.10.111 IP = 10.10.10.64 Ping 10.10.10.64 10 Mbps Hub Figure 1-2, Test setup This example contains enough code to be able to ‘ping’ the board. ‘ping’ is a utility found on most computer (Windows-based PCs, Linux, Unix, etc.) and allows you to see if a particular network enabled device is connected to your network. The IP address of the board is forced to 10.10.10.64 so, if you were to have a similar setup, you would be able to issue the following command from a command-prompt: ping 10.10.10.64 Ping (on the PC) should reply back with the ping time to the target. We had ping times of less than 10 milliseconds. Figure 1-3 shows the directory tree of the different components needed to build a µC/TCP-IP based application. For now, we will examine the contents of the following directories: \Micrium\Software\EvalBoards\Cogent\CSB337\IAR\BSP \Micrium\Software\EvalBoards\Cogent\CSB337\IAR\uC-Apps\Ex1 15 All Micrium software is placed under \Micrium\Software Processor specific header files. These are provided by the chip manufacturer and define CPU I/O registers. All sample code is placed under the ‘EvalBoards’ sub-directory. Specific evaluation boards are further characterized by the board manufacturer (Cogent) and the specific board (CSB337) followed by the tools used to build the example (IAR’s Embedded Workbench). This directory contains files that are common to all examples. BSP stands for ‘Board Support Package’. This directory contains files that are specific to the example, in this case, Example #1. This directory also contains build specific files. The ‘Exe’ directory contains the executable code that can be downloaded to the target. This directory contains files that are CPU and compiler specific. The directory contains cpu_c.c, cpu_a.asm and cpu_def.h. This directory contains library files to replace standard library functions such as memset(), memcpy(), strcpy(), strcat(), etc. The reason we do this is to simplify third party certification of your products. This directory contains the processor specific source files for the µC/OS-II ARM port running in ARM mode and using the IAR toolchain. This directory contains the processor independent source files for the µC/OS-II RTOS. This is the main directory for µC/TCP-IP. µC/TCP-IP files related to network interfaces are placed under the IF sub-directory. However, µC/TCP-IP currently only supports Ethernet and this directory contains code which is independent of any specific Ethernet chips. All Network Interface Controllers (NIC) driver software is found in the NIC subdirectory. The AT91RM9200 directory contains the code specific to this NIC. µC/TCP-IP assumes the presence of an RTOS and the OS directory contains ports to different RTOSs. The uCOS-II directory contains the µC/OS-II I specific files for µC/TCP-IP. driver software is found in the NIC sub-directory. The AT91RM9200 directory contains the code specific to this NIC. This directory contains the CPU, NIC and RTOS independent code for µC/TCP-IP. Figure 1-3, Directory tree for µC/TCP-IP based project 16 1.01.01 BSP (Board Support Package) As described in Figure 1-3, the BSP (Board Support Package) directory contains common code that can be used in more than one example. Specifically, the BSP directory contains the following files: bsp.c bsp.h net_bsp.c net_bsp.h net_isr.c csb33x_lnk_ram.xcl bsp.c and bsp.h BSP stands for Board Support Package and we place ‘services’ that the board provides in such a file. In our case, bsp.c contains I/O, timer initialization code, LED control code, and more. The I/Os that we use on the board are initialized when BSP_Init() is called. The concept of a BSP is to hide the hardware details from the application code. It is important that functions in a BSP reflect the function and does not make references to any CPU specifics. For example, the code to turn on an LED is called LED_On() and not csb337_led(). If you use LED_On() in your code, you can easily port your code to another processor (or board) simply by rewriting LED_On() to control the LEDs on a different board. The same is true for other services. You will also notice that BSP functions are prefixed with the function’s group. LED services start with LED_, Timer services start with Tmr_, etc. In other words, BSP functions don’t need to be prefixed by BSP_. net_bsp.c, net_bsp.h and net_isr.c This file contains code specific to the NIC (Network Interface Controller) used and other functions that are dependent of the hardware. Specifically, this file contains code to read data from and write data to the NIC, provide delay functions, control power to the NIC, get a time stamp and more. csb33x_lnk_ram.xcl This file contains the linker command file for the IAR toolchain. This file specifies where code and data is placed in memory. In this case, all the code is placed in RAM to make it easier to debug. When you are ready to deploy your product, you will most likely need to create a csb33x_lnk_flash.xcl to locate your code in Flash instead of RAM. 17 1.01.02 Ex1 This directory contains the code for this example and consist of: app.c app_cfg.h Ex1.* fs_conf.h includes.h net_cfg.h os_cfg.h app.c This file contains the application code for example #1. As with most C programs, code execution start at main() which is shown in listing 1-1. The example #1 starts µC/TCP-IP and a set of services that run on top of it. These services (like web server) are sold separately from µC/TCP-IP. See section 1.02 to know how to disable some services in the example if you have not purchased them. Listing 1-1 int main (void) { #if (OS_TASK_NAME_SIZE >= 16) CPU_INT08U err; #endif BSP_Init(); /* (1) Initialize BSP. APP_TRACE_DEBUG("Initialize OS...\n"); OSInit(); /* (2) Initialize OS. /* (3) Create start task. OSTaskCreateExt( AppTaskStart, (void *)0, (OS_STK *)&AppStartTaskStk[APP_START_OS_CFG_TASK_STK_SIZE - 1], APP_START_OS_CFG_TASK_PRIO, APP_START_OS_CFG_TASK_PRIO, (OS_STK *)&AppStartTaskStk[0], APP_START_OS_CFG_TASK_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* (4) Give a name to tasks. #if (OS_TASK_NAME_SIZE >= 16) OSTaskNameSet(OS_TASK_IDLE_PRIO, "Idle task", &err); OSTaskNameSet(OS_TASK_STAT_PRIO, "Stat task", &err); OSTaskNameSet(APP_START_OS_CFG_TASK_PRIO, "Start task", &err); #endif APP_TRACE_DEBUG("Start OS...\n"); OSStart(); /* (5) Start OS. */ */ */ */ */ } L1-1(1) We start by initializing the I/Os we’ll be using on this board as well as the µC/OS-II tick interrupt and the AT91RM9200’s interrupt controller. 18 L1-1(2) The example code assumes the presence of an RTOS called µC/OS-II and OSInit() is used to initialize µC/OS-II. L1-1(3) µC/OS-II requires that we create at least ONE application task. This is done by calling OSTaskCreateExt() and specifying the task start address, the top-of-stack to use for this task, the priority of the task and a few other arguments. L1-1(4) µC/OS-II allows you to assign names to tasks that have been created. We thus assign a name to the application task. These names are used mostly during debug. In fact, task names are displayed during debug when using IAR’s C-Spy debugger (or other µC/OS-II aware debuggers). L1-1(5) In order to start multitasking, your application needs to call OSStart(). OSStart() determines which task, out of all the tasks created, will get to run on the CPU. In this case, µC/OS-II will run AppTaskStart(). The first, and only ‘application’ task that µC/OS-II runs is shown in listing 1-2. Listing 1-2 static void AppTaskStart (void { (void)p_arg; *p_arg) /* Prevent compiler warning. */ APP_TRACE_DEBUG("Initialize interrupt controller...\n"); BSP_InitIntCtrl(); /* (1) Initialize interrupt controller. */ APP_TRACE_DEBUG("Initialize OS timer...\n"); Tmr_Init(); /* (2) Initialize OS timer. */ #if (OS_TASK_STAT_EN > 0) APP_TRACE_DEBUG("Initialize OS statistic task...\n"); OSStatInit(); /* (3) Initialize OS statistic task. #endif #if APP_FS_ENABLED AppInit_FS(); #endif AppInit_TCPIP(); #if APP_DHCPc_ENABLED AppInit_DHCPc(); #endif */ /* (4) Initialize file system. */ /* (5) Initialize TCP/IP stack. */ /* (6) Initialize DHCP client. */ #if APP_HTTPs_ENABLED APP_TRACE_DEBUG("Initialize HTTP server...\n"); HTTPs_Init(); /* (7) Initialize HTTP server. #endif #if APP_FTPs_ENABLED APP_TRACE_DEBUG("Initialize FTP server...\n"); /* (7) Initialize FTP server. FTPs_Init(AppIP_Addr, FTPs_CFG_DTP_IPPORT); #endif #if APP_TFTPs_ENABLED APP_TRACE_DEBUG("Initialize TFTP server...\n"); TFTPs_Init(); /* (7) Initialize TFTP server. #endif 19 */ */ */ #if APP_DNSc_ENABLED DNSc_Init(AppIP_DNS_Srvr); /* (8) Initialize DNS client. */ /* Test DNS client. */ #if APP_FTPc_ENABLED AppTest_FTPc(); #endif /* (8) Test FTP client. */ #if APP_POP3c_ENABLED AppTest_POP3c(); #endif /* (8) Test POP3 client. */ #if APP_SMTPc_ENABLED AppTest_SMTPc(); #endif /* (8) Test SMTP client. */ #if APP_SNTPc_ENABLED AppTest_SNTPc(); #endif /* (8) Test SNTP client. */ AppTest_DNSc(); #endif APP_TRACE_DEBUG("Create application task...\n"); AppTaskCreate(); /* (9) Create application task. APP_TRACE_DEBUG("\n******************************************************************"); APP_TRACE_DEBUG("\n* *"); APP_TRACE_DEBUG("\n* Micrium uC/TCP-IP TTCP Performance measurement *"); APP_TRACE_DEBUG("\n* AT91RM9200 on Cogent CSB337 SDK *"); APP_TRACE_DEBUG("\n* *"); APP_TRACE_DEBUG("\n******************************************************************"); APP_TRACE_DEBUG("\n"); TTCP_Init(); /* (10)Initialize TTCP application #endif */ */ LED_Off(1); LED_Off(2); LED_Off(3); while (DEF_YES) { /* OSTimeDlyHMSM(0, 0, 0, 100); } Task body, always written as an infinite loop. */ } L1-2(1) AppTaskStart() starts off by initializing the AT91RM9200 interrupt controller and start handling interruptions. L1-2(2) Enable the timer tick source from the microcontroller. µC/OS-II needs a time base to determine when it’s time to preempt a task and let the next task scheduled to run. Details as to how this is done can be found in the µC/OS-II book. L1-2(3) If you set OS_TASK_STAT_EN to 1 in os_cfg.h then the µC/OS-II statistic task is initialized by calling OSStatInit(). OSStatInit() basically figures out how fast the CPU is running in order to determine how much CPU usage your application will be consuming. Details as to how this is done can be found in the µC/OS-II book. L1-2(4) Initialize File System. This is optional. File System is used by some µC/TCP-IP services. If you purchased the µC/FTPs, µC/HTTPs or µC/TFTPs, you also need µC/FS. L1-2(5) We then initialize the TCP/IP stack by calling NetInit(). NetInit() initializes all of µC/TCP-IP’s data structures and creates two tasks. One task waits for packets to be received and the other task manages timers. 20 IMPORTANT Net_Init() returns an error code indicating whether the call was successful or not. If Net_Init() returns NET_ERR_NONE then Net_Init() properly initialized µC/TCP-IP. However, if Net_Init() returns something other than NET_ERR_NONE then you must examine the error code to determine the source of the error. Just as important, Net_Init() ‘aborts’ the initialization as soon as it finds an error. In other words, if you don’t examine the return value you might have a partially initialized µC/TCP-IP and the results are unpredictable. L1-2(6) Each ‘node’ on a TCP/IP network requires a unique address. This is called the IP address and consists of a 32-bit value. An IP address is generally represented as four decimal numbers separated by a dot (Dotted Decimal Notation). Each value corresponds to an eight bit value and is assigned to its corresponding position in the 32-bit word. For example, 160.110.80.40 corresponds to an IP address of 0xA06E5028. You should note here that the address is determined at run-time (Dynamic IP address) by the use of a service called DHCP (dynamic host configuration protocol). The optional µC/DHCPc module implements this protocol that allows the IP address of your target system (and many other information) to be assigned by another computer on your network (typically DHCP server). If you have not purchased the µC/DHCPc module, you should note that the address have to be determined at compile time by your test code (Static IP address). L1-2(7) Initialize the server modules (µC/FTPs, µC/HTTPs or µC/TFTPs). If you have not purchased one or all of them, please look at section 1.02 how to disable them. Also, please look at their respective documentation about how to configure them. L1-2(8) Test the optional client modules: • µC/DNSc client module: The DNS (domain name service) protocol enable to resolve fully qualified domain name (FQDN) to IP addresses. Ex.: www.micrium.com resolved to “198.66.208.142”. This enable the use of DNS name in code instead of the IP addresses, less descriptive and subject to change over time. • µC/FTPc client module: The FTP (file transfer protocol) protocol enable the transfer of files over internet. You can transfer any kind of file to your target or from your target to your PC using this protocol. The µC/FTPc client module can get and store files directly in the target’s RAM or using a file system. In this case, you will need to purchase the µC/FS module. • µC/POP3c client module: The POP3 (post office protocol 3) protocol enable the reception of email messages from a mailserver. The email messages are stored in a user’s mailbox in the server and pulled by the user. If you have to receive messages on your target from other computers, you need µC/POP3c client module. You also need µC/DNSc client module since POP3 servers are usually addressed by their DNS names. • µC/SMTPc client module: The SMTP (simple mail transfer protocol) protocol enable transfer of email messages over internet. The SMTP protocol is a push protocol. The sender of the message pushes the message to the recipient’s mailbox. If you have to send email message from your target to other computer, you need µC/SMTPc client module. You also need µC/DNSc client module since POP3 servers are usually addressed by their DNS names. 21 • µC/SNTPc client module: The SNTP (simple network time protocol) protocol enable the synchronization of computer’s real time clocks over the internet. The time information transferred is and offset from NTP epoch (1900-01-01 00:00:00 GMT) and the resolution is the millisecond. The µC/SNTPc client module transfers the current time over the internet but have no provision to store & update the time. For this feature, you need the µC/CLK module. µC/CLK and µC/SNTPc modules work independently. µC/CLK moduke can be initialized by any time source, including network source using µC/SNTPc. µC/SNTPc module can be used to synchronize any real-time clock, including µC/CLK, or just get a snapshot of the current time. L1-2(9) Start the application task. The application task enters an infinite loop and blinks one of the LEDs. L1-2(10) Initialize µC/TTCP module. This module enable user to make performance tests on µC/TCP-IP stack. With this simple application code, another computer on the same network can send a ping Echo Request to this target. app_cfg.h This is an application-specific configuration file used to configure Micrium products and/or non-Micriumrelated application files. You MUST include this file in your application because some of the modules in µC/TCP-IP assumes the presence of this file. app_cfg.h contains #defines to specify the task priorities of each of the tasks in your application (including those of µC/TCP-IP) as well as the stack size for those tasks. The reason all task priorities are placed in one file is to make it easier to ‘see’ the task priorities for your entire application in one place. includes.h includes.h is a ‘master’ header file that contains #include directives to include other header files. This is done to make the code cleaner to read and easier to maintain. Note that we assume the presence of includes.h. Ex1.* These files are IAR embedded workbench project files. net_cfg.h This file is used to configure µC/TCP-IP and defines the number of timers used in µC/TCP-IP, the number of buffers for packets reception and transmission, the number of ARP (Address Resolution Protocol) cache entries, the number of Sockets that your application can open and more. In all, there are about 50 or so #define to set in this file. os_cfg.h This file is used to configure µC/OS-II and defines the number maximum number of tasks that your application can have, which services will be enabled (semaphores, mailboxes, queues, etc.), the size of the idle and statistic task and more. In all, there are about 60 or so #define that you can set in this file. Each entry is commented and additional information about the purpose of each #define can be found in the µC/OS-II book. 22 1.02 Configuration of the Example #1 Demonstration of the capabilities of the µC/TCP-IP stack is hard without code using it. There is a lot of services that have been designed for TCP-IP over the years. Many of them have been implemented has optional modules to run over µC/TCP-IP. The example #1 integrates µC/TCP-IP and all the optional modules currently available. We are understanding that every client may get its own set of optional modules so we have to provide clients a way to disable the ones that they don’t have. Here is the way (using IAR tools) to disable optional modules and get a fully customized µC/TCP-IP demonstration example: When the example project file is loaded into IAR tools, the screen look like this: On the left pane, there is a list of different group of files included in the example, representing modules. Some are mandatory, some are optional. Mandatory modules: CSB337, µC/CPU, µC/LIB, µC/TCP-IP, µC/TTCP and µC/OS-II. Optional modules: µC/CLK, µC/DHCPc, µC/DNSc, µC/FS, µC/FTPc, µC/FTPs, µC/HTTPs, µC/POP3, µC/SMTPc, µC/SNTPc and µC/TFTPs. 23 Optional modules have interdependencies on other optional modules. µC/FTPs, µC/HTTPs and µC/TFTPs modules needs the FS module. µC/FTPc module may need it too, depending on configuration. µC/DNSc is needed if you use DNS names instead of IP addresses in your application for addressing other machines. To remove an optional module, there is two steps. First, select the corresponding group of files in the left, then press the “delete” key on your keyboard or select “remove” in the contextual menu. Then, select the “Ex1-Debug” entry in the left pane, select “options” in the contextual menu, then “C/C++ compiler”, then preprocessor pane. You will see a window like this: On the “Defined symbols” list, remove the entry corresponding to the module you want to remove. Ex: remove the APP_DHCPs_ENABLED entry if you want to remove the µC/DHCPc module. After you are removed all the module you haven’t purchased, you are ready to compile your own customized µC/TCP-IP example. 24 Chapter 2 µC/TCP-IP Architecture µC/TCP-IP was written from the ground up to be modular and easy to adapt to different CPUs (Central Processing Units), RTOSs (Real-Time Operating Systems), NICs (Network Interface Controllers) and compilers. Figure 2-1 shows a simplified block diagram of the different elements and their relationship. You will probably notice that all of the µC/TCP-IP files start with ‘net_’. This convention allows you to quickly identify files that belong to µC/TCP-IP. In fact, all functions and variables start with ‘Net’ and, all macros and #defines start with ‘NET_’. These and other conventions are described in the ‘µC/TCP-IP Coding Convention’ appendix. 25 Your Application LIB app_cfg.h net_cfg.h lib_def.h lib_mem.* lib_str.* BSD Socket API Layer net_bsd.c/h net_sock.c/h TCP/IP Layer net_ascii.c/h net_buf.c/h net_conn.c/h net_ctr.c/h net_stat.c/h net_tmr.c/h net_util.c/h net_arp.c/h net_icmp.c/h net_ip.c/h net_tcp.c/h net_udp.c/h Interface Specific (Ethernet) net.c/h net_cfg_net.h net_dbg.h net_def.h net_err.h net_type.h IF Layer net_if_pkt.c/h net_if.c.h µC/TCP-IP NIC Layer NIC Chip Specific net_nic.c/h net nic def.h PHY Specific NIC / CPU Specific net_bsp.c net_phy.c/h CPU Layer cpu_a.asm cpu.h cpu_def.h CPU RTOS Layer net_os.c/h NIC RTOS PHY Network Figure 2-1, Relationship between Application, µC/TCP-IP, CPU, NIC and RTOS 26 2.01.01 Your Application Your application needs to provide configuration information to µC/TCP-IP in the form of a C header files called app_cfg.h and net_cfg.h. app_cfg.h is an application specific configuration file that MUST be present in your application. app_cfg.h contains #defines to specify the task priorities of each of the tasks in your application (including those of µC/TCP-IP) as well as the stack size for those tasks. The reason all task priorities are placed in one file is to make it easier to ‘see’ the task priorities for your entire application in one place. Some of the configuration data in net_cfg.h consist of specifying how many buffers will be allocated to the TCP/IP stack, specify the number of timers to allocate to the stack, whether statistic counters will be maintained or not, whether the MAC (Media Access Control) address is obtained from the chip or is specified in the code, the number of ARP cache entries, whether UDP checksums are computed or not and more. In all, there are about 50 #define to set. However, most of the #define constants can be set to their recommended default value. 2.01.02 LIB (Libraries) Because µC/TCP-IP is designed to be used in safety critical applications, all ‘standard’ library functions like strcpy(), memset(), etc. have been re-written to follow the same quality as the rest as the protocol stack. 2.01.03 BSD Socket API Layer Your application interfaces to µC/TCP-IP using the well known BSD socket API (Application Programming Interface). You can either write your own TCP/IP applications using the BSD socket API or, you can purchase a number of off-the-shelf TCP/IP components (Telnet, Web server, FTP server, etc.) which all interface to the BSD socket interface. Note that the BSD socket layer is shown as a separate module but is actually part of µC/TCP-IP. Alternatively, you can use µC/TCP-IP’s own socket interface functions (net_sock.*). Basically, net_bsd.* is a layer of software to converts BSD socket calls to µC/TCP-IP socket calls. Of course, you would have a slight performance gain by interfacing directly to net_sock.* functions. Micrium network products uses the µC/TCP-IP socket interface functions. 2.01.04 TCP/IP Layer This layer contains most of the CPU, NIC, RTOS and compiler independent code for µC/TCP-IP. There are three categories of files in this section: 1) TCP/IP protocol specific files a. ARP (net_arp.*), b. ICMP (net_icmp.*), c. IP (net_ip.*), d. TCP (net_tcp.*), e. UDP (net_udp.*) 27 2) Support files a. ASCII conversions (net_ascii.*), b. Buffer management (net_buf.*), c. TCP/UDP connection management (net_conn.*), d. Counter management (net_ctr.*), e. Statistics (net_stat.*), f. Timer Management (net_tmr.*), g. other utilities (net_util.*). 3) Miscellaneous header files a. Master µC/TCP-IP header file (net.h) b. File containing error codes (net_err.h) c. Miscellaneous µC/TCP-IP data types (net_type.h) d. Miscellaneous definitions (net_def.h) e. Debug (net_dbg.h) f. Configuration definitions (net_cfg_net.h) 2.01.05 IF Layer The IF Layer understands about types of network interfaces (Ethernet, TokenRing, etc.). However, the current version of µC/TCP-IP only supports Ethernet interfaces. The IF layer is actually split into two sub-layers. net_if_pkt.* is the interface between the TCP/IP Layer and understands packet type devices. net_if_pkt.* could actually be used as-is with other packet type interfaces (other than Ethernet). net_if_char.* is the interface between the TCP/IP Layer and understands serial-character type devices. net_if.* contains the interface specifics but, independent of the actual chip (i.e. hardware). In other words, for Ethernet, net_if.* understands about Ethernet frames, MAC addresses, frame demultiplexing, and so on but, assumes nothing about actual Ethernet hardware. 2.01.06 NIC Layer µC/TCP-IP can work with just about any NIC (Network Interface Controller) and we have done everything we can to simplify the interface to different NICs. This layer knows about the specifics of the NIC: how to initialize the NIC, how to enable and disable interrupts from the NIC, how to find the size of a received packet, how to read a packet out of the NIC, how to write a packet to the NIC, how to set and get the NIC’s MAC (Media Access Control) address and more. In order to be independent of the ISR structure of your CPU and the mapping of the I/O registers of the NIC, we an additional file to encapsulate such details as the actual ISR(s) from the NIC and the method of reading and writing to the NIC registers. net_bsp.c contains the code to read and write values from and to the NIC, time delays, ISR handler, obtaining a time stamp from the environment and so on. This file is assumed to reside in your application. 28 2.01.07 PHY Layer Some NIC interfaces to physical layer devices which may need to be initialized and controlled. This layer is shown in Figure 2-1 as ‘dotted’ indicating that it’s not present with all NICs. In fact, some NICs have PHY control built-in. 2.01.08 CPU Layer µC/TCP-IP can work with either an 8, 16, 32 or even 64-bit CPU but, needs to have information about the CPU you are using. The CPU layer defines such things as the C data type corresponding to 16-bit and 32-bit variables, whether the CPU is little or big endian and, how interrupts are disabled and enabled on the CPU, etc. CPU specific files are found in the …\uC-CPU directory and, in order to adapt µC/TCP-IP to a different CPU, you would need to either modify the cpu*.* files or, create new ones based on the ones supplied in the uC-CPU directory. In general, it’s much easier to modify existing files because you have a better chance of not forgetting anything. 2.01.09 RTOS Layer µC/TCP-IP assumes the presence of an RTOS but, the RTOS layer allows µC/TCP-IP to be independent of any specific RTOS. µC/TCP-IP consists of two tasks. One task is responsible for handling packet reception and sends a response, and the other task is responsible for managing timers. As a minimum, the RTOS you use needs to provides the following services: 1) You need to be able to create at least two tasks (Rx packet task and the timer task) 2) Semaphore management (or the equivalent) and µC/TCP-IP needs to be able to create at least 2 semaphores for each socket and an additional 4 semaphores for internal use. 3) Provide timer management services µC/TCP-IP is provided with a µC/OS-II interface. If you use a different RTOS, you can use the net_os.* for µC/OS-II as a template to interface to the RTOS of your choice. We discuss the RTOS interface in a later chapter. 29 2.02 Block Diagram Figure 2-2 shows a block diagram of the modules found in µC/TCP-IP and their relationship. Also included are the names of the files that are related to µC/TCP-IP. Your Application app_cfg.h net_cfg.h µC/TCP-IP Sockets Sockets net_bsd.* net_sock.* net_bsd.* net_sock.* TCP UDP ICMP ICMP UDP TCP net_tcp.* net_udp.* net_icmp.* net_icmp.* net_udp.* net_tcp.* IP ARP ARP IP net_ip.* net_arp.* net_arp.* net_ip.* Buf net_buf.* IF IF net_if.* net_if.* Tmr Rx Tx net_tmr.* IF-Pkt IF-Pkt net_if_pkt.* net_if_pkt.* NIC net_nic.* Misc net.* net_ascii.* net_cfg_net.h net_conn.* net_ctr.* net_dbg.h net_def.h net_err.h net_stat.* net_type.h net_util.* CPU Your Application LIB cpu_def.h cpu*.* net_bsp.* lib_def.h lib_mem.* lib_str.* Network Figure 2-2, µC/TCP-IP Block Diagram 30 2.03 Directories The files shown in figure 2-1 and 2-2 are placed in a directory structure such as to group common elements. The µC/TCP-IP distribution contains the following directories: 2.03.01 µC/TCP-IP Directories \Micrium\Software\uC-TCPIP This is the main directory for µC/TCP-IP. \Micrium\Software\uC-TCPIP\IF This directory contains interface specific files. Currently, µC/TCP-IP only supports one type of interface, Ethernet. The Ethernet interface specific files are found in the following directories: \Micrium\Software\uC-TCPIP\IF\net_if_pkt.* net_if_pkt.* contain an interface layer between the NIC (Network Interface Controller) and the Ethernet interface layer. This file should not have to change as long as we are dealing with ‘packet’ oriented interfaces such as Ethernet and Arcnet. \Micrium\Software\uC-TCPIP\IF\Ether\net_if.* net_if.* contains the Ethernet interface specifics. This file should not need to be modified. \Micrium\Software\uC-TCPIP\NIC This directory contains device drivers for different interfaces. Currently, µC/TCP-IP only supports one type of interface, Ethernet. We tested µC/TCP-IP with two types of NICs: a SMC LAN91C111 and an Atmel AT91RM9200 CPU containing an on-chip NIC. The NIC specific code is thus found in the following directories: \Micrium\Software\uC-TCPIP\NIC\Ether\LAN91C111\net_nic*.* \Micrium\Software\uC-TCPIP\NIC\Ether\AT91RM9200\net_nic*.* Other Ethernet controller drivers will be placed under the Ether sub-directory. Note that other NIC drivers must also be called net_nic*.*. The directory determines which specific NIC your application will actually use. \Micrium\Software\uC-TCPIP\OS This directory contains the RTOS abstraction layer which allows you to use µC/TCP-IP with just about any commercial or in-house RTOS. You would place the abstraction layer for your own RTOS in a subdirectory under OS as follows: \Micrium\Software\uC-TCPIP\OS\rtos_name\net_os.* Note that you must always name the files for your RTOS abstraction layer net_os.*. µC/TCP-IP has been tested with µC/OS-II and the RTOS layer files for this RTOS are found in the following directory: \Micrium\Software\uC-TCPIP\OS\uCOS-II\net_os.* 31 \Micrium\Software\uC-TCPIP\Source This directory contains all the CPU, NIC and RTOS independent files as shown in figure 2-1 and 2-2. You should not have to change anything in this directory in order to use µC/TCP-IP. 2.03.01 Support Directories µC/TCP-IP are assumes the presence of a number of support files as described in this section. \Micrium\Software\CPU This directory contains files that are generally supplied by a CPU manufacturer and typically contains header files that define the access to CPU registers, I/O registers, timers and more. The name of the files are determined by the CPU manufacturer. \Micrium\Software\uC-CPU This directory contains files that are used to adapt to different CPUs/compilers. cpu_def.h This file contains definitions used by the other CPU specific files. In fact, cpu_def.h should be independent of the actual CPU used. Within the uC-CPU directory, we define processor specific files. \Micrium\Software\uC-CPU\cpu_type\compiler cpu.h This file contains definitions of data word sizes. Specifically, you define here what C data types are associated with 8, 16 and 32 bit integers and, 32 and 64 bit floating point numbers. cpu.h also defines endianess, critical section macros CPU_CRITICAL_ENTER() and CPU_CRITICAL_EXIT(), and more. cpu_a.s This file contains functions to implement critical section protection for the specific CPU type used. \Micrium\Software\uC-LIB This directory contains library support files that are independent of the CPU, µC/TCP-IP and compiler. Micrium doesn’t uses standard C library functions in order to simplify third-party certification. lib_def.h This file contains definitions that can be used by other applications. All #defines in this file are prefixed by DEF_ and contains definitions for DEF_TRUE and DEF_FALSE, DEF_YES and DEF_NO, DEF_ON and DEF_OFF and bit masks. lib_mem.c/h This file contains function to copy memory, clear memory, etc. All functions in this file start with Mem_. 32 lib_str.c/h This file contains function to replace the standard strcpy(), strcat(), etc. All functions start with Str_. 2.03.02 Test Code Directories \Micrium\Software\EvalBoards Although not actually part of µC/TCP-IP, we created a standard directory structure where application examples are placed. Specifically, sample code is placed under an ‘EvalBoards’ sub-directory. Each different evaluation board is categorized by its manufacturer, the actual board name and the tools that were used to test the sample code. Specifically, sample code is placed using the following structure: \Micrium\Software\EvalBoard\manufacturer\board\tools We tested µC/TCP-IP using the Cogent CSB337 (ARM9) processor using the IAR tool chain. Sample code is thus placed under the following directory: \Micrium\Software\EvalBoard\Cogent\CSB337\IAR\uC-Apps\Ex?? Each different example (Ex??) has its own directory under the IAR directory. The example directories contain the following µC/TCP-IP related files: app.c app_cfg.h includes.h net_cfg.h os_cfg.h Of course, other source files, compiler build files, linker command files and so on are also found in the example directories in order to create the specific example. Code that is common to all of the examples and related to control of I/Os for a given evaluation board are placed in a BSP sub-directory as shown below. BSP stands for ‘Board Support Package’ \Micrium\Software\EvalBoard\Cogent\CSB337\IAR\BSP The BSP directory can contain the following files: bsp.c bsp.h net_bsp.c net_bsp.h net_isr.c You will notice the presence of a net_bsp.c files. This file is placed in the BSP directory because it is dependent of the CPU and NIC used (interrupt structure, I/O ports, etc.) but, has a ‘net_’ prefix indicating that it’s a network specific file. 33 2.04 Task model Figure 2-3 shows a simplified task model of µC/TCP-IP along with application tasks. App Task App Task App Task BSD Sockets API µC/TCP-IP Rx Task Global Lock Tmr Task µC/TCP-IP Data NIC Network Figure 2-3, µC/TCP-IP, Task Model Your application interfaces to µC/TCP-IP via a well known API (Application Programming Interface) called BSD sockets (or µC/TCP-IP’s internal socket interface). Basically, you application can send and receive data to/from other hosts on the network via this interface. The BSD sockets API interfaces to internal structures and variables (i.e. data) that are maintained by µC/TCP-IP. A binary semaphore (the global lock in Figure 2-3) is used to guard the access to this data to ensure exclusive access. In other words, to read or write to this data, a task needs to acquire the binary semaphore before it can access the data and release it when done. Of course, your application tasks don’t have to know anything about this semaphore nor the data since its use is encapsulated by functions within µC/TCP-IP. 34 As we previously mentioned, µC/TCP-IP supports only one NIC (Network Interface Controller) at a time. Currently, µC/TCP-IP only works with Ethernet controller NICs but has been designed to support other types of NICs in the future. Writing a driver for different Ethernet controllers is fairly straightforward and generally consists of writing about two dozen fairly simple functions. 2.04.01 µC/TCP-IP Tasks and Priorities µC/TCP-IP basically defines two internal tasks: a receive (Rx Task) and a timer task (Tmr Task). The Rx Task is responsible for processing received packets from the NIC. If the packet is destined for an application, the Rx Task will arrange to pass the information to the task using the appropriate TCP/IP protocol. The Tmr Task is responsible for handling all timeouts related to the TCP/IP protocols. When setting up task priorities, it’s recommended that you set the priority of tasks that will use µC/TCP-IP’s services below that of the task priorities of µC/TCP-IP. In other words, µC/TCP-IP’s tasks should have a higher priority than tasks that use µC/TCP-IP. This is to reduce starvation issues when an application task needs to send a lot of data. However, if your application task that uses µC/TCP-IP needs to have a higher priority then you should voluntarily relinquish the CPU on a regular basis. For example, you can suspend the task for a number of OS clock ticks. 2.04.02 Receiving a Packet Figure 2-4 shows a simplified task model of µC/TCP-IP when packets are received from the NIC. assume we have a TCP packet being received. Here we F2-4(1) A packet is sent on the network and the NIC recognizes its address as the destination for the packet. The NIC then generates an interrupt and the NIC ISR determines that the interrupt comes from a packet reception (as opposed to the completion of a transmission). F2-4(2) Instead of processing the NIC directly from the ISR, we decided to pass the responsibility to a task. The Rx ISR thus simply ‘signals’ the Rx Task that there is a packet to process. A counting semaphore is used as the signaling mechanism. Note that further Rx interrupts are disabled to prevent re-entering the ISR because on most NICs, the interrupt status is cleared only when the packet is extracted from the NIC. F2-4(3) The Rx Task does nothing until a signal is received from the Rx ISR. F2-4(4) When a signal is received, the Rx Task wakes up and extracts the packet from the NIC and places it in a receive buffer. µC/TCP-IP maintains two types of buffers: small and large. A small buffer can typically hold up to 256 bytes of data from the NIC. A large buffer can hold up to 1536 bytes. These sizes as well as the quantity of these buffers are actually configurable at compile time to better suit the actual intended application. The Rx Task queries the NIC for the size of the packet in order for it to know which type of buffer is needed (small or large). F2-4(5) Buffers are shared resource and any access to those or any other µC/TCP-IP data structures is guarded by the binary semaphore guarding the data. This means that the Rx Task will need to acquire the semaphore before it can get a buffer from the pool. 35 F2-4(6) The Rx Task obtains a buffer from the buffer pool. The packet is removed from the NIC and placed in the buffer for further processing. Sockets TCP IP IF (7) µC/TCP-IP µC/TCP-IP Data (6) Rx Task (5) (8) (3) Rx Semaphore Global Lock (4) (Counting Semaphore) (6) (2) Rx ISR (1) NIC Network Figure 2-4, µC/TCP-IP, Receiving a Packet F2-4(7) The Rx Task examines the Ethernet frame to determine whether the packet is destined for the ARP or IP layer and passes the buffer to the appropriate layer for further processing. Note that the Rx Task brings the data all the way up to the application layer and thus the appropriate µC/TCP-IP P functions operate within the context of the Rx Task. F2-4(8) When the packet is processed, the lock is released. 36 2.04.03 Sending a Packet Figure 2-5 shows a simplified task model of µC/TCP-IP when packets are sent through the NIC. In this example, we show a TCP packet being sent. Application Task (1) µC/TCP-IP Data Sockets TCP (2) (3) IP (8) IF (4) Tx Rdy Semaphore (7) (6) Tx ISR (5) NIC Network Figure 2-5, µC/TCP-IP, Sending a Packet 37 Global Lock F2-5(1) A task (assuming an application task) that wants to send data interfaces to µC/TCP-IP through the BSD socket API. F2-5(2) A function within µC/TCP-IP acquires the binary semaphore (i.e. the global lock) in order to place the data to send into µC/TCP-IP’s data structures. F2-5(3) The appropriate µC/TCP-IP layer processes the data to send to prepare it for transmission. F2-5(4) The task (via the IF layer) then waits on a counting semaphore which is used to indicate that the transmitter in the NIC is available to send a packet. If the NIC is not able to send the packet, the task blocks until the semaphore is signaled by the NIC. Note that, at startup, the semaphore is initialized with a value corresponding to the number of packets that can be sent at one time through the NIC. In other words, if the NIC has sufficient buffer space to be able to queue up four packets then the counting semaphore is initialized with a count of 4. F2-5(5) When the NIC completes sending a packet, the NIC generates an interrupt. F2-5(6) The Tx ISR signals the Tx Available semaphore indicating that the NIC is able to send another packet. F2-5(7) The task then wakes up and copies the packet to send into the NIC. F2-5(8) After placing the packet into the NIC, the task releases the global data lock and continues execution. 38 Chapter 3 Buffer Management µC/TCP-IP places received packets in network buffers to be processed by the upper layers and also, places data to send in network buffers. There are two types of buffers as shown in Figure 3-1: small and large. Each buffer contains a header portion that is used by µC/TCP-IP. This header provides information to µC/TCP-IP about the contents of the buffer. The data portion contains the data that has either been received by the NIC and thus will be processed by µC/TCP-IP or, data that is destined for the NIC. Buffer management functions are found in net_buf.*. Small buffers are used by µC/TCP-IP when received data or, data to transmit fits in this size buffer. The header structure is common to both types of buffers. A header currently requires about 200 bytes of storage. Large Buffer Small Buffer Network Buffer Header NET_BUF_CFG_DATA_SIZE_SMALL Network Buffer Data NET_BUF_CFG_DATA_SIZE_LARGE Figure 3-1, µC/TCP-IP’s small and large buffers 39 There are currently four configurable options for network buffers. net_cfg.h which resides in your application: You change the configuration values in NET_BUF_CFG_NBR_SMALL This configuration constant determines the number of small network buffers used by µC/TCP-IP. The number of buffers needed depends on the run-time behavior of your network and the expected traffic on the network. NET_BUF_CFG_NBR_LARGE This configuration constant determines the number of large network buffers used by µC/TCP-IP. The number of buffers needed depends on the run-time behavior of your network and the expected traffic on the network. NET_BUF_CFG_DATA_SIZE_SMALL The configuration constant determines the size of the data portion for small buffers. The recommended size for small buffers is around 256 bytes. NET_BUF_CFG_DATA_SIZE_LARGE The configuration constant determines the size of the data portion for large buffers. Typically you would set large buffers to the largest packet that can be sent on the NIC. In the case of Ethernet, you should set this buffer to 1596. 3.01 Buffer Statistics µC/TCP-IP maintains run-time statistics on the usage of the buffers and your application can thus query µC/TCP-IP to find out how many buffers are available, how many buffers are used, what the maximum number of buffer usage is, and more. Your application can also reset the statistics of maximum number of buffers used. Examining buffer statistics allows you to better manage your memory usage. Typically, you would allocate more buffers than you ‘think’ you need and then, by examining buffer usage statistics, you can make adjustments. For example, if you allocate 100 small buffers but your application never uses more than 25 buffers than, you might want to consider reducing the number of small buffers to something like 30 or so. Statistics are kept in a data structure called NET_STAT_POOL (see net_stat.h). The data structure is shown below: typedef struct NET_TYPE net_stat_pool { Type; NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY CPU_INT32U CPU_INT32U } NET_STAT_POOL; EntriesInit; EntriesTotal; EntriesAvail; EntriesUsed; EntriesUsedMax; EntriesLostCur; EntriesLostTotal; EntriesAllocatedCtr; EntriesDeallocatedCtr; NET_STAT_POOL_QTY is a data type currently set to CPU_INT16U and thus can contains a maximum count of 65535. 40 Access to buffer statistics is obtained via interface functions that your application can call (described in the next sections). Most likely, you will only need to examine the following variables in NET_STAT_POOL: .EntriesAvail This variable indicates how many buffers are available in the pool. .EntriesUsed This variable indicates how many buffers are currently used by the TCP/IP stack. .EntriesUsedMax This variable indicates the maximum number of buffers used since it was last reset. .EntriesAllocatedCtr This variable indicates the total number of times buffers were allocated (i.e. used by the TCP/IP stack). .EntriesDeallocatedCtr This variable indicates the total number of times buffers were returned back to the buffer pool. 3.01.01 Buffer Statistics, Getting SMALL buffer statistics NetBuf_SmallPoolStatGet() allows you to obtain statistics on small buffer usage. The prototype of this function is shown below: NET_STAT_POOL NetBuf_SmallPoolStatGet (void); You would use this function as follows: NET_STAT_POOL small_stats; : : small_stats = NetBuf_SmallPoolStatGet(); printf(“#Buffers Used : %05d\n”, small_stats.EntriesUsed); printf(“#Buffers Available: %05d\n”, small_stats.EntriesAvail); printf(“Peak Buffer Usage : %05d\n”, small_stats.EntriesUsedMax); : : 41 3.01.02 Buffer Statistics, Getting LARGE buffer statistics NetBuf_LargePoolStatGet() allows you to obtain statistics on large buffer usage. The prototype of this function is shown below: NET_STAT_POOL NetBuf_LargePoolStatGet (void); You would use this function as follows: NET_STAT_POOL large_stats; : : large_stats = NetBuf_LargePoolStatGet(); printf(“#Buffers Used : %05d\n”, large_stats.EntriesUsed); printf(“#Buffers Available: %05d\n”, large_stats.EntriesAvail); printf(“Peak Buffer Usage : %05d\n”, large_stats.EntriesUsedMax); : : 3.01.03 Buffer Statistics, Resetting the Maximum count of SMALL buffers used You can RESET the maximum number of small buffers used by calling the following function: void 3.01.04 NetBuf_SmallPoolStatResetUsedMax(void); Buffer Statistics, Resetting the Maximum count of LARGE buffers used You can RESET the maximum number of large buffers used by calling the following function: void NetBuf_LargePoolStatResetUsedMax(void); 42 Chapter 4 Timer Management µC/TCP-IP manages software timers that are used to keep track of timeouts. Timer management functions are found in net_tmr.*. You can set the number of available timers via the configuration constant: NET_TMR_CFG_NBR_TMR (see net_cfg.h). The number of timers affect the amount of RAM required by µC/TCP-IP. Each timer requires 8 bytes plus 4 pointers. Timers are required for: - 4.01 Each ARP cache entry IP fragment reassembly The ICMP low-network-resources monitor task Each TCP connection for the TCP state machine Timer Statistics µC/TCP-IP maintains run-time statistics on the usage of the timers and your application can thus query µC/TCP-IP to find out how many timers are available, how many timers are used, what the maximum number of timer usage is, and more. Your application can also reset the statistics of maximum number of timers used. Examining timer statistics allows you to better manage your memory usage. Typically, you would allocate more timers than you ‘think’ you need and then, by examining timer usage statistics, you can make adjustments. Statistics are kept in a data structure called NET_STAT_POOL (see net_stat.h). The data structure is shown below: typedef struct NET_TYPE net_stat_pool { Type; NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY NET_STAT_POOL_QTY CPU_INT32U CPU_INT32U } NET_STAT_POOL; EntriesInit; EntriesTotal; EntriesAvail; EntriesUsed; EntriesUsedMax; EntriesLostCur; EntriesLostTotal; EntriesAllocatedCtr; EntriesDeallocatedCtr; 43 NET_STAT_POOL_QTY is a data type currently set to CPU_INT16U and thus can contains a maximum count of 65535. Access to timer statistics is obtained via interface functions that your application can call (described in the next sections). Most likely, you will only need to examine the following variables in NET_STAT_POOL: .EntriesAvail This variable indicates how many timers are available in the pool. .EntriesUsed This variable indicates how many timers are currently used by the TCP/IP stack. .EntriesUsedMax This variable indicates the maximum number of timers used since it was last reset. .EntriesAllocatedCtr This variable indicates the total number of times timers were allocated (i.e. used by the TCP/IP stack). .EntriesDeallocatedCtr This variable indicates the total number of times timers were returned back to the timer pool. 4.01.01 Timer Statistics, Getting statistics NetTmr_PoolStatGet() allows you to obtain statistics on small buffer usage. The prototype of this function is shown below: NET_STAT_POOL NetTmr_PoolStatGet (void); You would use this function as follows: NET_STAT_POOL tmr_stats; : : tmr_stats = NetTmr_PoolStatGet(); printf(“#Timers Used : %05d\n”, tmr_stats.EntriesUsed); printf(“#Timers Available: %05d\n”, tmr_stats.EntriesAvail); printf(“Peak Timer Usage : %05d\n”, tmr_stats.EntriesUsedMax); : : 44 Chapter 5 ASCII Utilities µC/TCP-IP contains utility functions that are used to convert IP addresses to and from ASCII strings and also MAC addresses to and from ASCII strings. These functions are found in net_ascii.*. 5.01 String to MAC address, NetASCII_Str_to_MAC() This function converts a series of hexadecimal numbers to a MAC address. The hexadecimal numbers must be separated by a colon character. The prototype for this function is: void NetASCII_Str_to_MAC (CPU_CHAR CPU_INT08U NET_ERR *paddr_mac_ascii, *paddr_mac, *perr) paddr_mac_ascii is a pointer to an ASCII string that contains hexadecimal numbers separated by colons that represents the MAC address. Note that the first ASCII character to the left is the most significant digit. "00:1A:07:AC:22:09" paddr_mac is a pointer to an array of CPU_INT08U large enough to hold NET_IF_ADDR_SIZE entries. perr is a pointer to an error code that is returned by this function and can be either: NET_ASCII_ERR_NONE NET_ASCII_ERR_NULL_PTR NET_ASCII_ERR_INVALID_LEN NET_ASCII_ERR_INVALID_CHAR NET_ASCII_ERR_INVALID_CHAR_LEN NET_ASCII_ERR_INVALID_CHAR_SEQ 45 MAC address successfully converted. You passed a NULL pointer paddr_mac_ascii or paddr_mac. Invalid ASCII string length. Invalid ASCII character. Invalid ASCII character length. Invalid ASCII character sequence. for argument 5.02 MAC address to String, NetASCII_MAC_to_Str() This function converts a MAC address to a series of hexadecimal numbers represented in ASCII. The hexadecimal numbers are separated by a colon character. The prototype for this function is: void NetASCII_MAC_to_Str (CPU_INT08U *paddr_mac, CPU_CHAR *paddr_mac_ascii, CPU_BOOLEAN hex_lower_case, CPU_BOOLEAN hex_colon_sep, NET_ERR *perr) paddr_mac is a pointer to an array of CPU_INT08U large enough to hold NET_IF_ADDR_SIZE entries. paddr_mac_ascii is a pointer to an ASCII string that contains hexadecimal numbers separated by colons that represents the MAC address. Note that the first ASCII character to the left is the most significant digit. The string must be large enough to hold (NET_IF_ADDR_SIZE * 3) bytes. hex_lower_case indicates that you want to format hexadecimal numbers using lower case characters instead of upper case characters. This argument can take the following values: DEF_NO DEF_YES Format alphabetic hexadecimal characters in upper case. Format alphabetic hexadecimal characters in lower case. hex_colon_sep indicates that you want to separate hexadecimal numbers using colon characters instead of hyphen characters. This argument can take the following values: DEF_NO DEF_YES Separate hexadecimal values with hyphen characters. Separate hexadecimal values with colon characters. perr is a pointer to an error code that is returned by this function and can be either: ASCII string successfully formatted. You passed a NULL pointer paddr_mac_ascii or paddr_mac. NET_ASCII_ERR_NONE NET_ASCII_ERR_NULL_PTR 46 for argument 5.03 String to IP address, NetASCII_Str_to_IP() This function converts an IPv4 address in ASCII dotted-decimal notation to a network protocol IPv4 address in hostorder. The prototype for this function is: NET_IP_ADDR NetASCII_Str_to_IP (CPU_CHAR NET_ERR *paddr_ip_ascii, *perr) paddr_ip_ascii Pointer to an ASCII string that contains a dotted-decimal IPv4 address. perr Pointer to variable that will hold the return error code from this function : IPv4 address successfully converted. Argument 'paddr_ip_ascii' passed a NULL pointer. NET_ASCII_ERR_INVALID_LEN Invalid ASCII string length. NET_ASCII_ERR_INVALID_CHAR Invalid ASCII character. NET_ASCII_ERR_INVALID_CHAR_LEN Invalid ASCII character length. NET_ASCII_ERR_INVALID_CHAR_VAL Invalid ASCII character value. NET_ASCII_ERR_INVALID_CHAR_SEQ Invalid ASCII character sequence. NET_ASCII_ERR_NONE NET_ASCII_ERR_NULL_PTR This function returns an IPv4 address represented by ASCII string, if NO errors. otherwise. NET_IP_ADDR_NONE, RFC #1983 states that "dotted decimal notation ... refers [to] IP addresses of the form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP address". In other words, the dotted-decimal notation separates four decimal octet values by the dot, or period, character ('.'). Each decimal value represents one octet of the IP address starting with the most significant octet in network order. IP Address Examples: DOTTED DECIMAL NOTATION 127.0.0.1 192.168.1.64 255.255.255.0 HEXADECIMAL EQUIVALENT 0x7F000001 0xC0A80140 0xFFFFFF00 The dotted-decimal ASCII string MUST: Include ONLY decimal values & the dot, or period, character ('.') ; ALL other characters are trapped as invalid, including any leading or trailing characters. Include EXACTLY four decimal values separated by EXACTLY three dot characters. Ensure that each decimal value does NOT exceed the maximum octet value (i.e. 255). Ensure that each decimal value's number of decimal digits, including leading zeros, does NOT exceed the maximum number of digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_IP. 47 5.04 IP address to String This function convert a network protocol IPv4 address in host-order into a dotted-decimal notation ASCII string. The function prototype is: void NetASCII_IP_to_Str (NET_IP_ADDR CPU_CHAR CPU_BOOLEAN NET_ERR addr_ip, *paddr_ip_ascii, lead_zeros, *perr) addr_ip IPv4 address. paddr_ip_ascii Pointer to an ASCII character array that will hold the return ASCII string from this function. lead_zeros Prepend leading zeros option: DEF_NO DEF_YES Do NOT prepend leading zeros to each decimal octet value. Prepend leading zeros to each decimal octet value. perr Pointer to variable that will hold the return error code from this function: NET_ASCII_ERR_NONE ASCII string successfully created. NET_ASCII_ERR_NULL_PTR Argument paddr_ip_ascii passed a NULL pointer. NET_ASCII_ERR_INVALID_CHAR_LEN Invalid ASCII character length. RFC #1983 states that "dotted decimal notation refers [to] IP addresses of the form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP address". In other words, the dotted-decimal notation separates four decimal octet values by the dot, or period, character ('.'). Each decimal value represents one octet of the IP address starting with the most significant octet in network order. IP Address Examples: DOTTED DECIMAL NOTATION 127.0.0.1 192.168.1.64 255.255.255.0 HEXADECIMAL EQUIVALENT 0x7F000001 0xC0A80140 0xFFFFFF00 The size of the ASCII character array that will hold the return ASCII string MUST be greater than or equal to NET_ASCII_LEN_MAX_ADDR_IP. Leading zeros option prepends leading '0's prior to the first non-zero digit in each decimal octet value. The number of leading zeros is such that the decimal octet's number of decimal digits is equal to the maximum number of digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_IP. If leading zeros option DISABLED and the decimal value of the octet is zero; then one digit of '0' value is formatted. This is NOT a leading zero; but a single decimal digit of '0' value. 48 Chapter 6 BSD v4 Socket Interface Your application interfaces to µC/TCP-IP using the well known BSD socket API (Application Programming Interface). You can either write your own TCP/IP applications using this API or, you can purchase a number of off-the-shelf TCP/IP components (Telnet, Web server, FTP server, etc.) which all interface to the BSD socket interface. You can also use µC/TCP-IP’s own socket interface functions which are found in the net_sock.* files. Basically, net_bsd.* is a layer of software that converts BSD socket calls to µC/TCP-IP socket calls as shown in Figure 6-1. You would have a slight performance gain by interfacing directly to net_sock.* functions. µC/TCP-IP’s socket API is discussed in Chapter 7. Also, the µC/TCP-IP calls are more versatile because they provide an error code to the calling function instead of just 0 or -1. Micrium layer 7 application typically use the µC/TCP-IP socket interface functions instead of the BSD functions. Your Application BSD Socket Interface net_bsd.* µC/TCP-IP Socket Interface net_sock.* µC/TCP-IP Figure 6-1, BSD Socket Interface relationship to µC/TCP-IP 49 6.01.01 UDP Socket Calls Figure 6-2 shows a typical UDP client-server application and the BSD calls used. The client does not establish a connection with the server. Instead, the client simply sends datagrams to the server using sendto() which contains the address of the server as a parameter. The server calls recvfrom() which waits until data arrives from a client (assuming the socket has been open in ‘blocking’ mode). recvfrom() returns enough information about the client to allow the server to send it a response. UDP Client UDP Server socket() socket() bind() recvfrom() sendto() More Requests Data (Request to Server) Process the request from the client recvfrom() Block until datagram is received Block until datagram is received Data (Reply to Client) sendto() Done close() Figure 6-2, BSD Socket calls used in a typical UDP client-server application 50 Service More Requests 6.01.02 TCP Socket Calls Figure 6-3 shows a typical TCP client-server application and the BSD calls used. You would typically start the server first and then, sometime later, start the client which connects to the server. The client sends requests to the server, the server processes the request and then, sends back a reply to the client. This continues until the client closes its end of the connection. Closing the client causes the client to send a special notification to the server. The server then closes its end of the connection and, either terminates or, waits for a new client connection. TCP Client TCP Server socket() socket() bind() listen() Block until we get a connection from a client Server listens for other connections New socket created to handle the connection accept() connect() More Requests send() Establish connection (TCP three-way handshaking) Data (Request to Server) recv() Block until we receive data recv() Process the request from the client Block until we receive data Data (Reply to Client) send() Done close() recv() close() Figure 6-3, Using BSD Socket calls in a TCP connection 51 Service More Requests 6.02 Data Structures sockaddr Generic (non-address-family-specific) address structure struct sockaddr { CPU_INT16U CPU_CHAR }; sa_family; sa_data[14]; /* Address family (e.g., AF_INET) */ /* Protocol-specific address information */ s_addr; /* IP address (32 bits) */ sin_family; sin_port; sin_addr; sin_zero[8]; /* /* /* /* */ */ */ */ in_addr Internet (IP) address structure struct in_addr { NET_IP_ADDR }; sockaddr_in struct sockaddr_in { CPU_INT16U CPU_INT16U struct in_addr CPU_CHAR }; Internet protocol (PF_INET) Address port (16 bits) IP address (32 bits) Not used Family values must be in host CPU byte order. All address values must be in network byte order (big endian). Figure 6-4 shows the sockaddr and the sockaddr_in data structures overlaid one on top of the other. 16-bit Family 14 bytes of data sockaddr sa_family 2 bytes sa_data 2 bytes 4 bytes 8 bytes sockaddr_in sin_family sin_port 16-bit Family sin_addr sin_zero 32-bit Internet Address 16-bit Port Number 8 bytes of unused data Figure 6-4, sockaddr_in is a different ‘view’ of the sockaddr data structure 52 6.03.01 accept() TCP accept() normally blocks waiting for connections addressed to the IP address and port number to which the given socket is bound to (you must have previously called listen() on the given socket, see Figure 6-3). When a connection arrives and the TCP handshake is successfully completed, a new socket is returned. The local and remote address and port numbers of the new socket have been filled in with the local port number of the new socket, and the remote address information has been returned in the sockaddr_in structure. Prototype int accept ( struct int sockaddr socklen_t sock_id, *paddr_remote, *paddr_len); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created. sock_id assumes to be bound to an address by the bind() call and is listening for connections via the listen() call (see Figure 6-3). paddr_remote Pointer to a socket address structure (see section 6.02, Data Structures) which contains the address of the remote host. paddr_len Pointer to the size of the socket address data structure which should always be: sizeof(struct sockaddr) OR sizeof(struct sockaddr_in) Returned Value accept() returns a newly connected socket descriptor if no error occurs and -1 otherwise. If the socket is configured for non-blocking, a return value of -1 which could indicate that the no requests for connection were queued when accept() was called. In this case, the server could do something else and call accept() at a later time. In other words, the server can ‘poll’ for a connection. Notes / Warnings See 'net_bsd.h BSD 4.x SOCKET ADDRESS DATA TYPES' for socket address format(s). Socket addresses MUST be in network-order. Uses µC/TCP-IP’s Function NetSock_Accept() 53 Example struct int int sockaddr_in MySockID; NewSockID; MySockAddr; void AppTask (void) { int bind_status; int addr_len; : : /* Call bind() */ /* Call listen() */ : NewSockID = accept(MySocketID, (struct sockaddr *)&MySockAddr, &addr_len); if (NewSockID < 0) { close(MySocketID); } else { /* Connection established with remote host, use NewSockID to communicate with client */ } : : } 54 6.03.02 bind() TCP/UDP Addresses are assigned to sockets with the bind function. bind() is generally always called by servers and not clients. In all cases, a port number must be specified. Prototype int bind ( struct int sockaddr socklen_t sock_id, *paddr_local, addr_len); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created. paddr_local Pointer to a socket address structure (see section 6.02, Data Structures) which contains the address of the local host to bind to. addr_len This argument specifies the size of the socket address data structure and should always be: sizeof(struct sockaddr) OR sizeof(struct sockaddr_in) Returned Value bind() returns 0 if successful or -1 upon error. Notes / Warnings See 'net_bsd.h BSD 4.x SOCKET ADDRESS DATA TYPES' for socket address format(s). Socket addresses MUST be in network-order. Uses µC/TCP-IP’s Function NetSock_Bind() 55 Example int struct sockaddr_in MySockID; MySockAddr; void AppTask (void) { int bind_status; : : MySockAddr.sin_family = AF_INET; MySockAddr.sin_port = htons(MY_SERVER_PORT_NBR); MySockAddr.sin_addr.s_addr = htonl(INADDR_ANY); bind_status = bind(MySocketID, (struct sockaddr *)&MySockAddr, sizeof(struct sockaddr_in)); if (bind_status < 0) { close(MySocketID); } else { /* Socket bound to desired port */ } : : } Example Comment(s) It’s typical to specify INADDR_ANY as the IP address to bind to especially for servers. This indicates that we would like to bind to any IP address in case the server has more than one IP address. However, the current version of µC/TCP-IP only supports one IP address per target system in which µC/TCP-IP runs on. It’s preferable to bind to any IP address in case µC/TCP-IP supports multiple IP addresses in the future. 56 6.03.03 close() TCP/UDP This function is called to terminate communications on a socket. The socket is marked to prevent further send and receives. Prototype int close (int sock_id); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created OR the socket ID returned by the accept() call. Returned Value close() returns 0 if successful or -1 upon error. Notes / Warnings None Uses µC/TCP-IP’s Function NetSock_Close() Example int MySocketID; void AppTask (void) { : : close(MySocketID); : : } 57 6.03.04 connect() TCP/UDP This function establishes a connection between the given socket and the remote socket associated with the foreign address, if any. If the function returns successfully, the given socket's local and remote IP address and port information have been filled in. If the socket was not previously bound to a local port, one is assigned randomly. After a socket endpoint is created, a client task will normally try to connect to a server application. The meaning of connect() is very different for TCP and UDP sockets. For TCP sockets, connect() returns successfully only after completing a handshake with the remote TCP implementation and the given socket's local and remote IP address and port information have been filled in, Success implies the existence of a reliable channel to that socket. connect() attempts to “dial a phone number” and connect with the server’s socket similar to a telephone call. The connection is maintained for the life of the socket. For UDP sockets, you can ‘connect’ to a different remote socket. All datagrams will be addressed to the same socket and, only datagrams from that socket will be accepted at this end while the ‘connect’ is still applicable. Prototype int connect ( struct int sockaddr socklen_t sock_id, *paddr_remote, addr_len); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created. paddr_remote Pointer to a socket address structure (see section 6.02, Data Structures) which contains the address of the remote host to connect to. addr_len This argument specifies the size of the socket address data structure and should always be: sizeof(struct sockaddr) OR sizeof(struct sockaddr_in) Returned Value connect() returns 0 if successful or -1 upon error. Notes / Warnings None Uses µC/TCP-IP’s Function NetSock_Conn() 58 Example int struct sockaddr_in MySockID; ServerAddr; void AppTask (void) { int connect_status; : : ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(REMOTE_SERVER_PORT_NBR); MySockAddr.sin_addr.s_addr = htonl(INADDR_ANY); connect_status = connect(MySocketID, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in)); if (connect_status < 0) { close(MySocketID); } else { /* Socket connected to remote server */ } : : } 59 6.03.05 inet_addr() This function converts an IPv4 address in ASCII dotted-decimal notation to a network protocol IPv4 address in network-order. Prototype in_addr_t inet_addr (char *paddr); Arguments Pointer to an ASCII string that contains a dotted-decimal IPv4 address (see Note #2). paddr Returned Value Network-order IPv4 address represented by ASCII string, if NO errors. -1 otherwise (i.e. 0xFFFFFFFF). Notes / Warnings 1) RFC 1983 states that "dotted decimal notation ... refers [to] IP addresses of the form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP address". In other words, the dotted-decimal notation separates four decimal octet values by the dot, or period, character ('.'). Each decimal value represents one byte of the IP address starting with the most significant byte in network order. IP Address Examples : DOTTED DECIMAL NOTATION 127.0.0.1 192.168.1.64 255.255.255.0 MSO ….…… LSO MSO LSO 2) HEXADECIMAL EQUIVALENT 0x7F000001 0xC0A80140 0xFFFFFF00 MSO …. LSO Most Significant Octet in Dotted Decimal IP Address Least Significant Octet in Dotted Decimal IP Address The dotted-decimal ASCII string MUST include ONLY decimal values and the dot, or period, character ('.'). ALL other characters trapped as invalid, including any leading or trailing characters. The ASCII string MUST also include EXACTLY four decimal values separated by EXACTLY three dot characters. Each decimal value MUST NOT exceed the maximum octet value (i.e. 255), ensure that each decimal value does NOT include leading zeros. Uses µC/TCP-IP’s Function / Macro NetASCII_Str_to_IP() NET_UTIL_HOST_TO_NET_32() 60 Example void AppTask (void) { inet_addr_t ip; inet_addr_t msk; : : ip = inet_addr(“192.168.1.64”); msk = inet_addr(“255.255.255.0”); : : } 61 6.03.06 inet_ntoa() This function converts a network protocol IPv4 address in network-order to an IPv4 address in ASCII dotteddecimal notation. Prototype char *inet_ntoa (struct in_addr addr); Arguments IPv4 address. in_addr Returned Value Pointer to ASCII string of converted IPv4 address (see Note #2), if NO errors. NULL pointer otherwise. Notes / Warnings 1) RFC 1983 states that "dotted decimal notation ... refers [to] IP addresses of the form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP address". In other words, the dotted-decimal notation separates four decimal octet values by the dot, or period, character ('.'). Each decimal value represents one octet of the IP address starting with the most significant octet in network order. IP Address Examples : DOTTED DECIMAL NOTATION 127.0.0.1 192.168.1.64 255.255.255.0 MSO ….…… LSO MSO LSO HEXADECIMAL EQUIVALENT 0x7F000001 0xC0A80140 0xFFFFFF00 MSO …. LSO Most Significant Octet in Dotted Decimal IP Address Least Significant Octet in Dotted Decimal IP Address 2) Since the character string is returned in a single, global character string array, this conversion function is NOT reentrant. 3) The IP address is saved in a ‘global’ array called NetBSD_IP_to_Str_Array[] and needs to be copied ‘out’ of this array to be able to use inet_ntoa() for another IP address. Uses µC/TCP-IP’s Function NetASCII_IP_to_Str() 62 Example void AppTask (void) { char *pstr; char ascii_ip_addr[NET_BSD_ASCII_LEN_MAX_ADDR_IP]; : : pstr = inet_ntoa(0xC0A80140); Str_Copy(ascii_ip_addr, pstr); : : /* Convert 192.168.1.64 to ASCII string */ /* Copy this string to local buffer */ } 63 6.03.07 listen() TCP Indicates that the given socket is ready to accept incoming connections. The socket must already be associated with a local port (i.e., bind() must have been called previously). After this call, incoming TCP connection requests addressed to the given local port (and IP address, if specified previously) will be completed and queued until they are passed to the program via accept(). listen() applies only to stream type sockets (i.e. TCP sockets). Prototype int listen (int int sock_id, sock_q_size); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created. sock_q_size Maximum number of new connections (sockets) waiting. In other words, this argument specifies the maximum queue length of pending connections while the server is busy servicing the current request. Returned Value Returns 0 if no error and -1 otherwise. Notes / Warnings None. Uses µC/TCP-IP’s Function NetSock_Listen() 64 Example int struct sockaddr_in MySockID; MySockAddr; void AppTask (void) { int listen_status; : : /* Call socket() */ /* Call bind() */ listen_status = listen(MySocketID, 3); if (listen_status < 0) { close(MySocketID); } else { /* Socket placed in listening state, proceed to ‘accept’ connections */ /* Call accept() */ } : : } 65 6.03.08 recv() TCP/UDP This function copies up to a specified number of bytes, received on the socket, into a specified location. The specified socket must be in the connected state. If the socket is configured for blocking mode, recv() blocks until either at least one byte is returned or the connection closes (indicated by returning 0). If the socket is configured for non-blocking mode, recv() returns a -1 if no data is available. The return value indicates the number of bytes actually copied into the buffer starting at the pointed-to location. For a stream socket (i.e. TCP), the bytes are delivered in the same order as they were transmitted, without omissions. For a datagram socket (i.e. UDP), each recv() returns the data from at most one send(), and order is not necessarily preserved. If the buffer provided to recv() is not big enough for the next available datagram, the datagram is silently truncated to the size of the buffer. You would typically use recv() for TCP sockets and recvfrom() for UDP sockets. Prototype ssize_t recv (int void _size_t int sock_id, *pdata_buf, data_buf_len, flags); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created OR the socket ID returned by the accept() call. pdata_buf Is a pointer to where the received message will be stored. data_buf_len Contains the size of the destination buffer. flags Specifies receive options. You can logically OR the flags. Valid flags are: 0 No socket flags selected MSG_PEEK Receive socket data without consuming the data MSG_DONTWAIT Receive the data without blocking In most cases, you would set flags to 0. Returned Value recv() returns the number of data octets actually received, -1 upon error, and 0 indicates that the connection was closed. 66 Blocking vs Non-Blocking The default setting for µC/TCP-IP is blocking. However, you can change that at compile time by setting the configuration #define (see net_cfg.h) NET_SOCK_CFG_BLOCK_SEL to one of the following values: NET_SOCK_BLOCK_SEL_DFLT sets blocking mode to the default, or blocking, unless modified by runtime options. NET_SOCK_BLOCK_SEL_BLOCK sets the blocking mode to blocking. This means that recv() will wait until data is available from the socket. After creating the socket, you can specify a timeout when in blocking mode by calling the µC/TCP-IP function NetSock_CfgTimeoutRxQ_Set(). In other words, recv() will wait forever until a message is received unless you specify a timeout value. NetSock_CfgTimeoutRxQ_Set() require three parameters: NET_SOCK_ID CPU_INT32U NET_ERR sock_id timeout_ms *perr sock_id is the socket ID that you pass to recv(). timeout_ms is the amount of time (in milliseconds) to wait for data to be received from the socket. If you specify a time of NET_TMR_TIME_INFINITE then, the socket will wait forever for data to arrive. perr is a pointer to an error code that is returned from NetSock_CfgTimeoutRxQ_Set(). NET_SOCK_ERR_NONE indicates that the socket timeout was set correctly. NET_SOCK_BLOCK_SEL_NO_BLOCK sets the blocking mode to non-blocking. This means that recv() call will NOT wait if data is not available from the socket. The caller should examine the return code of the function. 0 indicates that the connection has been lost and -1 indicates that no data was available. Of course, you will have to ‘poll’ recv() on a regular basis if data is not available. The current version of the software selects blocking or non-blocking at compile time for all sockets. A future version of µC/TCP-IP will allow the selection of blocking or non-bloacking at the individual socket level. However, each call to recv() can pass the MSG_DONTWAIT flag to disable blocking on that call. Notes / Warnings Only some recv() flag options are implemented. If other flag options are requested, recvfrom() returns an error so that flag options are NOT silently ignored. Uses µC/TCP-IP’s Function NetSock_RxData() 67 Example int CPU_INT08U MySockID; RxBuf[100]; void AppTask (void) { int rx_data_len; : : rx_data_len = recv(MySocketID, (void *)&RxBuf[0], 100, 0); if (rx_data_len > 0) { /* Process data received */ } else if (rx_data_len == 0) { close(MySocketID); } else { /* Data not received */ } : : /* See if we received data */ /* See if connection has been lost */ } 68 6.03.09 recvfrom() TCP/UDP recvfrom() is used to receive from a UDP socket. The function copies a specified number of bytes received on a socket to a specified location. Prototype ssize_t recvfrom ( int void _size_t int struct sockaddr socklen_t sock_id, *pdata_buf, data_buf_len, flags, *paddr_remote, *paddr_len); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created OR the socket ID returned by the accept() call. pdata_buf This is a pointer to where the data received from the socket will be placed. data_buf_len This argument specifies the maximum number of bytes to place in the pdata_buf buffer. flags Control flags and can be one of the following values. Note that options can be logically OR’d together: No socket flags selected. Receive socket data without consuming the socket data. Receive socket data without blocking. 0 MSG_PEEK MSG_DONTWAIT In most cases, you would set flags to 0. paddr_remote Pointer to an address buffer that will hold the socket address structure with the received data's remote address (see section 6.02, Data Structures). paddr_len When recvfrom() is called, paddrlen points to the size of the address buffer pointed to by paddr_remote. When the function returns, paddr_len points to the actual size of socket address structure with the received data's remote address. Returned Value recvfrom() returns the number of data octets actually received, -1 upon error, and 0 indicates that the connection was closed. 69 Blocking vs Non-Blocking The default setting for µC/TCP-IP is blocking. However, you can change that at compile time by setting the configuration #define (see net_cfg.h) NET_SOCK_CFG_BLOCK_SEL to one of the following values: NET_SOCK_BLOCK_SEL_DFLT sets blocking mode to the default, or blocking, unless modified by runtime options. NET_SOCK_BLOCK_SEL_BLOCK sets the blocking mode to blocking. This means that recvfrom() will wait until data is available from the socket. After creating the socket, you can specify a timeout when in blocking mode by calling the µC/TCP-IP function NetSock_CfgTimeoutRxQ_Set(). In other words, recvfrom() will wait forever until a message is received unless you specify a timeout value. NetSock_CfgTimeoutRxQ_Set() require three parameters: NET_SOCK_ID CPU_INT32U NET_ERR sock_id timeout_ms *perr sock_id is the socket ID that you pass to recvfrom(). timeout_ms is the amount of time (in milliseconds) to wait for data to be received from the socket. If you specify a time of NET_TMR_TIME_INFINITE then, the socket will wait forever for data to arrive. perr is a pointer to an error code that is returned from NetSock_CfgTimeoutRxQ_Set(). NET_SOCK_ERR_NONE indicates that the socket timeout was set correctly. NET_SOCK_BLOCK_SEL_NO_BLOCK sets the blocking mode to non-blocking. This means that recvfrom() call will NOT wait if data is not available from the socket. The caller should examine the return code of the function. 0 indicates that data was received and -1 indicates that no data was available. Of course, you will have to ‘poll’ recvfrom() on a regular basis if data is not available. The current version of the software selects blocking or non-blocking at compile time for all sockets. A future version of µC/TCP-IP will allow the selection of blocking or non-bloacking at the individual socket level. However, each call to recvfrom() can pass the MSG_DONTWAIT flag to disable blocking on that call. Notes / Warnings For UDP sockets, all data is transmitted and received atomically -- i.e. every single, complete datagram transmitted MUST be received as a single, complete datagram. Thus, if the socket's type is datagram and the receive data buffer size is NOT large enough for the received data, the remaining data octets are silently discarded and NO error is returned. See also 'net_sock.c NetSock_RxDataFrom() Note #3' & 'net_sock.c NetSock_RxDataHandler() Note #2'. Only some recvfrom() flag options are implemented. If other flag options are requested, recvfrom() returns an error so that flag options are NOT silently ignored. Uses µC/TCP-IP’s Function NetSock_RxDataFrom() 70 Example char struct int int sockaddr_in rx_buf[100]; sock_addr; sock_addr_len; rx_msg_len; sock_addr_len = sizeof(sock_addr); rx_msg_len = recvfrom(sock_id, (void *)&rx_buf[0], sizeof(rx_buf), 0, (struct sockaddr *)&sock_addr, &sock_addr_len); if (rx_msg_len < 0) { /* Data not received */ } else { /* Data received */ } 71 6.03.10 select() TCP/UDP This function checks if any sockets are ready for available read, write, &/or error operations. Prototype int select ( struct struct struct struct int fd_set fd_set fd_set timeval desc_nbr_max, *pdesc_rd, *pdesc_wr, *pdesc_err, *ptimeout); Arguments desc_nbr_max Specifies the maximum number of socket file descriptors in the file descriptor sets. pdesc_rd Pointer to a set of socket file descriptors to : (a) Check for available read operations. (b) (1) Return the actual socket file descriptors ready for available read operations, if no errors; (2) Return the initial, non-modified set of socket file descriptors, on any errors; (3) Return a null-valued (i.e. zero-cleared) descriptor set, if any timeout expires. pdesc_wr Pointer to a set of socket file descriptors to : (a) Check for available write operations. (b) (1) Return the actual socket file descriptors ready for available write operations, if no errors; (2) Return the initial, non-modified set of socket file descriptors, on any errors; (3) Return a null-valued (i.e. zero-cleared) descriptor set, if any timeout expires. pdesc_err Pointer to a set of socket file descriptors to : (a) Check for any available socket errors. (b) (1) Return the actual socket file descriptors ready with any pending errors; (2) Return the initial, non-modified set of socket file descriptors, on any errors; (3) Return a null-valued (i.e. zero-cleared) descriptor set, if any timeout expires. ptimeout Pointer to a timeout argument. Returned Value select() returns the number of socket file descriptors ready with available operations if successful, 0 upon timeout, and -1 upon error. Notes / Warnings Enabled via NET_SOCK_CFG_SEL_EN ONLY supports socket file descriptors (i.e. socket ID descriptor numbers). 72 Uses µC/TCP-IP’s Function NetSock_Sel() Example int int MySockID_UDP; MySockID_TCP; void { AppTask (void) struct struct struct int int sockaddr_in fd_set timeval rtn_val; rdy; addr; fdset; timeout; MySockID_UDP = socket(PF_INET, SOCK_DGRAM, /* Configure UDP socket server. IPPROTO_UDP); */ Mem_Clr((void *)&addr, (CPU_SIZE_T) sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(UDP_SERVER_PORT_NBR); addr.sin_addr.s_addr = htonl(UDP_SERVER_ADDR); rtn_val = bind(MySockID_UDP, &addr, sizeof(addr)); /* Configure TCP socket server. MySockID_TCP = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); */ Mem_Clr((void *)&addr, (CPU_SIZE_T) sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(TCP_SERVER_PORT_NBR); addr.sin_addr.s_addr = htonl(TCP_SERVER_ADDR); rtn_val = bind(MySockID_TCP, &addr, sizeof(addr)); rtn_val = listen(MySockID_TCP, 3); while (DEF_ON) { /* Handle socket servers forever. */ FD_ZERO(&fdset); FD_SET(MySockID_UDP, &fdset); FD_SET(MySockID_TCP, &fdset); timeout.tv_sec = 123; timeout.tv_usec = 456789; rtn_val = select((int (struct (struct (struct (struct if (rtn_val > 0) { ) FD_SETSIZE, *)&fdset, *) 0, *) 0, *)&timeout); /* If any server socket ready, ... /* ... handle ready sockets. rdy = FD_IS_SET(MySockID_UDP, &fdset); if (rdy == 1) { Handle ready UDP socket server; } rdy = FD_IS_SET(MySockID_TCP, &fdset); if (rdy == 1) { Handle ready TCP socket server; } fd_set fd_set fd_set timeval } } } 73 */ */ 6.03.11 send() TCP/UDP send() sends bytes contained in a buffer to a TCP socket. send() can only be used when a socket is in the connected state. If the socket does not have enough buffer space available to hold the message being sent, send() will block, unless the socket has been placed in non-blocking mode, or the MSG_DONTWAIT flag has been set in the flags parameter. Prototype ssize_t send (int void _size_t int sock_id, *p_data, data_len, flags); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created OR the socket ID returned by the accept() call. p_data This is a pointer to the application data to send. data_len This argument specifies the number of octets to send. flags Control flags and ca be one of the following values: No socket flags selected. Send data without blocking. 0 MSG_DONTWAIT In most cases, you would set flags to 0. Returned Value send() returns the number of data octets actually sent, -1 upon error, and 0 indicates that the connection was closed. A positive return value does not mean that the message was delivered, it just indicates that it was sent or queued for sending. Blocking vs Non-Blocking The default setting for µC/TCP-IP is blocking. However, you can change that at compile time by setting the configuration #define (see net_cfg.h) NET_SOCK_CFG_BLOCK_SEL to one of the following values: NET_SOCK_BLOCK_SEL_DFLT sets blocking mode to the default, or blocking, unless modified by runtime options. NET_SOCK_BLOCK_SEL_BLOCK sets the blocking mode to blocking. This means that send() will wait until data is able to be prepared and/or transmitted through the socket. After creating the socket, you can specify a timeout when in blocking mode by calling the µC/TCP-IP function NetSock_CfgTimeoutTxQ_Set() for TCP sockets (UDP sockets are best effort and exit with error rather than block). In other words, send() will wait forever until a message is prepared and/or 74 transmitted unless you specify a timeout value. NetSock_CfgTimeoutTxQ_Set() require three parameters: NET_SOCK_ID CPU_INT32U NET_ERR sock_id timeout_ms *perr sock_id is the socket ID that you pass to send(). timeout_ms is the amount of time (in milliseconds) to wait for data to be prepared and/or transmitted through the socket. If you specify a time of NET_TMR_TIME_INFINITE then, the socket will wait forever for data to transmit. perr is a pointer to an error code that is returned from NetSock_CfgTimeoutTxQ_Set(). NET_SOCK_ERR_NONE indicates that the socket timeout was set correctly. NET_SOCK_BLOCK_SEL_NO_BLOCK sets the blocking mode to non-blocking. This means that send() call will NOT wait if data is not sent to the socket. As much data from the message that can fit in the TCP buffer will be sent. The caller should examine the return code of the function. A positive value indicates the number of octets that was sent data and -1 indicates that no data was sent and, 0 indicates that the connection was lost. Of course, you will have to ‘poll’ send() on a regular basis if data is not sent. The current version of the software selects blocking or non-blocking at compile time for all sockets. A future version of µC/TCP-IP will allow the selection of blocking or non-bloacking at the individual socket level. However, each call to send() can pass the MSG_DONTWAIT flag to disable blocking on that call. Notes / Warnings Even though you can select blocking or non-blocking at compile time, the current version of the software indirectly always blocks. We say indirectly because, it’s not the socket that blocks but instead, it’s the driver who waits for availability of the transmitter. Only some send() flag options are implemented. If other flag options are requested, send() returns an error so that flag options are NOT silently ignored. Uses µC/TCP-IP’s Function NetSock_TxData() 75 Example int char int sock_id; tx_buf[100]; tx_msg_len; /* Place message into tx_buf[] */ tx_msg_len = send(sock_id, &tx_buf[0], sizeof(tx_buf), 0); if (tx_msg_len > 0) { /* Data was sent */ } else if (tx_msg_len == 0) { /* Connection was lost */ } else { /* Data not sent */ } 76 6.03.12 sendto() TCP/UDP sendto()sends bytes contained in a buffer to a UDP socket. If the socket does not have enough buffer space available to hold the message being sent, sendto() will block, unless the socket has been placed in non-blocking mode, or the MSG_DONTWAIT flag has been set in the flags parameter. Prototype ssize_t sendto ( int void _size_t int struct sockaddr socklen_t sock_id, *p_data, data_len, flags, *paddr_remote, addr_len); Arguments sock_id This is the socket ID returned by the socket() call when the socket was created OR the socket ID returned by the accept() call. p_data This is a pointer to the application data to send. data_len This argument specifies the number of octets to send. flags Control flags and ca be one of the following values: No socket flags selected. Send data without blocking. 0 MSG_DONTWAIT In most cases, you would set flags to 0. paddr_remote Pointer to the destination address buffer (see section 6.02, Data Structures). addr_len This argument specifies the size of the socket address data structure and should always be: sizeof(struct sockaddr) OR sizeof(struct sockaddr_in) Returned Value sendto() returns the number of data octets actually sent, -1 upon error, and 0 indicates that the connection was closed. A positive return value does not mean that the message was delivered, it just indicates that it was sent or queued for sending. Blocking vs Non-Blocking The default setting for µC/TCP-IP is blocking. However, you can change that at compile time by setting the configuration #define (see net_cfg.h) NET_SOCK_CFG_BLOCK_SEL to one of the following values: 77 NET_SOCK_BLOCK_SEL_DFLT sets blocking mode to the default, or blocking, unless modified by runtime options. NET_SOCK_BLOCK_SEL_BLOCK sets the blocking mode to blocking. This means that sendto() will wait until data is able to be prepared and/or transmitted through the socket. After creating the socket, you can specify a timeout when in blocking mode by calling the µC/TCP-IP function NetSock_CfgTimeoutTxQ_Set() for TCP sockets (UDP sockets are best effort and exit with error rather than block). In other words, sendto() will wait forever until a message is prepared and/or transmitted unless you specify a timeout value. NetSock_CfgTimeoutTxQ_Set() require three parameters: NET_SOCK_ID CPU_INT32U NET_ERR sock_id timeout_ms *perr sock_id is the socket ID that you pass to sendto(). timeout_ms is the amount of time (in milliseconds) to wait for data to be prepared and/or transmitted through the socket. If you specify a time of NET_TMR_TIME_INFINITE then, the socket will wait forever for data to transmit. perr is a pointer to an error code that is returned from NetSock_CfgTimeoutTxQ_Set(). NET_SOCK_ERR_NONE indicates that the socket timeout was set correctly. NET_SOCK_BLOCK_SEL_NO_BLOCK sets the blocking mode to non-blocking. This means that sendto() call will NOT wait if data is not sent to the socket. The caller should examine the return code of the function. A positive value indicates the number of octets that was sent data and -1 indicates that no data was sent. Of course, you will have to ‘poll’ sendto() on a regular basis if data is not sent. The current version of the software selects blocking or non-blocking at compile time for all sockets. A future version of µC/TCP-IP will allow the selection of blocking or non-bloacking at the individual socket level. However, each call to sendto() can pass the MSG_DONTWAIT flag to disable blocking on that call. Notes / Warnings Even though you can select blocking or non-blocking at compile time, the current version of the software indirectly always assumes blocking. We say indirectly because, it’s not the socket that blocks but instead, it’s the driver who waits for availability of the transmitter. For UDP sockets, all data is transmitted atomically -- i.e. each call to transmit data MUST be transmitted in a single, complete datagram. Since IP transmit fragmentation is NOT currently supported (see 'net_ip.h Note #1e'), if the socket's type is datagram and the requested application/socket transmit data length is greater than MTU, then the socket data transmit is aborted and NO socket data is transmitted. See also 'net_sock.c NetSock_TxDataTo() Note #3' and 'net_sock.c NetSock_TxDataHandler() Note #2'. Only some sendto() flag options are implemented. If other flag options are requested, sendto() returns an error so that flag options are NOT silently ignored. 78 Uses µC/TCP-IP’s Function NetSock_TxDataTo() Example int char struct int sockaddr_in sock_id; tx_buf[100]; sock_addr; tx_msg_len; tx_msg_len = (CPU_INT16S)sendto(sock_id, &tx_buf[0], sizeof(tx_buf), 0, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)); if (tx_msg_len < 0) { /* Data not sent */ } else { /* Data sent */ } 79 6.03.13 socket() TCP/UDP Creates a TCP or UDP socket, which may then be used as a communication endpoint for sending and receiving data using the specified protocol. You would specify TCP with the socket type/protocol pair SOCK_STREAM / IPPROTO TCP and UDP, with the socket type/protocol pair SOCK_DGRAM / IPPROTO_UDP. Prototype int socket (int int int protocol_family, sock_type, protocol); Arguments protocol_family Always use AF_INET or PF_INET (both values are the same) for TCP/IP sockets. This field establishes the domain. sock_type Type of socket: SOCK_STREAM for TCP SOCK_DGRAM for UDP SOCK_STREAM is a reliable byte-stream flow, where bytes are received the remote application in the same order as they were sent. File transfer and terminal emulation are examples of applications that require this type of protocol. SOCK_DGRAM preserve message boundaries. Applications that exchange client request messages and server response messages are examples of datagram communication Note that you can in fact specify 0 as the protocol since specifying SOCK_STREAM for the sock_type implies IPPROTO_TCP and, specifying SOCK_DGRAM for the sock_type implies IPPROTO_UDP. protocol Socket protocol: IPPROTO_TCP for TCP IPPROTO_UDP for UDP Note that you can in fact specify 0 as the protocol since specifying SOCK_STREAM for the sock_type implies IPPROTO_TCP and, specifying SOCK_DGRAM for the sock_type implies IPPROTO_UDP. 80 Arguments Summary The table below shows you the different ways you can specify the three arguments. TCP/IP Protocol TCP TCP UDP UDP Arguments protocol_family AF_INET or PF_INET AF_INET or PF_INET AF_INET or PF_INET AF_INET or PF_INET sock_type SOCK_STREAM SOCK_STREAM SOCK_DGRAM SOCK_DGRAM protocol IPPROTO_UDP 0 IPPROTO_TCP 0 Returned Value socket() returns the descriptor of the new socket ID (non-negative value) if no error occurs or -1 upon error. Notes / Warnings The protocol characteristics of a socket are frozen when it is created. In other words, you cannot change a stream socket to a datagram socket (or vice versa) at run-time. It’s also very important that both sides (your target and the remote host) have sockets with the same socket family type and, protocol. Uses µC/TCP-IP’s Function NetSock_Open() Example int int AppTCPSockID_1; AppTCPSockID_2; int int AppUDPSockID_1; AppUDPSockID_2; void AppTask (void) { : : AppTCPSockID_1 = AppTCPSockID_2 = : : AppUDPSockID_1 = AppUDPSockID_2 = : : } socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); socket(PF_INET, SOCK_STREAM, 0); socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); socket(PF_INET, SOCK_DGRAM, 0); 81 Chapter 7 Micriµm Socket Layer In addition to the BSD socket API discussed in Chapter 6, your application may interface to µC/TCP-IP using its own socket API found in the net_sock.* files. Basically, your application would skip the BSD socket layer & instead directly call the µC/TCP-IP socket layer as shown in Figure 14-1. You would have a slight performance gain by interfacing directly to net_sock.* functions. The µC/TCP-IP calls are more versatile because they provide an error code to the calling function instead of just 0 or -1. Micrium layer 7 application typically use the µC/TCP-IP socket interface functions instead of the BSD functions. Your Application BSD Socket Interface net_bsd.* µC/TCP-IP Socket Interface net_sock.* µC/TCP-IP Figure 7-1, µC/TCP-IP Socket Interface 82 7.10 µC/TCP-IP Socket Error Codes When socket functions return error codes, the error codes SHOULD be inspected to determine if the error is a temporary, non-fault condition (like no data to receive) or fatal (like the socket has been closed). Whenever any of the following fatal error codes are returned by any µC/TCP-IP socket function, that socket MUST be immediately closed()'d without further by other socket functions : NET_SOCK_ERR_NOT_USED NET_SOCK_ERR_INVALID_FAMILY NET_SOCK_ERR_INVALID_PROTOCOL NET_SOCK_ERR_INVALID_TYPE NET_SOCK_ERR_INVALID_STATE NET_SOCK_ERR_FAULT 83 Chapter 8 NIC Drivers µC/TCP-IP is able to work with a number of Network Interface Controllers (NICs). If we don’t have a driver for the specific NIC you are planning on using, you can write your own driver as described in this chapter. However, it’s recommended that you modify an already existing NIC driver with your NIC’s specific code. We recommend that you follow our coding convention for consistency reasons. µC/TCP-IP currently only supports Ethernet type interface controllers. There are many Ethernet controllers available on the market and each one requires a driver to work with µC/TCP-IP. It’s actually possible to adapt drivers written for other TCP/IP stacks because the drivers are basically only responsible for copying data to and from the NIC. The amount of code needed to interface a specific NIC to µC/TCP-IP greatly depends on the complexity of the NIC. 8.01 Directories and Files Drivers are placed under the NIC directory as shown below. \Micrium\Software\uC-TCPIP\NIC µC/TCP-IP is capable of supporting multiple types of NICs but, currently only supports Ethernet. Ethernet drivers are thus placed under the \Ether subdirectory as shown below. \Micrium\Software\uC-TCPIP\NIC\Ether Individual NICs are typically identified by the manufacturer’s part number. µC/TCP-IP currently supports the SMC LAN91C111 and Atmel’s AT91RM9200 integrated MAC (Media Access Controller). You will find the drivers for these NICs in the following directories (assuming you purchased them with µC/TCP-IP). \Micrium\Software\uC-TCPIP\NIC\Ether\LAN91C111\net_nic*.* \Micrium\Software\uC-TCPIP\NIC\Ether\AT91RM9200\net_nic*.* Note that NIC drivers must be called net_nic*.*. The actual directory determines which specific NIC your application will actually use. 84 8.02 Interfacing to µC/TCP-IP Figure 8-1 shows the relationship between µC/TCP-IP, the NIC driver, the RTOS (Real-Time Operating System) and your BSP (Board Support Package). Here is a brief description of the contents of each file. More details will be provided in subsequent sections. net_nic.* contains the NIC specific code but, is independent of the CPU and RTOS used. Also, net_nic.* doesn’t know about the interface to the actual chip (memory or I/O mapped). net_bsp_a.s is an assembly language file that handles receive and transmit ISRs (Interrupt Service Routines) from your NIC. It is assumed to be part of your application code because it depends on the CPU you are using, its interrupt structure and the compiler used. The ISR is typically written in assembly language but could also written in C if your compiler and RTOS allows it. net_bsp.c contains code specific to the actual chip in your system. As a minimum, this file contains functions to read data from and write commands/data to the NIC. This file can also contain other NIC specific functions as needed by the NIC. Specifically, it can contain code to enable/disable ISRs from the NIC, initialize the NIC’s ISRs, and do other ISR related functions. net_bsp.c should contain code that is specific to the board or I/O structure of your target. This file is also assumed to be part of your application code because it depends on the CPU you are using, its interrupt structure and the compiler used. net_os.c contains code that interfaces to your RTOS. Functions specific to the NIC will be discussed in this chapter. µC/TCP-IP NIC Driver (net_nic.*) Section 8.04 (Chip Specific) ISRs (net_bsp_a.asm) Section 8.02 BSP (net_bsp.c) Section 8.03 OS (net_os.c) Section 8.05 (Your Application) (Your Application) (RTOS Specific) Figure 8-1, Interface relationship to NIC 85 8.02 ISRs, net_bsp_a.asm µC/TCP-IP assumes that NIC handling is interrupt driven. Packets received will interrupt the CPU and the completion of a packet transmission will also interrupt the CPU. We assume that ISRs (Interrupt Service Routines) are part of your application code but will be calling services provided by the stack or the RTOS. If you need to write your ISRs in assembly language, we recommend that you call the file net_bsp_a.asm for consistency. This file is assumed to be part of your application code and thus would be located in your application’s directory. Listing 8-1 shows the pseudo-code of a typical NIC ISR. In most cases, net_bsp_a.asm only needs sufficient code to save/restore CPU registers and call the function NetNIC_ISR_Handler() which is found in net_nic.c. Listing 8-1, Pseudo-code of NIC ISR written in assembly language NetNIC_ISR: Save CPU registers; Call OS ISR entry function; Call NetNIC_ISR_Handler(); Call OS ISR exit function; Restore CPU registers; Return from interrupt; 86 8.03 net_bsp.c net_bsp.c is a file that is assumed to be part of your application code since it’s specific to how the NIC is connected to your target as shown in Figure 8-2. It’s assumed that the CPU interfaces with the NIC via a series registers defined by the NIC. Each register is identified by a unique ID or, address (0 .. N-1). The specific NIC defines what each register does. Figure 8-2 shows an interface to a NIC with 16-bit wide registers and thus, net_bsp.c defines two functions: NetNIC_Rd16() and NetNIC_Wr16(). The prototype for these functions is shown below: CPU_INT16U void where: reg_offset val NetNIC_Rd_16 (CPU_INT16U reg_offset); NetNIC_Wr_16 (CPU_INT16U reg_offset, CPU_INT16U val); is the register ID. is the value to set the register to. You will notice that the functions are prefixed with NetNIC_ even though they are in the file net_bsp.c. The reasoning is that NetNIC_Rd_16() (for example) is a NIC function that should have normally been part of net_nic.c but, because it’s target specific, it needs to be placed in a file that will change based on the target. NetNIC_Wr_16() NIC µC/TCP-IP NetNIC_Rd_16() Registers 0 1 2 Defined in net_bsp.c N-1 Figure 8-2, Interface between µC/TCP-IP and the NIC net_bsp.c also contains ISR related functions such as initialization of the interrupt controller for the NIC ISR, setting up the interrupt vector, enabling and disabling interrupts from the NIC, etc. Below are additional functions that µC/TCP-IP expects to find in net_bsp.c: NetNIC_IntInit() is a function that initializes the NIC interrupt on the target. Basically, this function sets up the interrupt controller (if present), sets up the interrupt vector associated with the NIC interrupt and, enables the NIC interrupt. NetNIC_IntClr() is a function that clears the NIC interrupt. In other words, this is a function that indicates that the NIC interrupt has been serviced and that the NIC can receive another interrupt. Code for these functions is assumed to be present if you set NET_NIC_CFG_INT_CTRL_EN to DEF_ENABLED in net_cfg.h. 87 8.04 net_nic.c As previously mentioned, functions in this file contains the NIC specific code but, is independent of the CPU and RTOS used. Also, net_nic.c doesn’t know about the interface to the actual chip (memory or I/O mapped). This file contains code for the following functions: void NetNIC_Init (NET_ERR *perr); void NetNIC_IntEn (void); CPU_BOOLEAN void NetNIC_ConnStatusGet NetNIC_ConnStatusChk (void); (void); void NetNIC_ISR_Handler (void); CPU_INT16U NetNIC_RxPktGetSize (void); void NetNIC_RxPkt (void CPU_INT16U NET_ERR *ppkt, size, *perr); void NetNIC_RxPktDiscard (CPU_INT16U NET_ERR size, *perr); void NetNIC_TxPkt (void CPU_INT16U NET_ERR *ppkt, size, *perr); 88 8.05.01 net_nic.c, NetNIC_Init() This function is called by Net_Init() to initialize the NIC. The code in listing 8-2 shows the typical operations performed by NetNIC_Init(). You should simply copy this code for your own driver. Listing 8-2, Initializing the NIC void { NetNIC_Init (NET_ERR *perr) NetOS_NIC_Init(perr); if (*perr != NET_OS_ERR_NONE) { return; } NetNIC_ConnStatus #if (NET_CTR_CFG_STAT_EN NetNIC_StatRxPktCtr NetNIC_StatTxPktCtr #endif = DEF_OFF; == DEF_ENABLED) = 0; = 0; #if (NET_CTR_CFG_ERR_EN == DEF_ENABLED) NetNIC_ErrRxPktDiscardedCtr = 0; NetNIC_ErrTxPktDiscardedCtr = 0; #endif NetNIC_InitHardware(); /* Create NIC OS objects */ /* Initialize the NIC status */ /* Initialize NIC statistic counters */ /* Initialize NIC error counters */ /* Initialize the NIC hardware */ *perr = NET_NIC_ERR_NONE; } Listing 8-3 shows the pseudo-code for a function that would initialize the NIC hardware via the function NetNIC_InitHardware(). Listing 8-3, Initializing the NIC hardware void { NetNIC_InitHardware (void) /* /* /* /* /* /* Turn ON the NIC */ Initialize the chip’s registers */ Read the MAC address if it’s store in EEPROM */ Initiate auto negotiation */ Enable the NIC’s receiver */ Enable the NIC’s transmitter */ #if (NET_NIC_CFG_INT_CTRL_EN == DEF_ENABLED) NetNIC_IntInit(); /* Initialize the interrupt controller for the NIC .. */ /* .. see net_bsp.c */ #endif } 89 8.05.02 net_nic.c, NetNIC_IntEn() This function is called at the very end of Net_Init() to enable interrupts from the NIC. The pseudo-code for this function is shown in listing 8-4. Listing 8-4, Enabling both Rx and Tx NIC interrupts void { NetNIC_IntEn (void) /* Enable Rx interrupts from the NIC */ /* Enable Tx interrupts from the NIC */ } You will notice that we also transmit interrupts even though we don’t have anything to transmit. The reason for this is explained in section 8.01.01, NetOS_NIC_Init(). 90 8.05.03 net_nic.c, NetNIC_ConnStatusGet() This function is called to get the NIC's network connection status. Listing 8-5 shows the code for this function and in most cases, it doesn’t need to change. However, the NIC's network connection status is encapsulated in this function for the possibility of obtaining the connection status using a non-trivial procedure. Listing 8-5, Obtaining the connection status from the NIC CPU_BOOLEAN NetNIC_ConnStatusGet (void) { return (NetNIC_ConnStatus); } 91 8.05.04 net_nic.c, NetNIC_ISR_Handler() This function is called by NetNIC_ISR() (possibly written in assembly language) to handler both Rx and Tx interrupts from the NIC. The pseudo-code for this function is shown in Listing 8-6. Note that at the end of the function we call NetNIC_IntClr() to clear the interrupt that appears on the interrupt controller (if one is used). You will recall that NetNIC_IntClr() is defined in net_bsp.c because the implementation depends on the interrupt structure of the CPU used in the target system. Listing 8-6, Servicing both Rx and Tx interrupts void { NetNIC_ISR_Handler (void) Determine the source of the interrupt; if (Rx interrupt) { NetNIC_RxISR_Handler(); /* Interrupt was from the reception of a packet */ } if (Tx interrupt) { NetNIC_TxISR_Handler(); /* Interrupt was from the completion of a packet transmission */ } #if (NET_NIC_CFG_INT_CTRL_EN == DEF_ENABLED) NetNIC_IntClr(); /* Clear the interrupt controller for the NIC interrupt */ #endif } 92 8.05.05 net_nic.c, NetNIC_RxPktGetSize() This function is called by the IF layer to determine how many bytes were received by the NIC. This allows the IF layer to determine the size of the buffer needed to buffer the packet in order to pass it along to the other stack layers for processing. The pseudo-code in Listing 8-7 shows what this function needs to accomplish. Listing 8-7, Obtaining the size of the packet received from the NIC CPU_INT16U NetNIC_RxPktGetSize (void) { CPU_INT16U size; size = Get the size (in bytes) of the packet received from the NIC; return (size); } 93 8.05.06 net_nic.c, NetNIC_RxPkt() This function is called by the IF layer (NetIF_RxTaskHandler()) to extract a packet received out of the NIC and place it into a network buffer. The pseudo-code for this function is shown in Listing 8-8. Note that if the packet is successfully read from the NIC we increment the NetNIC_StatRxPktCtr counter (to keep track of the number of packets received) using the NET_CTR_STAT_INC() macro. The local variable cpu_sr is necessary because the macro NET_CTR_STAT_INC() needs to increment NetNIC_StatRxPktCtr indivisibly. ppkt is a pointer to the ‘data’ portion of the network buffer where the packet from the NIC will be placed. size is the size (in number of bytes) of the packet to retrieve from the NIC. Note that the size was obtained by the NetNIC_RxPktGetSize() function discussed in section 8.05.05. perr is a pointer to an variable that holds the error code reported by this function. Valid error code are: NET_NIC_ERR_NONE NET_ERR_INIT_INCOMPLETE Packet successfully read. Network initialization NOT complete. The NIC packet receive function can read data from the NIC octet-by-octet or by words. By the way, an octet is 8 bits. This term is used in networking, rather than byte, because some systems might have bytes that are not 8 bits long. For NICs with DMA capability, the NIC driver MUST DMA-receive NIC packets into its own memory buffer(s) in order to avoid CPU word-alignment exceptions. The NIC driver's NetNIC_RxPkt() function would then Mem_Copy() the received packet from the NIC's DMA memory buffer(s) into the ‘data’ portion of the network buffer pointed to by ppkt. 94 Received Packet n +1 +2 +3 … NIC a b c d a NetNIC_Rd08() Network Buffer a b c d n +1 +2 +3 … Figure 8-3, Reading the NIC one octet at a time Listing 8-8, Reading a packet out of the NIC and into a network buffer void NetNIC_RxPkt (void CPU_INT16U NET_ERR *ppkt, size, *perr) { #if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif CPU_INT08U *p_buf; if (Net_InitDone != DEF_YES) { *perr = NET_ERR_INIT_INCOMPLETE; return; } /* Ignore packet if we haven’t completed stack init. */ p_buf = (CPU_INT08U *)ppkt; while (size > 0) { *p_buf++ = NetNIC_Rd08(); size--; } /* Point to destination buffer */ /* Read one octet at a time from the NIC */ Re-enable Rx interrupts from the NIC; NET_CTR_STAT_INC(NetNIC_StatRxPktCtr); *perr = NET_NIC_ERR_NONE; } 95 Received Packet n +1 +2 +3 … NIC a b c d a b NetNIC_Rd16() MSB LSB Network Buffer a b c d n +1 +2 +3 … Figure 8-4, Reading the NIC two octets at a time (Network Order) Listing 8-9, Reading a packet out of the NIC and into a network buffer void NetNIC_RxPkt (void CPU_INT16U NET_ERR *ppkt, size, *perr) { #if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif CPU_INT16U rx_data; CPU_INT08U *p_buf; if (Net_InitDone != DEF_YES) { *perr = NET_ERR_INIT_INCOMPLETE; return; } /* Ignore packet if we haven’t completed stack init. */ p_buf = (CPU_INT08U *)ppkt; /* Point to destination buffer while (size > 0) { rx_data = NetNIC_Rd16(); *p_buf++ = (CPU_INT08U)(rx_data >> 8); size--; if (size == 0) { break; } else { *p_buf++ = (CPU_INT08U)(rx_data & 0x00FF); size--; } } Re-enable Rx interrupts from the NIC; NET_CTR_STAT_INC(NetNIC_StatRxPktCtr); *perr = NET_NIC_ERR_NONE; } 96 */ Received Packet n +1 +2 +3 … a b c d a b c d NetNIC_Rd32() Network Buffer a b c d n +1 +2 +3 … Figure 8-5, Reading the NIC four octets at a time (Network Order) Listing 8-9, Reading a packet out of the NIC and into a network buffer void NetNIC_RxPkt (void CPU_INT16U NET_ERR *ppkt, size, *perr) { #if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif CPU_INT16U rx_data; CPU_INT08U *p_buf; if (Net_InitDone != DEF_YES) { *perr = NET_ERR_INIT_INCOMPLETE; return; } /* Ignore packet if we haven’t completed stack init. */ p_buf = (CPU_INT08U *)ppkt; /* Point to destination buffer while (size > 0) { rx_data = NetNIC_Rd32(); *p_buf++ = (CPU_INT08U)((rx_data >> 24) & 0xFF); size--; if (size == 0) { break; } else { *p_buf++ = (CPU_INT08U)((rx_data >> 16) & 0xFF); size--; if (size == 0) { break; } else { *p_buf++ = (CPU_INT08U)((rx_data >> 8) & 0xFF); size--; if (size == 0) { break; } else { *p_buf++ = (CPU_INT08U)(rx_data & 0xFF); size--; } } } } Re-enable Rx interrupts from the NIC; NET_CTR_STAT_INC(NetNIC_StatRxPktCtr); *perr = NET_NIC_ERR_NONE; } 97 */ 8.05.07 net_nic.c, NetNIC_RxPktDiscard() It is often necessary to discard packets because of error conditions that have been detected by the network stack. When this occurs, NetNIC_RxPktDiscard() is called. This function typically writes the appropriate command to the NIC to discard the received packet. However, depending on the NIC, it’s possible that there is actually nothing to do and thus, this function would almost be empty. The pseudo-code and a portion of the actual code for this function is shown in listing 8-9. Note that if the packet is discarded, we increment the NetNIC_ErrRxPktDiscardedCtr counter using the NET_CTR_ERR_INC() macro. The local variable cpu_sr is necessary because the macro NET_CTR_ERR_INC() needs to increment NetNIC_ErrRxPktDiscardedCtr indivisibly. size is the number of bytes to discard from the NIC. perr is a pointer to an variable that holds the error code reported by this function. Valid error code are: NET_NIC_ERR_NONE NET_ERR_INIT_INCOMPLETE Packet successfully discarded. Network initialization NOT complete. Listing 8-9, Getting the NIC to discard the received packet void NetNIC_RxPktDiscard (CPU_INT16U NET_ERR size, *perr) { #if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif if (Net_InitDone != DEF_YES) { *perr = NET_ERR_INIT_INCOMPLETE; return; } /* If not initialized, abort the discard Write commands to the NIC to discard the last packet received; NET_CTR_ERR_INC(NetNIC_ErrRxPktDiscardedCtr); *perr = NET_NIC_ERR_NONE; } 98 */ 8.05.08.01 net_nic.c, NetNIC_TxPktPrepare() This function is called by the NetIF_Pkt_Tx() function to prepare a NIC packet for transmission. Note that this function is necessary only if the NIC has multiple transmit packets & has the capability to transmit packet(s) while simultaneously preparing other NIC transmit packet(s). From a CPU usage standpoint, preparing NIC transmit packet(s) separately from finally transmitting the packet(s) is no more or less efficient than if combined in a single transmit function. But from a network throughput standpoint, preparing additional NIC transmit packet(s) while the NIC is actively transmitting other previously-prepared packet(s) significantly improves network throughput performance. To accomodate NICs with this simultaneous prepare & transmit packet(s) capability, the NIC driver may implement the transmit preparation in the NetNIC_TxPktPrepare() function and the NET_NIC_CFG_TX_PKT_PREPARE_EN configuration constant MUST be configured as DEF_ENABLED. ppkt is a pointer to the first byte of data to write to the NIC. size is the number of bytes to write to the NIC. perr is a pointer to an variable that holds the error code reported by this function. Valid error code are: NET_NIC_ERR_NONE Packet successfully written/sent to the NIC. NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. NET_ERR_TX NIC Transmit error. For NIC's with DMA capability, the NIC driver MUST prepare DMA-transmit NIC packets from its own memory buffer(s) in order to avoid internal buffer corruption and deadlocks. The NIC driver's NetNIC_TxPktPrepare() function would Mem_Copy() the transmit packet from the ‘data’ portion of the network buffer pointed to by ppkt into the NIC's DMA memory buffer(s). The NIC driver could then configure the DMA transmit to start in NetNIC_TxPkt() or the NIC driver could wait until NetNIC_TxPkt() to start the DMA transmit. If a NIC does not have the capability to simultaneously prepare and transmit packet(s), this function is not necessary and the preparation for transmitting packet(s) may be fully implemented in the NetNIC_TxPkt(). In this case, the NIC driver does need not to implement the NetNIC_TxPktPrepare() function but the NET_NIC_CFG_TX_PKT_PREPARE_EN configuration constant MUST be configured as DEF_DISABLED. 99 8.05.08.02 net_nic.c, NetNIC_TxPkt() This function is called by the NetIF_Pkt_Tx() function to write a packet to the NIC for transmission. The pseudo-code and a portion of the actual code for this function is shown in listing 8-10. Note that if the packet is successfully written to the NIC, we assume that the packet has been sent and we thus increment the NetNIC_StatTxPktCtr counter using the NET_CTR_STAT_INC() macro. The local variable cpu_sr is necessary because the macro NET_CTR_STAT_INC() needs to increment NetNIC_StatTxPktCtr indivisibly. ppkt is a pointer to the first byte of data to write to the NIC. size is the number of bytes to write to the NIC. perr is a pointer to an variable that holds the error code reported by this function. Valid error code are: NET_NIC_ERR_NONE Packet successfully written/sent to the NIC. NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. NET_ERR_TX NIC Transmit error. The NIC packet transmit function can write data into the NIC octet-by-octet or by words. The NIC packet transmit function MUST read data from network buffers to ensure the following : 1) That the data reads from network buffers satisfies any CPU word-alignment requirements. Since various IF layers may require data to start on different word-aligned boundaries inside the network buffers, the packet data in the network buffer already ensures that internal accesses are CPU-word-size aligned. This means that the data must be read from network buffers either : a) Octet-by-octet starting from the data pointer address (ppkt) b) By words aligned to the starting data pointer address (ppkt) – which may NOT necessarily start on a CPU-word-size aligned boundary If the packet transmit data is written into the NIC in words, then the words must be appropriately constructed from network buffer data octets to satisfy the network CPU-word-size alignment requirements. 2) That the data writes into NIC transmit packets correctly order the data octets to maintain network-order. For NIC's with DMA capability, the NIC driver MUST DMA-transmit NIC packets from its own memory buffer(s) in order to avoid internal buffer corruption and deadlocks. The NIC driver's NetNIC_TxPkt() function would Mem_Copy() the transmit packet from the ‘data’ portion of the network buffer pointed to by ppkt into the NIC's DMA memory buffer(s). The NIC driver would then configure the DMA transmit to start immediately or at some later point in time. 100 Listing 8-10, Writing a packet to the NIC void NetNIC_TxPkt (void CPU_INT16U NET_ERR *ppkt, size, *perr) { #if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif if (Net_InitDone != DEF_YES) { *perr = NET_ERR_INIT_INCOMPLETE; return; } /* Abort transmission if init NOT complete */ Write the packet into the NIC packet from the buffer pointed to by ‘ppkt’ and with size ‘size’ : while (size > 0) { Read data octet from buffer; Write data octet into NIC; size--; } OR while (size > 0) { Read data word from buffer; if (data word aligned to NIC packet) { Write data word into NIC packet in network-order; } else { Split data word into octets; Write data octets into NIC packet in network-order; } size -= word - size; } if (*perr != NET_NIC_ERR_NONE) { NetNIC_TxPktDiscard(perr); return; } NET_CTR_STAT_INC(NetNIC_StatTxPktCtr); } 101 8.05.09 net_nic.c, NetNIC_RxISR_Handler() This function is called by NetNIC_ISR_Handler() (see section 8.05.04) to handle packet reception. Note that this is a local function because it’s called from within net_nic.c. We decided to make NetNIC_RxISR_Handler() a separate function to make the code cleaner. However, if your application needs every bit of performance, you can integrate the Rx portion of the handler directly in NetNIC_ISR_Handler(). NetNIC_RxISR_Handler() doesn’t actually do much except signal the Rx Packet Semaphore indicating that a packet was received from the NIC. This semaphore needs to be a counting semaphore because it needs to be able to ‘remember’ the number of times the NIC signaled the reception of packets which could happen if the NIC contains multiple receive buffers. Figure 8-3 shows the relationship between the NIC, the Rx ISR and the Rx task. Rx Packet Semaphore (1) IF Rx Task NetOS_IF_RxTaskWait() (Counting Semaphore) net_if_pkt.c NetOS_IF_RxTaskSignal() (5) net_os.c (2) NetNIC_RxISR_Handler() (3) NetNIC_ISR() NIC (4) Rx ISR NetNIC_ISR_Handler() net_nic.c net_bsp_a.s Network Figure 8-3, Packet reception interrupt and the Rx Packet Semaphore F8-3(1) The IF layer always waits for packets to arrive and thus waits forever for the Rx Packet Semaphore to be signaled. F8-3(2) When a packet arrives, the NIC signals the Rx Packet Semaphore (describe shortly) and the IF Rx Task reads the packet out of the NIC and places the read packet in a network buffer and passes this buffer to the upper layers of the protocol for processing. F8-3(3) When a packet is received, the NIC generates an interrupt and NetNIC_ISR() is invoked. F8-3(4) NetNIC_ISR() doesn’t do much because typically this function is written in assembly language and we prefer writing most of the code in C and thus, NetNIC_ISR() simply calls NetNIC_ISR_Handler() which determines that the cause of the interrupt was from a packet reception and thus, calls NetNIC_RxISR_Handler(). The pseudo-code and a portion of the actual code for this function is shown in listing 8-11. 102 F8-3(5) NetNIC_RxISR_Handler() doesn’t do much either except call NetOS_IF_RxTaskSignal() to notify the IF Rx Task that a packet was received. We decided to defer processing of the received packet to a task instead of handling it in the ISR to keep the ISR as short as possible and, make the driver easier to write. You will note that all RTOS related functions are encapsulated in a file called net_os.c. By simply changing the contents of net_os.c, you can adapt µC/TCP-IP to different RTOSs. Of course, for this to work, you need to maintain the same function names since the rest of the stack assumes these function names. Listing 8-11, Handling packet reception interrupts static void NetNIC_RxISR_Handler (void) { NET_ERR err; NetOS_IF_RxTaskSignal(&err); /* Signal Net IF Rx Task that NIC received a packet */ switch (err) { case NET_IF_ERR_NONE: Disable Rx interrupts from the NIC; break; case NET_IF_ERR_RX_Q_FULL: case NET_IF_ERR_RX_Q_POST_FAIL: default: NetNIC_RxPktDiscard(0, &err); break; } } With most NICs, the interrupt from the NIC is actually cleared when the NIC is read. Since we don’t actually read the NIC from the ISR, we must disable further Rx interrupts from the NIC until we actually read the NIC which is done in the IF Rx Task. 103 8.05.10 net_nic.c, NetNIC_TxISR_Handler() This function is called by NetNIC_ISR_Handler() when a packet is sent to the NIC. Note that this is a local function because it’s called from within net_nic.c. We decided to make NetNIC_TxISR_Handler() a separate function to make the code cleaner. However, if your application needs every bit of performance, you can integrate the Tx portion of the handler directly in NetNIC_ISR_Handler(). NetNIC_TxISR_Handler() doesn’t actually do much except signal the Tx Rdy Semaphore indicating that the NIC completed sending a packet or, is ready to send a packet. Figure 8-4 shows the relationship between the NIC, the Tx ISR and the IF layer. (1) IF NetOS_NIC_TxRdyWait() Tx Rdy Semaphore net_if_pkt.c NetOS_NIC_TxRdySignal() (5) net_os.c (2) NetNIC_TxISR_Handler() (3) NetNIC_ISR() NIC (4) Tx ISR NetNIC_ISR_Handler() net_nic.c net_isr_a.s Network Figure 8-4, Sending a packet and the Tx Rdy Semaphore F8-4(1) Before writing a packet to the NIC, the IF (Interface) layer needs to acquire the Tx Rdy Semaphore. A semaphore value greater than 0 indicates that the NIC is able to transmit a packet. A value of 0, indicates that the NIC is unable to send a packet because it’s already busy with processing a transmit request. The IF layer will thus WAIT (i.e. block) until the semaphore is signaled and thus available. F8-4(2) If the semaphore is available (a value greater than 0), the IF layer simply moves the packet to send onto the NIC for transmission. Of course, the semaphore value is decremented. This operation is performed atomically by your RTOS. 104 F8-4(3) F8-4(4) F8-4(5) When the NIC completes sending a packet, the NIC generates an interrupt. The function that handles the ISR is called NetNIC_ISR(). This function is found in net_bsp_a.s (or net_bsp.c if you can write all your ISRs in C). The NIC’s Tx ISR calls the C handler NetNIC_ISR_Handler() to handle most of the ISR in C instead of assembly language. Note that on some NICs, there is a single ISR for both Rx and Tx interrupts. In this case, the ISR handler determines whether the interrupt was caused by a received packet or, completion of a transmitted packet (or a transmit empty condition). For the transmission interrupt, NetNIC_ISR_Handler() calls NetNIC_TxISR_Handler() which signals the Tx Rdy Semaphore (by calling NetOS_NIC_TxRdySignal()) indicating that the NIC is able to send another packet (because it just completed sending a packet). If the IF layer blocked waiting for the semaphore then, it’s unblocked and the packet can be moved to the NIC as in F8-4(2). If the IF layer was not blocked (because it only had one packet to send) then, the semaphore is simply signaled and the Tx ISR terminates. The pseudo-code for NetNIC_TxISR_Handler() is shown in Listing 8-12. Listing 8-12, Handling packet transmission interrupts static void NetNIC_TxISR_Handler (void) { Acknowledge the Tx interrupt to clear the NIC interrupt; Re-enable Tx Interrupts; NetOS_NIC_TxRdySignal(); } 105 8.06 net_os.c net_os.c contains RTOS interface functions to make µC/TCP-IP independent of the actual RTOS used. In this section, we only discuss the RTOS functions related to the NIC driver but, net_os.c contains many more RTOS related services needed by the network stack. 8.06.01 net_os.c, NetOS_NIC_Init() This function is called to initialize RTOS objects used by the NIC driver. The NIC driver makes use of a semaphore that indicates when it’s able to transmit data to the NIC. Figure 8-4 showed the relationship between the Tx Rdy Semaphore, the NIC and the NIC’s Tx ISR. The initial value of the semaphore greatly depends on how the Tx Interrupt is generated for the specific NIC. For the generic configuration of the NIC Tx Rdy Semaphore for single-transmit-packet-buffer NICs ONLY, configure NET_NIC_CFG_TX_RDY_INIT_VAL in net_cfg.h as follows: 0 For NIC driver's that use the Transmit Empty interrupt 1 For NIC driver's that use the Transmit Complete interrupt NIC with Transmit Empty Interrupt: For example, if a NIC driver is coded to use the Transmit Empty interrupt (i.e. an interrupt is generated ONLY when the transmitter goes from non-empty to empty), NET_NIC_CFG_TX_RDY_INIT_VAL would be set to 0. The semaphore is initialized to 0 because as soon as we enable the transmit interrupt for the first time, the NIC will issue an interrupt. What we want to do is signal the semaphore to indicate that the transmitter is ready and then disable interrupts from the transmitter. The NIC Transmit Empty ISR must be written to: - Clear the ISR Clear the interrupt enable Signal the OS object that the transmit is empty It’s also important to note that NetNIC_TxPkt() (or a subfunction) must re-enable the transmit interrupt after the transmit data has been written into the NIC. NIC with Transmit Complete Interrupt: If a NIC driver is coded to use the Transmit Done/Complete interrupt (i.e. an interrupt is generated WHEN the transmitter is done transmitting a packet), NET_NIC_CFG_TX_RDY_INIT_VAL would be set to 1. The semaphore is initialized to 1 because at initialization, we would not transmit anything and thus, there would be no transmit complete interrupt issued. In other words, the transmit ready semaphore would indicate that the transmitter is ready to accept packets to send. The NIC Transmit Complete ISR must be written to: - Clear the ISR Signal the OS object that the transmit is empty You should note that the transmit interrupt is always enabled since it will only interrupt the CPU after a transmit packet has been sent. 106 The pseudo-code for NetOS_NIC_Init() is shown in listing 8-13. Listing 8-13, Initializing RTOS objects used by the NIC void { NetOS_NIC_Init (NET_ERR *perr) /* Initialize the Tx Rdy Semaphore (see above discussion for initial value) */ *perr = NET_ERR_NONE; } 107 8.06.02 net_os.c, NetOS_NIC_TxRdyWait() NetOS_NIC_TxRdyWait() is the function that the IF calls to determine if the NIC is able to receive a packet for transmission. Typically, the caller should block (i.e. wait forever) for the semaphore to be available. Alternatively, you can implement the code to block with a timeout (if your RTOS allows this) and take corrective action if the block times out. The pseudo-code for this function is shown in Listing 8-14. Listing 8-14, Waiting for the NIC to be ready to transmit packets void { NetOS_NIC_TxRdyWait (NET_ERR *perr) /* Wait for Tx Rdy Semaphore with optional timeout */ switch (semaphore wait error code) { case ‘no error’: *perr = NET_NIC_ERR_NONE; break; case ‘wait timed out’: default: *perr = NET_NIC_ERR_TX_RDY_SIGNAL_TIMEOUT; break; } } Note that this function needs to set *perr to either NET_NIC_ERR_NONE if the wait was successful or, NET_NIC_ERR_TX_RDY_SIGNAL_TIMEOUT if the wait timed out. 108 8.06.03 net_os.c, NetOS_NIC_TxRdySignal() This function is called by the NIC’s Tx handler to indicate that the NIC has completed transmission of a packet. This function should generally map to a single OS call to perform the signaling. The pseudo-code is shown in listing 8-15. Listing 8-15, Signaling completion of a transmitted packet void { NetOS_NIC_TxRdySignal (void) /* Signal that NIC has transmitted a packet } 109 */ Chapter 9 Configuration Manual µC/TCP-IP is configurable at compile time via about 50 #defines. Of these, 5 values may likely never change (there is only currently only one configuration choice). This leaves 45 or so values to configure. #defines are used because they allow code and data sizes to be scaled at compile time based on your selection. In other words, this allows the footprint of µC/TCP-IP to be adjusted based on your requirements. It’s recommended that you start your configuration process with the recommended values. When multiple values for a #define are possible, the recommended or default value is shown in RED. 110 9.01 Network Configuration There are two parameters to set for the network configuration: NET_CFG_INIT_CFG_VALS NET_CFG_OPTIMIZE 9.01.01 Network Configuration, NET_CFG_INIT_CFG_VALS This configuration constant is used to determine whether internal TCP/IP parameters are set to default values or, are set by the user. NET_CFG_INIT_CFG_VALS can take on of two values: NET_INIT_CFG_VALS_DFLT Configure µC/TCP-IP’s network parameters with default values. The application need only call Net_Init() to initialize both µC/TCP-IP and its configurable parameters. This configuration is highly recommended since configuring network parameters requires in-depth knowledge of the protocol stack. In fact, most books we have consulted recommend the default values that we selected. Parameter Units Minimum Maximum Default #Small Buffers #Small Buffers #Large Buffers #Large Buffers #Timers #Timers #Connections #Connections #ARP Caches #ARP Caches #TCP Connections #TCP Connections #Sockets #Sockets 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (19 / 20) * #Small Buffers ( 1 / 6) * #Small Buffers (19 / 20) * #Large Buffers ( 1 / 6) * #Large Buffers (19 / 20) * #Timers ( 1 / 6) * #Timers (19 / 20) * #Connections ( 1 / 6) * #Connections (19 / 20) * #ARP Caches ( 1 / 6) * #ARP Caches (19 / 20) * #TCP Connections ( 1 / 6) * #TCP Connections (19 / 20) * #Sockets ( 1 / 6) * #Sockets Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value Maximum Value NetDbg_MonTaskTime_sec Seconds 1 600 60 NetConn_AccessedTh_nbr #Connections 10 65000 100 NetARP_CacheTimeout_sec NetARP_CacheAccessedTh_nbr Seconds #ARP Caches 60 100 600 65000 60 1000 NetARP_ReqMaxAttempts_nbr NetARP_ReqTimeout_sec #Attempts Seconds 1 1 6 10 4 5 NetIP_AddrThisHost NetIP_AddrThisHostSubnetMask NetIP_AddrDfltGateway IP address IP address IP address 0.0.0.0 0.0.0.0 0.0.0.0 255.255.255.255 255.255.255.255 255.255.255.255 0.0.0.0 0.0.0.0 0.0.0.0 NetIP_FragReasmTimeout_sec Seconds 1 10 5 NetICMP_TxSrcQuenchTxTh_nbr #Source Quenches Transmitted 1 100 5 NetDbg_RsrcBufSmallThLo_nbr NetDbg_RsrcBufSmallThLoHyst_nbr NetDbg_RsrcBufLargeThLo_nbr NetDbg_RsrcBufLargeThLoHyst_nbr NetDbg_RsrcTmrThLo_nbr NetDbg_RsrcTmrThLoHyst_nbr NetDbg_RsrcConnThLo_nbr NetDbg_RsrcConnThLoHyst_nbr NetDbg_RsrcARP_CacheThLo_nbr NetDbg_RsrcARP_CacheThLoHyst_nbr NetDbg_RsrcTCP_ConnThLo_nbr NetDbg_RsrcTCP_ConnThLoHyst_nbr NetDbg_RsrcSockThLo_nbr NetDbg_RsrcSockThLoHyst_nbr Table 9-1, µC/TCP-IP Internal Parameters 111 NET_INIT_CFG_VALS_APP_INIT It’s possible to change the parameters listed in Table 9-1 by calling µC/TCP-IP functions that will do the work for you based on the parameter values you desire. Some of these values might in fact be stored in non-volatile memory that is recalled at power-up (e.g. using EEPROM or battery-backed RAM) by your application. If you select this option, you will need to initialize ALL of these configuration parameters. Alternatively, you can first call Net_InitDflt() to initialize all the parameter to their default values and then simply change only the ones you need afterwards. 112 9.01.02 Network Configuration, NET_CFG_OPTIMIZE Some of the code in µC/TCP-IP offers you the choice of optimizing the code for better performance or, for the smallest code size via the NET_CFG_OPTIMIZE value. The choices are: NET_OPTIMIZE_SPD Optimizes network protocol suite for best speed performance NET_OPTIMIZE_SIZE Optimizes network protocol suite for best binary image size 113 9.02 Debug Configuration A fair amount of code in µC/TCP-IP has been included to simplify debugging. Two configuration constants are used for this purpose: NET_DBG_CFG_DBG_INFO_EN NET_DBG_CFG_TEST_EN NET_DBG_CFG_MEM_CLR_EN 9.02.01 Debug Configuration, NET_DBG_CFG_DBG_INFO_EN This configuration constant is used to enable/disable network protocol suite debug information: - Internal constants assigned to global variables - Internal variable data sizes calculated & assigned to global variables - Run-time debug functions that provide information on : - Internal resource usage – low or lost resources - Internal faults or errors The value can either be: DEF_DISABLED or DEF_ENABLED 9.02.02 Debug Configuration, NET_DBG_CFG_MEM_CLR_EN This configuration constant is used to clear internal network data structures when allocated & deallocated. By clearing we mean setting all bytes in the data structures to 0 or to default initialization values. You can set this configuration constant to either: DEF_DISABLED or DEF_ENABLED You would typically set it to DEF_DISABLED unless you are debugging a Layer 7 application and you want to examine the contents of the buffer. Having the buffer cleared generally helps you differentiate between ‘proper’ data and ‘pollution’. 9.02.03 Debug Configuration, NET_DBG_CFG_TEST_EN This configuration constant is used internally for testing/debugging purposes and can be set to either: DEF_DISABLED or DEF_ENABLED 114 9.03 Argument Checking Configuration Most functions in µC/TCP-IP include code to validate arguments that are passed to it. Specifically, µC/TCP-IP as code to check to see if a passed pointer is a NULL pointer, if an argument is within a valid range, etc. Two configuration constants are used for this purpose: NET_ERR_CFG_ARG_CHK_EXT_EN NET_ERR_CFG_ARG_CHK_DBG_EN 9.03.01 Argument Checking Configuration, NET_ERR_CFG_ARG_CHK_EXT_EN This configuration constant allows code to be generated to check arguments for functions that can be called by the user and, for functions which are internal but receives arguments from an API that the user can call. Also, enabling this check verifies whether µC/TCP-IP is initialized before API tasks and functions perform the desired function. You can set this configuration constant to either: DEF_DISABLED or DEF_ENABLED 9.03.02 Argument Checking Configuration, NET_ERR_CFG_ARG_CHK_DBG_EN This configuration constant allows code to be generated which checks to make sure that pointers passed to functions are not NULL, that arguments are within range, etc. You can set this configuration constant to either: DEF_DISABLED or DEF_ENABLED 115 9.04 Counters Configuration µC/TCP-IP contains code that increments counters to keep of statistics such as the number of packets received, the number of packets transmitted, etc. Also, µC/TCP-IP contains counters that are incremented when error conditions are detected. There are two configuration constants for this: NET_CTR_CFG_STAT_EN NET_CTR_CFG_ERR_EN 9.04.01 Counters Configuration, NET_CTR_CFG_STAT_EN This configuration constant determines whether the code and data space used to keep track of statistics will be included. You can set this configuration constant to either: DEF_DISABLED or DEF_ENABLED 9.04.02 Counters Configuration, NET_CTR_CFG_ERR_EN This configuration constant determines whether the code and data space used to keep track of errors will be included. You can set this configuration constant to either: DEF_DISABLED or DEF_ENABLED 116 9.05 Timers Configuration µC/TCP-IP manages software timers that are used to keep track of timeouts. There are currently only two configuration options for timers: NET_TMR_CFG_NBR_TMR NET_TMR_CFG_TASK_FREQ 9.05.01 Timers Configuration, NET_TMR_CFG_NBR_TMR This configuration constant determines the number of timers that µC/TCP-IP will be managing. Of course, the number of timers affect the amount of RAM required by µC/TCP-IP. Each timer requires 8 bytes plus 4 pointers. Timers are required for: - The Network Debug Monitor Task Each ARP cache entry Each IP fragment reassembly Each TCP connection 1 total 1 per ARP cache 1 per IP fragment chain 7 per TCP connection A good starting point may be to allocate the maximum number of timers for all resources. For instance, if the Network Debug Monitor Task is enabled (see section 18.30), 20 ARP caches are configured (NET_ARP_CFG_NBR_CACHE = 20), & 10 TCP connections are configured (NET_TCP_CFG_NBR_CONN = 10); the maximum number of timers for these resources is 1 for the Network Debug Monitor Task, (20 * 1) for the ARP caches and, (10 * 7) for the TCP connections : # Timers = 9.05.02 1 + (20 * 1) + (10 * 7) = 91 Timers Configuration, NET_TMR_CFG_TASK_FREQ This configuration constant determines how often (in Hz) the network timers are to be updated. This value MUST NOT be configured as a floating-point number. You would be typically set this value to 10 Hz. 117 9.06 Network Buffers Configuration µC/TCP-IP places received packets in network buffers to be processed by the upper layers and also, places data to send in network buffers. There are two types of buffers as shown in Figure 9-1: small and large. Each buffer contains a header portion that is used by µC/TCP-IP. This header provides information to µC/TCP-IP about the contents of the buffer. The data portion contains the data that has either been received by the NIC and thus will be processed by µC/TCP-IP or, data that is destined for the NIC. Small buffers are used by µC/TCP-IP when received data or, data to transmit fits in this size buffer. The header structure is common to both types of buffers. A header currently requires about 200 bytes of storage. Large Buffer Small Buffer Network Buffer Header NET_BUF_CFG_DATA_SIZE_SMALL Network Buffer Data NET_BUF_CFG_DATA_SIZE_LARGE Figure 9-1, µC/TCP-IP’s small and large buffers There are currently four configurable options for network buffers: NET_BUF_CFG_NBR_SMALL NET_BUF_CFG_NBR_LARGE NET_BUF_CFG_DATA_SIZE_SMALL NET_BUF_CFG_DATA_SIZE_LARGE 118 9.06.01 Network Buffers Configuration, NET_BUF_CFG_NBR_SMALL This configuration constant determines the number of small network buffers used by µC/TCP-IP. The number of buffers needed depends on the run-time behavior of your network and the expected traffic on the network. We tested µC/TCP-IP with 20 small buffers. 9.06.02 Network Buffers Configuration, NET_BUF_CFG_NBR_LARGE This configuration constant determines the number of large network buffers used by µC/TCP-IP. The number of buffers needed depends on the run-time behavior of your network and the expected traffic on the network. We tested µC/TCP-IP with 20 large buffers. 9.06.03 Network Buffers Configuration, NET_BUF_CFG_DATA_SIZE_SMALL The configuration constant determines the size of the data portion for small buffers. The recommended size for small buffers is around 256 bytes. 9.06.04 Network Buffers Configuration, NET_BUF_CFG_DATA_SIZE_LARGE The configuration constant determines the size of the data portion for large buffers. Typically you would set large buffers to the largest packet that can be sent on the NIC. In the case of Ethernet, you should set this buffer to 1596. 119 9.07 NIC (Network Interface Controller) Configuration Currently, two parameters need to be configured for the NIC: NET_NIC_CFG_TX_RDY_INIT_VAL NET_NIC_CFG_INT_CTRL_EN 9.07.01 NIC Configuration, NET_NIC_CFG_TX_RDY_INIT_VAL This configuration constant determines the initial value of the semaphore used to indicate whether the NIC is ready to transmit packet or not. Refer to the discussion on NetOS_NIC_Init() in the NIC Driver chapter. This value greatly depends on the type of NIC used. 9.07.02 NIC Configuration, NET_NIC_CFG_INT_CTRL_EN This configuration constant tells the NIC driver whether there is an interrupt controller in your system. This is needed to allow the NIC to call a function to clear the interrupt source from the interrupt controller. This function is: NetNIC_IntClr(). This configuration value can either be set to: DEF_DISABLED There is no interrupt controller in your system DEF_ENABLED There is an interrupt controller in your system or 9.07.03 NIC Configuration, NET_NIC_CFG_RD_WR_SEL This optional configuration constant tells the NIC driver how the board-specific read/write functionality of the NIC should be implemented. This configuration value can either be set to: NET_NIC_RD_WR_SEL_MACRO NIC read/write functionality SHOULD be implemented with macro's in the applications net_bsp.h NET_NIC_RD_WR_SEL_FNCT NIC read/write functionality SHOULD be implemented with functions in the applications net_bsp.c and MUST be prototyped in the NIC's net_nic.h or 120 9.08 Network Interface Layer Configuration These configuration constants are used by the Interface Layer (IF layer). There are currently two configuration constants to set: NET_IF_CFG_TYPE NET_IF_CFG_ADDR_FLTR_EN 9.08.01 Network Interface Layer Configuration, NET_IF_CFG_TYPE This configuration constant determines the type of network interface used by µC/TCP-IP. Currently, only Ethernet NICs can be used and thus, this parameter should ALWAYS be set to NET_IF_TYPE_ETHER. 9.08.02 Network Interface Layer Configuration, NET_IF_CFG_ADDR_FLTR_EN This configuration constant determines whether address filtering is enabled or not. This configuration value can either be set to: DEF_DISABLED Addresses are NOT filtered DEF_ENABLED Addresses are filtered or 121 9.09 ARP (Address Resolution Protocol) Configuration ARP is only required for some network interfaces like Ethernet. There are currently four configuration constants to set: NET_ARP_CFG_HW_TYPE NET_ARP_CFG_PROTOCOL_TYPE NET_ARP_CFG_NBR_CACHE NET_ARP_CFG_ADDR_FLTR_EN 9.09.01 ARP Configuration, NET_ARP_CFG_HW_TYPE The current version of µC/TCP-IP only supports Ethernet-type networks and thus, this configuration constant should ALWAYS be set to NET_ARP_HW_TYPE_ETHER. 9.09.02 ARP Configuration, NET_ARP_CFG_PROTOCOL_TYPE The current version of µC/TCP-IP only supports IP v4 and thus, this configuration constant should ALWAYS be set to NET_ARP_PROTOCOL_TYPE_IP_V4. 9.09.03 ARP Configuration, NET_ARP_CFG_NBR_CACHE ARP caches the mapping of IP addresses to physical (i.e. MAC) addresses. The number of cache entries depends on the size of your local network and the number of different hosts you expect your product to be communicating with. Each cache entry requires about 50 bytes of RAM (assuming IPv4, Ethernet NICs and 32-bit pointers). We tested µC/TCP-IP with a fairly small network and we set the size to 10. 9.09.04 ARP Configuration, NET_ARP_CFG_ADDR_FLTR_EN This configuration constant determines whether address filtering is enabled or not. This configuration value can either be set to: DEF_DISABLED Addresses are NOT filtered DEF_ENABLED Addresses are filtered or 122 9.10 ICMP (Internet Control Message Protocol) Configuration The ICMP configuration currently only requires you to set two configuration constants: NET_ICMP_CFG_MON_TASK_EN NET_ICMP_CFG_TX_SRC_QUENCH_SIZE 9.10.01 ICMP Configuration, NET_ICMP_CFG_TX_SRC_QUENCH_EN ICMP transmits ICMP source quench messages to other hosts when the Network Resources are low (see section 18.30). This configuration value can either be set to: DEF_DISABLED ICMP Transmit Source Quenches disabled DEF_ENABLED ICMP Transmit Source Quenches enabled or 9.10.02 ICMP Configuration, NET_ICMP_CFG_TX_SRC_QUENCH_SIZE This configuration value sets the ICMP transmit source quench list size. The recommended initial value for this parameter is 10. 123 9.11 Transport Layer Configuration, NET_CFG_TRANSPORT_LAYER_SEL µC/TCP-IP allows you to either select to include code for UDP or for both UDP and TCP. Of course, enabling only UDP would reduce both the code size and data size required by µC/TCP-IP. However, some application software may need TCP. The allowable values for this configuration constant are: NET_TRANSPORT_LAYER_SEL_UDP_TCP or NET_TRANSPORT_LAYER_SEL_UDP 124 9.12 UDP (User Datagram Protocol) Configuration UDP configuration currently only requires you to set three configuration constants: NET_UDP_CFG_APP_API_SEL NET_UDP_CFG_RX_CHK_SUM_DISCARD_EN NET_UDP_CFG_TX_CHK_SUM_EN 9.12.01 UDP Configuration, NET_UDP_CFG_APP_API_SEL This configuration constant is used to determine where to send the demultiplexed UDP datagram. Specifically, the datagram may be sent to the socket layer, only to a function you would write in your application or both. The allowable values for this parameter are: NET_UDP_APP_API_SEL_SOCK Only send datagram to socket layer NET_UDP_APP_API_SEL_APP Only send datagram to your application NET_UDP_APP_API_SEL_SOCK_APP Send datagram first to the socket layer then, your application If your application is to receive the datagram then, you will need to define the following function in your application to process the datagram received: void 9.12.02 NetUDP_RxAppDataHandler(NET_BUF NET_IP_ADDR NET_UDP_PORT_NBR NET_IP_ADDR NET_UDP_PORT_NBR NET_ERR *pbuf, src_addr, src_port, dest_addr, dest_port, *perr); UDP Configuration, NET_UDP_CFG_RX_CHK_SUM_DISCARD_EN This configuration constant is used to determine whether packets received without a valid checksum are discarded or kept. Before a UDP Datagram Check-Sum is validated, it is necessary to check whether the UDP datagram was transmitted with or without a computed Check-Sum (see RFC #768, Section 'Fields : Checksum'). See also net_udp.c NetUDP_RxPktValidate(), note #6d. This configuration value can either be set to: DEF_DISABLED ALL UDP datagrams received without a check-sum are flagged so that "an application may optionally discard datagrams without checksums" (see RFC #1122, Section 4.1.3.4). DEF_ENABLED ALL UDP datagrams received without a checksum are discarded. or 125 9.12.03 UDP Configuration, NET_UDP_CFG_TX_CHK_SUM_EN This configuration constant is used to determine whether UDP checksums are computed for transmission to other hosts. An application MAY optionally be able to control whether a UDP checksum will be generated (see RFC #1122, Section 4.1.3.4). See also net_udp.c NetUDP_TxPktPrepareHdr(), note #4b. This configuration value can either be set to: DEF_DISABLED ALL UDP datagrams are transmitted without a computed checksum DEF_ENABLED ALL UDP datagrams are transmitted with a computed checksum or 126 9.13 TCP (Transport Control Protocol) Configuration, NET_TCP_CFG_NBR_CONN TDP configuration currently only requires you to set four configuration constants: NET_TCP_CFG_NBR_CONN NET_TCP_CFG_RX_WIN_SIZE_OCTET NET_TCP_CFG_TX_WIN_SIZE_OCTET NET_TCP_CFG_TIMEOUT_CONN_MAX_SEG_SEC NET_TCP_CFG_TIMEOUT_CONN_ACK_DLY_MS NET_TCP_CFG_TIMEOUT_CONN_RX_Q_MS NET_TCP_CFG_TIMEOUT_CONN_TX_Q_MS 9.13.01 TCP, NET_TCP_CFG_NBR_CONN This configuration constant establishes the maximum number of concurrent TCP connections that µC/TCP-IP will be able to handle. This value is application specific. 9.13.02 TCP, NET_TCP_CFG_RX_WIN_SIZE_OCTET This configuration constant sets the connection receive window size. We recommend starting with a value of 4096. 9.13.03 TCP, NET_TCP_CFG_TX_WIN_SIZE_OCTET This configuration constant sets the connection transmit window size. We recommend starting with a value of 8192. 9.13.04 TCP, NET_TCP_CFG_TIMEOUT_CONN_MAX_SEG_SEC Configures TCP connections default maximum segment lifetime timeout (MSL) value. The value is specified in integer seconds. We recommend starting with a value of 3 seconds. 9.13.05 TCP, NET_TCP_CFG_TIMEOUT_CONN_ACK_DLY_MS The constant sets up the TCP acknowledgement delay in integer milliseconds. RFC #2581, Section 4.2 states that "an ACK MUST be generated within 500 ms of the arrival of the first unacknowledged packet". Thus, 500 ms is the default value. 127 9.13.06 TCP, NET_TCP_CFG_TIMEOUT_CONN_RX_Q_MS Configures TCP connection receive queue timeout (in milliseconds OR no timeout if configured with NET_TMR_TIME_INFINITE). We recommend starting with a value of 3000 milliseconds OR the no-timeout value of NET_TMR_TIME_INFINITE. 9.13.07 TCP, NET_TCP_CFG_TIMEOUT_CONN_TX_Q_MS Configures TCP connection transmit queue timeout (in milliseconds OR no timeout if configured with NET_TMR_TIME_INFINITE). We recommend starting with a value of 3000 milliseconds OR the no-timeout value of NET_TMR_TIME_INFINITE. 128 9.14 BSD v4 Sockets Configuration The BSD v4 socket configuration currently only requires you to set nine values: NET_SOCK_CFG_FAMILY NET_SOCK_CFG_NBR_SOCK NET_SOCK_CFG_BLOCK_SEL NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX NET_SOCK_CFG_PORT_NBR_RANDOM_BASE NET_SOCK_CFG_TIMEOUT_RX_Q_MS NET_SOCK_CFG_TIMEOUT_CONN_REQ_MS NET_SOCK_CFG_TIMEOUT_CONN_ACCEPT_MS NET_SOCK_CFG_TIMEOUT_CONN_CLOSE_MS 9.14.01 BSD v4 Sockets Configuration, NET_SOCK_CFG_FAMILY The current version of µC/TCP-IP only supports one option for this parameter: NET_SOCK_FAMILY_IP_V4. 9.14.02 BSD v4 Sockets Configuration, NET_SOCK_CFG_NBR_SOCK This configuration constant determines the maximum number of sockets that can be opened at the same time. This value is application specific. 9.14.03 BSD v4 Sockets Configuration, NET_SOCK_CFG_BLOCK_SEL This configuration constant determines the default blocking (or non-blocking) behavior for sockets. The default is non-blocking. This parameter can take the following values: Use the default (i.e. non-blocking) Sockets will be blocking by default Sockets will be non-blocking by default NET_SOCK_BLOCK_SEL_DFLT NET_SOCK_BLOCK_SEL_BLOCK NET_SOCK_BLOCK_SEL_NO_BLOCK If you select blocking mode, you can block with a timeout. The amount of time for the timeout is determined by various timeout functions implemented in net_sock.c : NetSock_CfgTimeoutRxQ_Set() NetSock_CfgTimeoutConnReqSet() NetSock_CfgTimeoutConnAcceptSet() NetSock_CfgTimeoutConnCloseSet() 9.14.04 BSD v4 API Configuration, NET_SOCK_CFG_SEL_EN . This configuration value can either be set to: DEF_DISABLED BSD select() API disabled DEF_ENABLED BSD select() API enabled or 129 9.14.05 BSD v4 Sockets Configuration, NET_SOCK_CFG_SEL_NBR_EVENTS_MAX This configuration constant is used to configure the maximum number of socket events/operations that select() can wait on. One recommended initial value for this parameter is 10. 9.14.06 BSD v4 Sockets Configuration, NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX This configuration constant is used to configure stream-type sockets' accept queue maximum size. recommended initial value for this parameter is 5. 9.14.07 One BSD v4 Sockets Configuration, NET_SOCK_CFG_PORT_NBR_RANDOM_BASE This configuration constant is used to establish the starting number for the ‘random port number’. Since two times the number of random ports are required for each socket, the base value for the random port number must be : Random Port Number Base <= 65535 – (2 * NET_SOCK_CFG_NBR_SOCK) The arbitrary default value of 65000 is a good starting point for NET_SOCK_CFG_NBR_SOCK values less than 18. 9.14.08 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_RX_Q_MS This configuration constant is used to establish a socket receive queue timeout (in milliseconds OR no timeout if configured with NET_TMR_TIME_INFINITE). We recommend starting with a value of 3000 milliseconds OR the no-timeout value of NET_TMR_TIME_INFINITE. 9.14.09 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_CONN_REQ_MS This configuration constant is used to establish a socket connection request timeout (in milliseconds OR no timeout if configured with NET_TMR_TIME_INFINITE). We recommend starting with a value of at least 10000 milliseconds OR the no-timeout value of NET_TMR_TIME_INFINITE. 9.14.10 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_CONN_ACCEPT_MS This configuration constant is used to establish a socket connection accept timeout (in milliseconds OR no timeout if configured with NET_TMR_TIME_INFINITE). We recommend starting with a value of at least 3000 milliseconds OR the no-timeout value of NET_TMR_TIME_INFINITE. 9.14.11 BSD v4 Sockets Configuration, NET_SOCK_CFG_TIMEOUT_CONN_CLOSE_MS This configuration constant is used to establish a socket connection close timeout (in milliseconds OR no timeout if configured with NET_TMR_TIME_INFINITE). We recommend starting with a value of at least 10000 milliseconds. 130 9.14.12 BSD v4 API Configuration, NET_BSD_CFG_API_EN . This configuration value can either be set to: DEF_DISABLED BSD 4.x layer API disabled DEF_ENABLED BSD 4.x layer API enabled or 131 9.15 Connection Manager Configuration This section defines the connection manager’s configuration. There are two configuration constants in this section: NET_CONN_CFG_FAMILY NET_CONN_CFG_NBR_CONN 9.15.01 Connection Manager Configuration, NET_CONN_CFG_FAMILY This configuration constant determines the connection manager’s family and should always be set to NET_CONN_FAMILY_IP_V4_SOCK. 9.15.02 Connection Manager Configuration, NET_CONN_CFG_NBR_CONN This configuration constant determines the total number of connections for the stack. The configured number of connections MUST be greater than the configured/required/expected number of application connections & transport layer connections. 132 9.16 Application-Specific Configuration, app_cfg.h This section defines the configuration constants that are related to µC/TCP-IP but are application-specific. Most of these configuration constants relate to the various ports for µC/TCP-IP such as the CPU, OS, NIC, or network interface ports. Some of the configuration constants relate to the compiler and standard library ports. These configuration constants should be defined in an application's app_cfg.h file. 9.16.01 Application-Specific Configuration, Operating System Configuration These configuration constants relate to the µC/TCP-IP OS port. For many OSs, the µC/TCP-IP task priorities, stack sizes, and other options may need to be explicitly configured. The priority of µC/TCP-IP tasks is dependent on the network communication requirements of the application. For most applications, the priority for µC/TCP-IP tasks is typically lower than the priority for other application tasks. Consult the specific OS's documentation to determine the OS's priority scheme. For µC/OS-II, the following OS task priorities and OS stack sizes must be configured: NET_OS_CFG_IF_RX_TASK_PRIO NET_OS_CFG_TMR_TASK_PRIO 50 51 The arbitrary task priorities of 50 and 51 are a good starting point for most applications. NET_OS_CFG_TMR_TASK_STK_SIZE NET_OS_CFG_IF_RX_TASK_STK_SIZE 1000 1000 The arbitrary stack size of 1000 is a good starting point for most applications. 133 9.16.02 Application-Specific Configuration, uC_CFG_OPTIMIZE_ASM_EN This configuration constant determines whether optimized assembly files/functions should be included in the µC/TCP-IP build. µC/TCP-IP optimization file(s), which are available only for certain processors and compilers, are located in the following directories: \<µC-TCPIP>\Ports\ \ \ where <µC-TCPIP> directory directory directory directory path name name name for for for for µC/TCP-IP ALL processor specific code specific processor (CPU) specific compiler Currently, only the following optimization files/functions are available for µC/TCP-IP: \<µC-TCPIP>\Ports\ \ \net_util_a.asm NetUtil_16BitSumDataCalcAlign_32() The uC_CFG_OPTIMIZE_ASM_EN configuration value can either be set to: DEF_DISABLED No optimized assembly files/functions are included in the µC/TCP-IP build. or DEF_ENABLED Optimized assembly files/functions are included in the µC/TCP-IP build. 134 Chapter 10 Debug Management µC/TCP-IP contains debug constants & functions that may be used by applications to determine network RAM usage, check run-time network resource usage, or check network error or fault conditions. These constants & functions are found in net_dbg.*. Most of these debug features must be enabled by appropriate configuration constants (see Chapter 9). 10.01 Network Debug Information Constants Network debug information constants provide the developer with run-time statistics on µC/TCP-IP configuration, data type & structure sizes, & data RAM usage. The list of debug information constants can be found in net_dbg.c Sections GLOBAL NETWORK MODULE DEBUG INFORMATION CONSTANTS & GLOBAL NETWORK MODULE DATA SIZE CONSTANTS. These debug constants are enabled by configuring NET_DBG_CFG_DBG_INFO_EN to DEF_ENABLED. You could use these constants as follows: CPU_INT16U CPU_INT32U CPU_INT32U CPU_INT32U net_version; net_data_size; net_data_size_buf_large; net_data_size_buf_large_tbl; net_version net_data_size net_data_size_buf_large net_data_size_buf_large_tbl = = = = Net_Version; Net_DataSize; NetBuf_LargeSize; NetBuf_LargeTblSize; printf(“µC/TCP-IP Version : printf(“Total Network RAM Used : printf(“Large Network Buffer Size : printf(“Large Network Buffer Table Size : %05d\n”, %05d\n”, %05d\n”, %05d\n”, 135 net_version); net_data_size); net_data_size_buf_large); net_data_size_buf_large_tbl); 10.02.01 Check Network Status, NetDbg_ChkStatus() This function returns the current run-time status of certain µC/TCP-IP conditions. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED. The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatus (void) The function returns NET_DBG_STATUS_OK if all network conditions are OK; i.e. no warnings, faults, or errors currently exist. Otherwise, the function returns the following status condition codes logically OR'd : NET_DBG_STATUS_FAULT Some network status fault(s). NET_DBG_STATUS_RSRC_LOST NET_DBG_STATUS_RSRC_LO Some network resources lost. Some network resources low. NET_DBG_STATUS_FAULT_BUF NET_DBG_STATUS_FAULT_TMR NET_DBG_STATUS_FAULT_CONN NET_DBG_STATUS_FAULT_TCP Some network buffer management fault(s). Some network timer management fault(s). Some network connection management fault(s). Some TCP layer fault(s). You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN CPU_BOOLEAN CPU_BOOLEAN CPU_BOOLEAN net_status net_fault net_fault_conn net_rsrc_lost net_rsrc_lo net_status; net_fault; net_fault_conn; net_rsrc_lost; net_rsrc_low; = = = = = NetDbg_ChkStatus(); DEF_BIT_IS_SET(net_status, DEF_BIT_IS_SET(net_status, DEF_BIT_IS_SET(net_status, DEF_BIT_IS_SET(net_status, 136 NET_DBG_STATUS_FAULT); NET_DBG_STATUS_FAULT_CONN); NET_DBG_STATUS_RSRC_LOST); NET_DBG_STATUS_RSRC_LO); 10.02.02 Check Network Resources Lost Status, NetDbg_ChkStatusRsrcLost() This function returns whether any µC/TCP-IP resources have been lost. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED. The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatusRsrcLost (void) The function returns NET_DBG_STATUS_OK if no network resources lost. Otherwise, the function returns the following resources lost condition codes logically OR'd : Some network resources lost. Some network SMALL buffer resources lost. Some network LARGE buffer resources lost. Some network timer resources lost. Some network connection resources lost. Some network ARP cache resources lost. Some network TCP connection resources lost. Some network socket resources lost. NET_DBG_SF_RSRC_LOST NET_DBG_SF_RSRC_LOST_BUF_SMALL NET_DBG_SF_RSRC_LOST_BUF_LARGE NET_DBG_SF_RSRC_LOST_TMR NET_DBG_SF_RSRC_LOST_CONN NET_DBG_SF_RSRC_LOST_ARP_CACHE NET_DBG_SF_RSRC_LOST_TCP_CONN NET_DBG_SF_RSRC_LOST_SOCK You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN CPU_BOOLEAN CPU_BOOLEAN CPU_BOOLEAN net_status; net_rsrc_lost; net_rsrc_lost_tmr; net_rsrc_lost_conn; net_rsrc_lost_sock; net_status net_rsrc_lost net_rsrc_lost_tmr net_rsrc_lost_conn net_rsrc_lost_sock = = = = = NetDbg_ChkStatusRsrcLost(); DEF_BIT_IS_SET(net_status, NET_DBG_SF_RSRC_LOST); DEF_BIT_IS_SET(net_status, NET_DBG_SF_RSRC_LOST_TMR); DEF_BIT_IS_SET(net_status, NET_DBG_SF_RSRC_LOST_CONN); DEF_BIT_IS_SET(net_status, NET_DBG_SF_RSRC_LOST_SOCK); 137 10.02.03 Check Network Resources Low Status, NetDbg_ChkStatusRsrcLow() This function returns whether any µC/TCP-IP resources are currently low. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED or when the Debug Monitor Task itself is enabled (see section 10.30). The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatusRsrcLow (void) The function returns NET_DBG_STATUS_OK if no network resources are low. Otherwise, the function returns the following resources low condition codes logically OR'd : NET_DBG_SF_RSRC_LO NET_DBG_SF_RSRC_LO_BUF_SMALL NET_DBG_SF_RSRC_LO_BUF_LARGE NET_DBG_SF_RSRC_LO_TMR NET_DBG_SF_RSRC_LO_CONN NET_DBG_SF_RSRC_LO_ARP_CACHE NET_DBG_SF_RSRC_LO_TCP_CONN NET_DBG_SF_RSRC_LO_SOCK Some network Network SMALL buffer Network LARGE buffer Network timer Network connection Network ARP cache Network TCP connection Network socket resources low. resources low. resources low. resources low. resources low. resources low. resources low. resources low. You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN CPU_BOOLEAN CPU_BOOLEAN CPU_BOOLEAN net_status net_rsrc_lo net_rsrc_lo_tmr net_rsrc_lo_conn net_rsrc_lo_sock net_status; net_rsrc_lo; net_rsrc_lo_tmr; net_rsrc_lo_conn; net_rsrc_lo_sock; = = = = = NetDbg_ChkStatusRsrcLo(); DEF_BIT_IS_SET(net_status, DEF_BIT_IS_SET(net_status, DEF_BIT_IS_SET(net_status, DEF_BIT_IS_SET(net_status, 138 NET_DBG_SF_RSRC_LO); NET_DBG_SF_RSRC_LO_TMR); NET_DBG_SF_RSRC_LO_CONN); NET_DBG_SF_RSRC_LO_SOCK); 10.02.04 Check Network Buffers Status, NetDbg_ChkStatusBufs() This function returns the current run-time status of µC/TCP-IP buffers. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED. The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatusBufs (void) The function returns NET_DBG_STATUS_OK if all network buffers are OK; i.e. no buffer faults currently exist. Otherwise, the function returns the following network buffer fault codes logically OR'd : NET_DBG_SF_BUF Some network buffer management fault(s). NET_DBG_SF_BUF_SMALL_TYPE NET_DBG_SF_BUF_SMALL_ID NET_DBG_SF_BUF_SMALL_LINK_TYPE NET_DBG_SF_BUF_SMALL_LINK_UNUSED NET_DBG_SF_BUF_SMALL_LINK_BACK_TO_BUF NET_DBG_SF_BUF_SMALL_LINK_NOT_TO_BUF NET_DBG_SF_BUF_SMALL_LINK_TO_BUF NET_DBG_SF_BUF_SMALL_POOL_TYPE NET_DBG_SF_BUF_SMALL_POOL_ID NET_DBG_SF_BUF_SMALL_POOL_DUP NET_DBG_SF_BUF_SMALL_POOL_NBR_MAX Small buffer invalid type. Small buffer invalid ID. Small buffer invalid link type. Small buffer link unused. Small buffer invalid link back to same buffer. Small buffer invalid link NOT back to same buffer. Small buffer invalid link back to buffer. Small buffer invalid pool buffer type. Small buffer invalid pool buffer ID. Small buffer pool contains duplicate buffer(s). Small buffer pool number of buffers greater than maximum number of small buffers. Small buffer used but in pool. Small buffer unused but NOT in pool. NET_DBG_SF_BUF_SMALL_USED_IN_POOL NET_DBG_SF_BUF_SMALL_UNUSED_NOT_IN_POOL NET_DBG_SF_BUF_LARGE_TYPE NET_DBG_SF_BUF_LARGE_ID NET_DBG_SF_BUF_LARGE_LINK_TYPE NET_DBG_SF_BUF_LARGE_LINK_UNUSED NET_DBG_SF_BUF_LARGE_LINK_BACK_TO_BUF NET_DBG_SF_BUF_LARGE_LINK_NOT_TO_BUF NET_DBG_SF_BUF_LARGE_LINK_TO_BUF NET_DBG_SF_BUF_LARGE_POOL_TYPE NET_DBG_SF_BUF_LARGE_POOL_ID NET_DBG_SF_BUF_LARGE_POOL_DUP NET_DBG_SF_BUF_LARGE_POOL_NBR_MAX NET_DBG_SF_BUF_LARGE_USED_IN_POOL NET_DBG_SF_BUF_LARGE_UNUSED_NOT_IN_POOL Large buffer invalid type. Large buffer invalid ID. Large buffer invalid link type. Large buffer link unused. Large buffer invalid link back to same buffer. Large buffer invalid link NOT back to same buffer. Large buffer invalid link back to buffer. Large buffer invalid pool buffer type. Large buffer invalid pool buffer ID. Large buffer pool contains duplicate buffer(s). Large buffer pool number of buffers greater than maximum number of large buffers. Large buffer used but in pool. Large buffer unused but NOT in pool. You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN net_status; net_fault_buf; net_status = NetDbg_ChkStatusBufs(); net_fault_buf = DEF_BIT_IS_SET(net_status, NET_DBG_SF_BUF); 139 10.02.05 Check Network Timers Status, NetDbg_ChkStatusTmrs() This function returns the current run-time status of µC/TCP-IP timers. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED. The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatusTmrs (void) The function returns NET_DBG_STATUS_OK if all network timers are OK; i.e. no timer faults currently exist. Otherwise, the function returns the following network timer fault codes logically OR'd : NET_DBG_SF_TMR Some network timer management fault(s). NET_DBG_SF_TMR_TYPE NET_DBG_SF_TMR_ID NET_DBG_SF_TMR_LINK_TYPE NET_DBG_SF_TMR_LINK_UNUSED NET_DBG_SF_TMR_LINK_BACK_TO_TMR NET_DBG_SF_TMR_LINK_TO_TMR Network timer invalid type. Network timer invalid id. Network timer invalid link type. Network timer link unused. Network timer invalid link back to same timer. Network timer invalid link back to timer. NET_DBG_SF_TMR_POOL_TYPE NET_DBG_SF_TMR_POOL_ID NET_DBG_SF_TMR_POOL_DUP NET_DBG_SF_TMR_POOL_NBR_MAX Network timer invalid pool type. Network timer invalid pool ID. Network timer pool contains duplicate timer(s). Network timer pool number of timers greater than maximum number of timers. NET_DBG_SF_TMR_LIST_TYPE NET_DBG_SF_TMR_LIST_ID NET_DBG_SF_TMR_LIST_DUP NET_DBG_SF_TMR_LIST_NBR_MAX Network timer task list invalid type. Network timer task list invalid ID. Network timer task list contains duplicate timer(s). Network timer task list number of timers greater than maximum number of timers. Network timer task list number of timers NOT equal to number of used timers. NET_DBG_SF_TMR_LIST_NBR_USED NET_DBG_SF_TMR_USED_IN_POOL NET_DBG_SF_TMR_UNUSED_NOT_IN_POOL NET_DBG_SF_TMR_UNUSED_IN_LIST Network timer used but in pool. Network timer unused but NOT in pool. Network timer unused but in timer task list. You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN net_status; net_fault_tmr; net_status = NetDbg_ChkStatusTmrs(); net_fault_tmr = DEF_BIT_IS_SET(net_status, NET_DBG_SF_TMR); 140 10.02.06 Check Network Connections Status, NetDbg_ChkStatusConns() This function returns the current run-time status of µC/TCP-IP connections. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED and when the Network Connections module itself is enabled. The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatusConns (void) The function returns NET_DBG_STATUS_OK if all network connections are OK; i.e. no connection faults currently exist. Otherwise, the function returns the following network connection fault codes logically OR'd : NET_DBG_SF_CONN Some network connection management fault(s). NET_DBG_SF_CONN_TYPE NET_DBG_SF_CONN_FAMILY NET_DBG_SF_CONN_ID NET_DBG_SF_CONN_ID_NONE NET_DBG_SF_CONN_ID_UNUSED NET_DBG_SF_CONN_LINK_TYPE NET_DBG_SF_CONN_LINK_UNUSED NET_DBG_SF_CONN_LINK_BACK_TO_CONN Network connection invalid type. Network connection invalid family. Network connection invalid ID. Network connection with NO connection IDs. Network connection linked to unused connection. Network connection invalid link type. Network connection link unused. Network connection invalid link back to same connection. Network connection invalid link NOT back to same connection. Network connection NOT in appropriate connection list. NET_DBG_SF_CONN_LINK_NOT_TO_CONN NET_DBG_SF_CONN_LINK_NOT_IN_LIST Network connection invalid pool type. Network connection invalid pool ID. Network connection pool contains duplicate connection(s). Network connection pool number of connections greater than maximum number of connections. NET_DBG_SF_CONN_POOL_TYPE NET_DBG_SF_CONN_POOL_ID NET_DBG_SF_CONN_POOL_DUP NET_DBG_SF_CONN_POOL_NBR_MAX NET_DBG_SF_CONN_LIST_IX_NBR_MAX NET_DBG_SF_CONN_LIST_NBR_NOT_SOLITARY NET_DBG_SF_CONN_USED_IN_POOL NET_DBG_SF_CONN_USED_NOT_IN_LIST NET_DBG_SF_CONN_UNUSED_IN_LIST NET_DBG_SF_CONN_UNUSED_NOT_IN_POOL NET_DBG_SF_CONN_IN_LIST_IN_POOL NET_DBG_SF_CONN_NOT_IN_LIST_NOT_IN_POOL 141 Network connection invalid list index number. Network connection lists number of connections NOT equal to solitary connection. Network connection used but in pool. Network connection used but NOT in list. Network connection unused but in list. Network connection unused but NOT in pool. Network connection in list & in pool. Network connection NOT in list & NOT in pool. You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN net_status; net_fault_conn; net_status = NetDbg_ChkStatusConns(); net_fault_conn = DEF_BIT_IS_SET(net_status, NET_DBG_SF_CONN); 142 10.02.07 Check TCP Layer Status, NetDbg_ChkStatusTCP() This function returns the current run-time status of µC/TCP-IP's TCP layer. This function is enabled by configuring NET_DBG_CFG_DBG_STATUS_EN to DEF_ENABLED and when the TCP layer itself is enabled. The prototype for this function is: NET_DBG_STATUS NetDbg_ChkStatusTCP (void) The function returns NET_DBG_STATUS_OK if the TCP layer is OK; i.e. no TCP layer faults currently exist. Otherwise, the function returns the following TCP layer fault codes logically OR'd : NET_DBG_SF_TCP Some TCP layer fault(s). NET_DBG_SF_TCP_CONN_TYPE NET_DBG_SF_TCP_CONN_ID NET_DBG_SF_TCP_CONN_LINK_TYPE NET_DBG_SF_TCP_CONN_LINK_UNUSED TCP connection invalid type. TCP connection invalid ID. TCP connection invalid link type. TCP connection link unused. NET_DBG_SF_TCP_CONN_POOL_TYPE NET_DBG_SF_TCP_CONN_POOL_ID NET_DBG_SF_TCP_CONN_POOL_DUP NET_DBG_SF_TCP_CONN_POOL_NBR_MAX TCP connection invalid pool type. TCP connection invalid pool ID. TCP connection pool contains duplicate connection(s). TCP connection pool number of connections greater than maximum number of connections. NET_DBG_SF_TCP_CONN_USED_IN_POOL NET_DBG_SF_TCP_CONN_UNUSED_NOT_IN_POOL NET_DBG_SF_TCP_CONN_Q NET_DBG_SF_TCP_CONN_Q_BUF_TYPE NET_DBG_SF_TCP_CONN_Q_BUF_UNUSED NET_DBG_SF_TCP_CONN_Q_LINK_TYPE NET_DBG_SF_TCP_CONN_Q_LINK_UNUSED NET_DBG_SF_TCP_CONN_Q_BUF_DUP TCP connection used in pool. TCP connection unused NOT in pool. Some TCP connection queue fault(s). TCP connection queue buffer invalid type. TCP connection queue buffer unused. TCP connection queue buffer invalid link type. TCP connection queue buffer link unused. TCP connection queue contains duplicate buffer(s). You could use this function as follows: NET_DBG_STATUS CPU_BOOLEAN net_status; net_fault_tcp; net_status = NetDbg_ChkStatusTCP(); net_fault_tcp = DEF_BIT_IS_SET(net_status, NET_DBG_SF_TCP); 143 10.03 Network Debug Monitor Task The Network Debug Monitor Task periodically checks the current run-time status of certain µC/TCP-IP conditions & saves that status to global variables which may be queried by other network modules. Currently, the Network Debug Monitor Task is only enabled when ICMP Transmit Source Quenches are enabled (see section 9.10.01) because this is the only network functionality that requires a periodic update of certain network status conditions. Applications do not need the Debug Monitor Task functionality since applications have access to the same debug status functions that the Monitor Task calls. 144 Appendix A µC/TCP-IP Licensing Policy You can evaluate the µC/TCP-IP source code for FREE for 45 days, but a license is required when µC/TCP-IP is used commercially. The policy is as follows: µC/TCP-IP source and object code can be used by accredited Colleges and Universities without requiring a license, as long as there is no commercial application involved. In other words, no licensing is required if µC/TCP-IP is used for educational use. You need to obtain an 'Executable Distribution License' to embed µC/TCP-IP in a product that is sold with the intent to make a profit or if the product is not used for education or 'peaceful' research. For licensing details, contact us at: Micrium 949 Crestview Circle Weston, FL 33327-1848 U.S.A. Phone FAX : +1 954 217 2036 : +1 954 217 2037 WEB Email : www.micrium.com : licensing@micrium.com 145
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.4 Linearized : Yes XMP Toolkit : 3.1-701 Producer : Acrobat Distiller 7.0.5 (Windows) Creator Tool : Acrobat PDFMaker 7.0.7 for Word Modify Date : 2007:10:28 02:10:01-04:00 Create Date : 2007:10:28 02:09:50-04:00 Metadata Date : 2007:10:28 02:10:01-04:00 Format : application/pdf Title : Chapter 4 Creator : Jean J. Labrosse Document ID : uuid:afb4b83d-7712-449c-9741-84c6deeb45ae Instance ID : uuid:6a6d6645-7abb-421d-bd1c-0af368e3bcc0 Company : Micrium, Inc. Page Count : 145 Page Layout : OneColumn Author : Jean J. LabrosseEXIF Metadata provided by EXIF.tools