- •Preface
- •About this book
- •Intended audience
- •Using this book
- •Typographical conventions
- •Further reading
- •Feedback
- •Feedback on ARM TCP/IP
- •Feedback on this book
- •Introduction
- •1.1 A typical embedded networking stack
- •1.2 What is PPP?
- •1.3 ARM TCP/IP requirements
- •1.3.1 Memory requirements
- •1.3.2 CPU requirements
- •1.3.3 Operating system requirements
- •1.4 ARM PPP requirements
- •1.4.1 Line management functions
- •1.4.2 Static memory
- •1.4.3 Dynamic memory
- •1.4.4 Periodic clock tick
- •1.5 Example package directories
- •1.6 Sample programs
- •TCP/IP Porting
- •2.1 Porting procedure
- •2.2 Portable and nonportable files
- •2.2.1 Portable files
- •2.2.2 Nonportable files
- •2.3 Creating the IP port file
- •2.3.1 Standard macros and definitions
- •2.3.2 CPU architecture
- •2.3.4 Debugging aids
- •2.3.5 Timers and multitasking
- •2.3.6 Stack features and options
- •2.4 Coding the glue layer
- •2.4.1 Task control
- •2.5 Specifying IP addresses
- •2.5.1 Porting programmer IP issues
- •2.5.2 End user IP issues
- •2.6 Testing the TCP/IP port
- •PPP Porting
- •3.1 Porting procedure
- •3.2 Porting PPP
- •3.2.1 Source files
- •3.2.2 Compiling PPP
- •3.2.3 Entry points and support calls
- •3.3 Testing PPP
- •3.3.1 Loopback
- •3.3.2 Client connection
- •3.3.3 Server connection
- •3.3.4 Abrupt disconnect
- •3.3.5 Multilink test
- •TCP/IP API Functions
- •4.2.1 cksum()
- •4.2.2 dprintf() and initmsg()
- •4.2.3 dtrap()
- •4.2.4 ENTER_CRIT_SECTION() and EXIT_CRIT_SECTION()
- •4.2.5 LOCK_NET_RESOURCE() and UNLOCK_NET_RESOURCE()
- •4.2.6 npalloc()
- •4.2.7 npfree()
- •4.2.8 panic()
- •4.2.9 prep_ifaces()
- •4.2.10 tcp_sleep()
- •4.2.11 tcp_wakeup()
- •4.3 Network interfaces
- •4.3.1 The NET structure
- •4.3.2 n_close()
- •4.3.3 n_init()
- •4.3.4 n_reg_type()
- •4.3.5 n_stats()
- •4.3.6 pkt_send()
- •4.3.7 raw_send()
- •PPP API Functions
- •5.2.1 _ALLOC() functions
- •5.2.2 ConPrintf()
- •5.2.3 _FREE() functions
- •5.2.4 get_secret()
- •5.2.5 ppp_port_init()
- •5.3 Serial line drivers
- •5.3.1 ln_connect()
- •5.3.2 ln_getc()
- •5.3.3 ln_hangup()
- •5.3.4 ln_putc()
- •5.3.5 ln_speed()
- •5.3.6 ln_state()
- •5.3.7 ln_write()
- •5.4 PPP entry points
- •5.4.1 lcp_lowerdown()
- •5.4.2 lcp_lowerup()
- •5.4.3 ppp_input()
- •5.4.4 ppp_timeisup()
- •5.4.5 prep_ppp()
- •Modem Functions
- •6.1 dialer.c
- •6.1.1 dial()
- •6.1.2 dial_check()
- •6.1.3 dialer_status()
- •6.1.4 modem_cmd()
- •6.1.5 modem_connect()
- •6.1.6 modem_getc()
- •6.1.7 modem_gets()
- •6.1.8 modem_hangup()
- •6.1.9 modem_init()
- •6.1.10 modem_lstate()
- •6.1.11 modem_putc()
- •6.1.12 modem_reset()
- •6.1.13 modem_speed()
- •6.1.14 modem_state()
- •6.1.15 modem_write()
- •6.2 login.c
- •6.2.1 do_script()
- •6.2.2 login()
- •6.2.3 log_input()
- •6.2.4 log_output()
- •6.2.5 logserver()
- •6.3 mdmport.c
- •6.3.1 dial_delay()
- •6.3.2 hangup()
- •6.3.3 modem_clr_dtr() and modem_set_dtr()
- •6.3.4 modem_DCD()
- •6.3.5 modem_portstat()
- •DHCP Client Functions
- •7.1 DHCP client functions
- •7.1.1 dhc_init()
- •7.1.2 dhc_discover()
- •7.1.3 dhc_set_callback()
- •7.1.4 dhc_halt()
- •7.1.5 dhc_second()
- •Low-overhead UDP Functions
- •8.1 UDP functions
- •8.1.1 udp_alloc()
- •8.1.2 udp_close()
- •8.1.3 udp_open()
- •8.1.4 udp_send()
- •8.1.5 udp_socket()
- •Sockets
- •9.1 ARM implementation of sockets
- •9.2 Socket API reference
- •9.2.1 t_accept()
- •9.2.2 t_bind()
- •9.2.3 t_connect()
- •9.2.4 t_errno()
- •9.2.5 t_getpeername()
- •9.2.6 t_getsockname()
- •9.2.7 t_getsockopt()
- •9.2.8 t_listen()
- •9.2.9 t_recv() and t_recvfrom()
- •9.2.10 t_select()
- •9.2.11 t_send() and t_sendto()
- •9.2.12 t_setsockopt()
- •9.2.13 t_shutdown()
- •9.2.14 t_socket()
- •9.2.15 t_socketclose()
- •ARM-specific Functions
- •10.1 ARM directories
- •10.1.1 armthumb
- •10.2 cksum.s
- •10.3 clock.c
- •10.3.1 clock_init()
- •10.3.2 clock_c()
- •10.4 delay.s
- •10.5 dtrap.s
- •10.6 except.s
- •10.7.1 ENTER_CRIT_SECTION() and EXIT_CRIT_SECTION()
- •10.7.2 irqDispatch()
- •10.7.3 irq_Enable() and irq_Disable()
- •10.7.4 irqInit()
- •10.8 lswap.s
- •10.10 olicom.c
- •10.11 pcmcia.c
- •10.12 stack.s
- •10.13 uart.c description
- •10.14 uart.c ring buffer management functions
- •10.14.1 ring_add()
- •10.14.2 ring_avail()
- •10.14.3 ring_new()
- •10.14.4 ring_remove()
- •10.14.5 ring_space()
- •10.15 uart.c interface functions
- •10.15.1 uart_getc()
- •10.15.2 uart_DCD()
- •10.15.3 uart_delay()
- •10.15.4 uart_do_irq()
- •10.15.5 uart_init()
- •10.15.6 uart_irq()
- •10.15.7 uart_putc()
- •10.15.8 uart_ready()
- •10.15.9 uart_reset()
- •10.15.10 uart_setup()
- •10.15.11 uart_stats()
- •10.16 uart.c debug TTY interface functions
- •10.16.1 dputchar()
- •10.16.2 getch()
- •10.16.3 kbhit()
- •Miscellaneous Library Functions
- •11.1 app_ping.c
- •11.2 in_utils.c
- •11.2.1 con_page()
- •11.2.2 hexdump()
- •11.2.3 nextarg()
- •11.2.4 ns_printf()
- •11.2.5 panic()
- •11.2.6 print_eth()
- •11.2.7 print_ipad()
- •11.2.8 print_uptime()
- •11.2.11 sysuptime()
- •11.2.12 uslash()
- •11.3 memman.c
- •11.4 menus.c, menulib.c, and nrmenus.c
- •11.5 nextcarg.c
- •11.5.1 nextcarg()
- •11.6 nvfsio.c
- •11.6.1 Overview
- •11.6.2 nv_fclose()
- •11.6.3 nv_fgets()
- •11.6.4 nv_fopen()
- •11.6.5 nv_fprintf()
- •11.6.6 nv_fwrite()
- •11.6.7 nv_initialize()
- •11.6.8 nv_writeflash()
- •11.7 nvparms.c
- •11.8 parseip.c
- •11.8.1 parseip()
- •11.9 reshost.c
- •11.9.1 in_reshost()
- •11.10 strilib.c
- •11.11 strlib.c
- •11.12 tcp_echo.c
- •11.13 ttyio.c
- •11.14 udp_echo.c
- •11.15 userpass.c
- •11.15.1 add_user()
- •11.15.2 check_permit()
- •Example Applications
- •12.1 Overview of the examples
- •12.1.1 Requirements
- •12.1.2 Building projects
- •12.1.3 Running the examples
- •12.2 Example descriptions
- •12.2.1 chargen
- •12.2.2 loopback
- •12.2.3 maildemo
- •12.2.4 menus
- •Error Codes
- •A.1 ENP_ error codes
- •A.2 Socket error codes
TCP/IP API Functions
4.3.5n_stats()
This is an optional function that can be used to display per-net statistics. It could also be used to log such statistics or return a pointer to a status block, depending on your requirements.
Syntax
void *n_stats(int if_number)
where:
if_number is an index into the nets[ ] array of the interface for which statistics are to be dumped.
Return value
Optional.
Usage
This function is only used for debugging purposes. If you need extra debugging information from the device driver, you can arrange for this function to return a pointer to a status block.
ARM DUI 0079B |
Copyright © 1998 and 1999 ARM Limited. All rights reserved. |
4-23 |
TCP/IP API Functions
4.3.6pkt_send()
This function sends the data in the passed PACKET structure and queues the PACKET structure for later release. If the MAC hardware is idle, the actual transmission of the packet should be started by this function, otherwise it should be scheduled to be sent later, usually by an End Of Transmission (EOT) interrupt from the hardware.
MAC headers for media, such as Ethernet or Token Ring, are placed at the head of the buffer passed by the calling function. Some drivers may have to access, strip, or modify the MAC header if they are layered on top of complex lower layers.
Syntax
tStatus pkt_send(PACKET pkt)
where:
pkt |
is the PACKET structure containing the frame to send. |
Return value
Returns one of the following:
0 |
if successful. |
ENP_code if not successful (see ENP_ error codes on page A-2).
Usage
The PACKET structure is defined in the file \inet\netbuf.h. All the information needed to send the packet is filled in before this call is made. The important fields are:
pkt->nb_prot pointer to data to send.
pkt->nb_plen length of data to send.
pkt->net |
nets[ ] structure for posting statistics. |
The hardware driver should send nb_plen bytes, starting at nb_prot. When all the bytes are sent, the PACKET structure should be returned to the free queue by a call to pk_free(), which can be called at interrupt time. Do not free the packet before it has been successfully sent by the hardware, because it can then be reused (and its buffer altered) by the IP stack.
The simplest way to implement this function is to block (busy-wait) until the data is sent. This allows fast prototyping of new drivers, but generally affects performance. The usual design is to:
4-24 |
Copyright © 1998 and 1999 ARM Limited. All rights reserved. |
ARM DUI 0079B |
TCP/IP API Functions
1.Put the packet in an awaiting_send queue.
2.Check to see if the hardware is idle.
3.Call a send_next_from_q() function to dequeue the packet at the head of the send queue.
4.Begin sending the packet.
The EOT interrupt frees the packet that has just been sent and calls the send_next_from_q() function again. Moving all the PACKETS through the awaiting_send queue ensures that they are sent in FIFO order. This significantly improves TCP and application performance.
If your hardware (or a lower layer driver) does not have an EOT interrupt or any analogous mechanism, you may need to use the raw_send() alternative to this function.
Slow devices, such as serial links and hardware that DMAs data directly out of predefined memory areas, can copy the passed buffer into driver-managed memory buffers, free the PACKET, and return immediately. However, these devices should be prepared to be called with more packets before transmission is complete.
Interface transmit functions should also maintain system statistics about packet transmissions. These are kept in the n_mib structure attached to each nets[ ] entry. Exact definitions of all these counters are available in RFC 1213. At a minimum, you should maintain packet byte and error counts, because these can help you debug your product during development and isolate configuration problems in the field. It is recommended that you perform statistics keeping at EOT time, but statistics can be approximated in this call. Example 4-3 on page 4-26 shows a generic example.
ARM DUI 0079B |
Copyright © 1998 and 1999 ARM Limited. All rights reserved. |
4-25 |
TCP/IP API Functions
Example 4-3
/* compile statistics about completed transmit */
eth = (struct ethhdr *)pkt->nb_prot; |
/* get ether header */ |
ifc = pkt->net; |
|
if(send_status==SUCCESSFUL) |
/* send_status set by hardware EOT */ |
{ |
|
if(eth->e_dst[0] & 0x01) |
/* see if multicast bit is on */ |
ifc->n_mib->ifOutNUcastPkts++; |
|
else |
|
ifc->n_mib->ifOutUcastPkts++; |
|
ifc->n_mib->ifOutOctets +=pkt->nb_plen;
}
else /* error sending packet */
{
ifc->n_mib->ifOutErrors++;
}
Because this function may not wait for the packet transmission to complete, depending on your implementation, you can return a 0 if the packet has been successfully queued for send, or the send is in progress. Error (nonzero) codes should only be returned if a distinct hardware failure is detected. There is no mechanism to report errors detected in previous packets or during the EOT interrupt.
4-26 |
Copyright © 1998 and 1999 ARM Limited. All rights reserved. |
ARM DUI 0079B |
