Ping (Packet Internet Gopher) uses the "echo" function of the ICMP (Internet Control Message Protocol) protocol to test whether the host/server responds. ICMP provides communication between routers and hosts outside of normal situations. It is an integral part of IP. ICMP includes source station suppression messages that reduce the transmission rate, redirect messages that request the host to change the routing table, and echo request/reply messages that the host can use to determine whether the destination is reachable. ICMP messages are transmitted in the data area of the IP datagram. When the host/server receives an ICMP message with an echo type, it responds with an "echo reply" message. After the local machine receives and confirms the message, it can be considered that the host/server is active, so that the local machine and the remote host/server can be connected and can communicate with each other. I
have implemented a simple ping function based on the ping command under DOS and the current status of 51 single-chip microcomputer resources. Its usage is as follows:
(1) MCU-->PC Use "ping XXX.XXX.XXX.XXX
(2) PC-->MCU Follow the normal operation in DOS
Each ping command repeats the test 8 times, that is, 8 times of information is displayed.
Note that the displayed content is slightly different from that on the PC. This is because ping here works in a multi-task single-window environment. In order to distinguish the source of the response, it is necessary to add the source IP address information. In addition, due to 51 resource limitations, the time parameter (time is the time it takes for the local host to go back and forth with the other host) is cancelled. The specific simplified contents are as follows:
(1) Only the "ping+IP address" command format is supported, and the domain name method and other options are not available
(2) A fixed 32-byte test packet
(3) The round-trip time between the local host and the other host is not calculated, and the test time is 1 to 2 seconds
. In short, the simplified ping can complete the most basic connectivity test function.
0 8 16 31
------------------------------------------------
| Type (8 or 0) | Code (0) | Checksum |
------------------------------------------------
| Identifier | Sequence number |
------------------------------------------------
| Optional data |
------------------------------------------------
| . . . |
------------------------------------------------
Figure 1 ICMP echo request or reply message format
PingCycle
| Scheduled operation
V
PingCmd ---------------- --------------
-------->| PingRequest|----------->| |
Command | | Request | | |
| | |
| A | | B |
| | | |
<--------|PingEcho |<-----------|PingAnswer |
Echo ---------------- Answer --------------
Figure 2 A Ping B process (full-duplex operation, vice versa, the reverse process is not drawn)
Figure 1 shows the ICMP echo request/reply message format (i.e. Ping packet format). After the network card driver is implemented, the implementation of Ping is simplified to filling in the message (see the pseudo code list for details). As shown in Figure 2, I mainly use 4 functions to implement the complete ping process. Ping request (PingRequest), Ping reply (PingAnswer), echo after receiving the reply (PingEcho), and scheduled operation (PingCycle).
PingRequest completes the Ping request. When the Ping command is entered, this function is called to send a request packet.
PingAnswer completes the Ping response. It works in the background and automatically responds whenever it receives a request packet sent to its own IP.
PingEcho displays the response information. Whenever a response is received, the relevant information is immediately displayed.
PingCycle periodically operates the pingbuf record buffer. It scans once per second and changes the state according to the current situation and status.
- ----------------------------------------------------
| | Status (status) | Times (times) | Memory handle (memhandle) |
| ----------------------------------------------------
N | . . . |
| ----------------------------------------------------
| | Status (status) | Times (times) | Memory handle (memhandle) |
- ----------------------------------------------------
N=MaxLenPingBufFigure
3 pingbuf record buffer format
The IP address must be converted into a MAC address before it can be transmitted on the Ethernet. If there is no corresponding item in the ARP cache, it will take a long time to find it (network transmission time relative to CPU time). In order not to block the process, I designed a pingbuf record buffer, as shown in Figure 3. This table is queried once a second and changes its state according to the current situation. It includes three fields: state, number of times, and memory handle. The "number of times" field indicates the remaining number of tests. 0 means that the test is completed, and the state is changed to 0 to indicate that this record item is now idle. The "memory handle" field stores the first address pointer of the ICMP message buffer. The "state" field records the state number, which means as follows:
0---Idle
1---Sent but no response
2---Sent and responded
3---Waiting for ARP
4---First preparation to send (used to synchronize the 1-second clock)
The state transition diagram is shown in Figure 4.
Figure 4 is omitted. For details, see the pseudo code list PingCycle. Please draw the state diagram yourself.
This implementation also uses auxiliary programs such as ping command processing, IP address conversion, and checksum calculation. For details, see the pseudo code list. The IP protocol uses a unified CheckSum algorithm to calculate and verify the header checksum of the datagram. The header is regarded as a 16-bit integer sequence, and the checksum is defined as the binary complement of the sum of all 16-bit integers in the header. Similarly, the sum and complement are also defined to use the binary complement algorithm. All TCP/IP protocol checksum calculations and data packet verification are completed by the CheckSum subroutine. However, it should be noted that the TCP and UDP checksums require a pseudo header. The packets that require header checksum calculation and verification are: IP, ICMP, UDP, TCP. The only difference between them is that the sum data is different, and the algorithm uses CheckSum. See the source program listing for details. (Hint: The IP header consists of 20 bytes from the version number, header length, service type to the destination IP address (if it does not contain IP options); the ICMP checksum only covers the ICMP message. Comparing the similarities between the UDP, TCP pseudo header and the IP header, it is not necessary to allocate a separate pseudo header buffer, but to directly use the IP buffer to calculate the checksum. By observing the adjacent data of the IP header, direct calculation can be achieved by taking certain measures. That is, first clear the IP lifetime field to 0, assign the corresponding value to the protocol field, assign the checksum to the UDP/TCP packet length value, and add 12 to indicate the 3-word length of the pseudo header. After the calculation is completed, add the correct lifetime and checksum value to the IP packet header, as shown in Figure 5.)
0 8 16 31 0 8 16 31
---------------------------- ---------------------------
| Lifetime | Protocol | Header checksum | | Source IP address |
---------------------------- ---------------------------
| Source IP address | | Destination IP address |
---------------------------- ---------------------------
| Destination IP address | | Zero | Protocol | UDP/TCP length |
---------------------------- ---------------------------
| Data | | UDP/TCP packet data |
---------------------------- ---------------------------
IP packet format (partial) UDP, TCP pseudo header + data format
Figure 5 Comparison of IP packet format (partial) and UDP, TCP pseudo header format
Pseudocode listing:
PingRequest(IP address) //Ping request
{
//Apply for small memory
pICMP=OSMemGet();
//Fill in Ethernet frame
Destination MAC address=physical address obtained after parsing the IP address passed in by the ping command
Source MAC address=MAC address of this node
Type=0x0800 //IP packet
//Fill in IP frame
Version number & header length=0x45
Service type=0
Total length=60
Identifier=GlobalID++ //Global variable 16-bit GlobalID plus 1
flag & fragment offset=0x0000
Lifetime=0x80
Protocol=0x0001 //icmp
header checksum=0x0000
Source IP address=IP address
of this node Destination IP address=IP address passed in by the ping command
Header checksum=CheckSum(IP header and length) //Calculate the IP packet header checksum
//Fill in ICMP frame
Type=8 //8 Request 0
Response code = 0
checksum = 0x0
identifier = 0x0300
sequence number = GlobalID
checksum = CheckSum (ICMP header and length) //Calculate the ICMP packet header checksum
//Register the ICMP packet in PingBuf
for(i=0;i
PingBuf[i].times=0x8; //Test 8 times
PingBuf[i].ip=IP address passed in by ping command;
PingBuf[i].memhandle=memory handle;
PingBuf[i].status=4; //First preparation for sending (used to synchronize 1 second clock)
break;
}
}
if(i==MaxLenPingBuf) release memory;
}
PingAnswer(*input packet buffer first address pBUF) //Ping response
{
//Rewrite Ethernet frame
Destination MAC address = source MAC address
Source MAC address = local node MAC address
//Rewrite IP frame
Lifetime = life-1
Destination IP address = source IP address
Source IP address = local node IP address
Header checksum = 0x0000
Header checksum = CheckSum (IP header and length) //Calculate IP packet header checksum
//Rewrite ICMP frame
Type = 0 //8 request 0 response
Checksum = 0x0
Checksum = CheckSum (ICMP header and length) //Calculate ICMP packet header checksum
//Directly send ICMP packet to TxQFIFO buffer
OSQSend(QID,*pBUF);
}[page]
PingEcho(*input packet buffer first address pBUF) //Echo after receiving the response
{
//Print ping response, because the 51 timer is slow, the time parameter is omitted (time is the time taken for the local machine to go back and forth with the other host).
PrintStr(" \\tReply from IP=");
PrintStr(input packet source IP address);
PrintStr
(": bytes=32");
PrintStr(" TTL=");
PrintByte(input packet TTL);
PrintStr(" ");
//Process PingBuf recordsfor
(i=0;i
if(PingBuf[i].ip==pBUF.ipframe.ip){
PingBuf[i].status=2; //Sent and respondedbreak
;
}
}
}
}
PingCycle() //Timed operation, put in the 1 second loop task
{
for(;;){
taskDelay(1 second);
for(i=0;i
case 0: //Idle
break;
{
case 1: //Sent but no response
//Print timeout informationPrintStr
(" \\tRequest timed out.(");
PrintStr(PingBuf[i].ip);
PrintStr(") ");
case 2: //Sent and responded
//State transitionPingBuf
[i].times=PingBuf[i].times-1;
if(PingBuf[i].times==0)
PingBuf[i].status=0;
else{
case 4: //First preparation to send (used to synchronize the 1 second clock)
//Check the ARP cacheif
(ARP cache has a corresponding item){
//Directly send ICMP packet to TxQFIFO
bufferOSQSend(QID,*pBUF);
PingBuf[i].status=1; //Sent but no response
}
else PingBuf[i].status=3; //Wait for ARP
}
break;
}
case 3: //Wait for ARP
{
//Check ARP cache
if(ARP cache has corresponding item){
//Directly send ICMP packet to TxQFIFO buffer
OSQSend(QID,*pBUF);
}
PingBuf[i].status=1; //Sent but no response
}
default: //Other status, error
PingBuf[i].status=0;
}
}
}
void PingCommand(WORDTABLE *WordTable)//PING command processing
{
if(WordTable->Num==1)
PrintStr(" Please input IP address! ");
else{
if(IPadrToHEX(WordTable->wt[1].Str, &ping_ip_address)==0){
PrintStr(" IP address error! ");return;
}
else
PingRequest(ping_ip_address);
}
}
INT16U CheckSum(INT16U *buf,INT16U length) //Checksum calculation
{
INT16U len;
INT32U sum;
len=length>>1;
for(sum=0;len>0;len--)
sum+=*buf++;
if (length&1)
sum+=(*buf&0xFF00);
sum=(sum>>16)+(sum&0xFFFF);
sum+=(sum>>16);
return(~sum);
}
union ip_address_type{ //IP address data structure
unsigned long dwords;
unsigned int words[2];
unsigned char bytes[4];
};
bit IPadrToHEX(unsigned char *Str,union ip_address_type *ip) //Convert IP string to IP address value
{
unsigned char i,j,ch,x;
ch=*Str++;
for(j=0;j<3;j++){
x=0;
for(i=0;i<4;i++){
if(ch==\'.\') {ch=*Str++;break;}
else if(i==3) return 0;
else if(ch<0&&ch>9) return 0;
else
x=10*x+(ch-\'0\');
ch=*Str++;
}
ip->bytes[ j]=x;
}
x=0;
for(i=0;i<4;i++){
if(ch==\'\\0\') {ch=*Str++;break;}
else if(i==3) return 0;
else if(ch<0&&ch>9) return 0;
else
x=10*x+(ch-\'0\');
ch=*Str++;
}
ip->bytes[3]=x;
return 1;
}
void HEXToIPadr(unsigned char *Str,union ip_address_type *ip) //Convert IP address value to IP string
{
unsigned char i;
unsigned char x,y;
for(i=0;i<4;i++){
x=ip->bytes[i];
if(x>99){
y=x/100;*Str++=y+\'0\';
x=x- 100*y;y=x/10;*Str++=y+\'0\';
x=x-10*y;*Str++=x+\'0\';
if(i==3) *Str++=\' \\0\';
else *Str++=\'.\';
}
else if(x>9){
y=x/10;*Str++=y+\'0\';
x=x-10*y;* Str++=x+\'0\';
if(i==3) *Str++=\'\\0\';
else *Str++=\'.\';
}
else{
*Str++=x+\'0\';
if(i==3) *Str++=\'\\0\';
else *Str++=\'.\';
}
}
}
References:
1. "Internetworking with TCP/IP" (3rd edition)
Previous article:51 MCU ARP protocol implementation principle
Next article:51 MCU general assembly delay subroutine
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- 【UFUN Learning】Chapter 4 Chip ID
- I have received the acceptance notice, but I don’t know when the court session will begin. What should I do?
- Please explain the principle of this boost circuit
- Find a book specifically about C++ move semantics
- Career Options
- ST BlueNRG-LP Evaluation Board DesignSpark Unboxing
- TI Engineer's Annual Review: Processors (Hot Products: MSP430, C2000, C6000 Multicore, etc.) Selected Q&A
- How to choose an analog-to-digital converter?
- [Project source code] FPGA-based asynchronous FIFO show-ahead mode
- [Construction Monitoring and Security System] XIV. Realization of the core functions of the project