//======================================================================
//TITLE:
// STM32F2xx's tcp_echoserver routine explanation
//AUTHOR:
// norains
//DATE:
// Monday 04-July-2011
//Environment:
// Keil MDK 4.2
// STM32F207 core version
//==============================================================================
I recently got the core version of STM32F207, which has a network card chip on board, so I naturally want to tinker with it. For a novice who has never been exposed to the Internet, the best way to get started is to speculate on the routines of ST company, so norains is no exception today. Then let's take a look at this official routine!
First, let's understand the workflow of the C/S network program, as shown in the figure:
This diagram is not drawn by norains, but is captured from a PPT called "TCP/IP Socket Network Programming" that is circulated on the Internet. You must be familiar with this process, because the example process described below is very consistent with the diagram.
ST's TCP routines are divided into client and server. According to the literal meaning, we can know that the tcp_echoserver routine uses STM32F2xx as a server. The first step of the routine is initialization, which calls the tcp_echoserver_init() function.
In the tcp_echoserver_init() function, the following things are done:
1. Create a new TCP protocol control block
2. Bind the address and port number (port)
3. Start listening (listen)
4. Set the accept callback function
The complete code is as follows:
void tcp_echoserver_init(void)
{
//Create a new TCP control block
tcp_echoserver_pcb = tcp_new();
if (tcp_echoserver_pcb != NULL)
{
err_t err;
//Bind to port 7
err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 7);
if (err == ERR_OK)
{
//Start monitoring
tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
//Set tcp_echoserver_accept as the callback function of accept
tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);
}
else
{
printf("Can not bind pcb\n"); //norains 2011-7-4 comment
}
}
else
{
printf("Can not create new pcb\n"); //norains 2011-7-4 comment
}
}
When the client starts to connect, the set tcp_echoserver_accept() callback function will be called. This function mainly creates a new data structure and passes it to the underlying TCP, and finally sets the three callback functions of receive, error and poll.
The code of tcp_echoserver_accept() is as follows:
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
err_t ret_err;
struct tcp_echoserver_struct *es;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
///Set priority for new connections
tcp_setprio(newpcb, TCP_PRIO_MIN);
//Allocate a structure space to maintain the TCP connection
es = (struct tcp_echoserver_struct *)mem_malloc(sizeof(struct tcp_echoserver_struct));
if (es != NULL)
{
es->state = ES_ACCEPTED;
es->pcb = newpcb;
es->p = NULL;
//Pass the newly allocated structure data to the new pcb
tcp_arg(newpcb, es);
//Set the receive callback function for the new connection
tcp_recv(newpcb, tcp_echoserver_recv);
//Set the error callback function for the new connection
tcp_err(newpcb, tcp_echoserver_error);
//Set the poll callback function for the new connection
tcp_poll(newpcb, tcp_echoserver_poll, 1);
ret_err = ERR_OK;
}
else
{
/* return memory error */
ret_err = ERR_MEM;
}
return ret_err;
}
Next is the callback function tcp_echoserver_recv(). Since this function is quite long, I will not list all the codes here. For users, it is enough to know what the corresponding judgment conditions mean, such as:
static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
struct tcp_echoserver_struct *es;
err_t ret_err;
LWIP_ASSERT("arg != NULL",arg != NULL);
es = (struct tcp_echoserver_struct *)arg;
if (p == NULL)
{
//If an empty frame is received, release the connection
...
}
else if(err != ERR_OK)
{
//A non-empty frame is received, but an error may occur for some reason, resulting in a return value other than ERR_OK, so the buffer is released here
...
}
else if(es->state == ES_ACCEPTED)
{
//Connection is successful, here you need to set the sent callback function
...
}
else if (es->state == ES_RECEIVED)
{
//Receive data from the client
...
}
else
{
//When the connection is closed, data is still received
...
}
return ret_err;
}
The code part of STM32F207 is temporarily discussed here. The question now is, how to test the correctness of this code? This requires the use of the echotool.exe program provided by ST. The program is located in the PC_Software folder of stm32f2x7_eth_lwip. The program must be opened in the command line, and its approximate parameters are as follows:
If our server ip address is 192.168.0.8, then you can enter the following command for testing:
echotool.exe 192.168.0.8 /p tcp /r 7 /n 15 /t 2 /d Testing LwIP TCP echo server
If the network is connected, the test will be successful and the following screen will be displayed, as shown in the figure:
Previous article:How to deal with STM32 entering HardFault_Handler
Next article:How to code the STM32 serial port to receive messages more stably
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
- CBG201209U201T Product Specifications
- Keil compiles ADuC7029 and reports an error
- Technical Article: Optimizing 48V Mild Hybrid Electric Vehicle Motor Drive Design
- DIY an STLink V2.1
- Playing with Zynq Serial 18——[ex01] Trying out the first project based on Zynq PL
- Hangshun chip-HK32F103 xCxDxE data sheet
- How to lay digital and analog floors?
- The entire process of R&D and production of a chip
- pyWatch with BLE functionality and micropython
- Use the microcontroller DAC to output analog voltage and control the output voltage of the DC-DC circuit so that Vout=2*Vset. Please help me design the circuit