Last described how ENC28J60 wrote the first Hello World on STM32, this time based on the last modification of the driver, using UIP to achieve ARP package response, ICMP response (ping pass MCU)
UIPgitee download address: https://gitee.com/jinling_gitee/uip.git Github address: https://github.com/adamdunkels/uip
After downloading, the project path is as follows:
When using UIP, you need to modify something to work properly:
1. Modify the uip-conf.h file, which is some configuration files that UIP is open to users
2. Declare UIP_APPCALL, uip_log callback function
3. Implement tapdev. Tapdev_declared under H header file Init ENC28J60 initialization, tapdev_read: Read a package of data, tapdev_send Send a package of data functions
Mainly uses files under the UIP folder, and also uses uip-conf.h, tapdev under the unix folder. H.
Modify uip-conf.h
Make some changes to uip-conf.h to work properly:
1. Comment on webserver.h Introduce header file
Implement UIP_APPCALL, uip_log function
These two functions are callback functions of UIP, this time only to use UIP ping to pass MCU, so they are implemented as empty functions:
In main. Two functions are declared in c, corresponding to UIP_APPCALL and uip_log, and timer. Clock_called in C Time
.... //UIP_APPCALL void main_appcall(){ } //UIP_APPCALL void main_uiplog(char* msg) { } int clock_time(){ } .....
Go back to uip-conf.h and declare UIP_APPCALL and uip_log implementation function is main_appcall and main_uiplog:
#define UIP_APPCALL main_appcall #define uip_log main_uiplog
clock_time function, already in clock. Declaration in h, just not implemented, so there is no need to repeat declaration here
Uipopt. Declare uip_in H Tcp_ Appstate_ T appstate type
In uipopt.h 503 line position with commented out uip_tcp_appstate_t Declaration, open here:
Or go to uip.h Comment off using uip_tcp_appstate_t position:
Implement tapdev_init, tapdev_read, tapdev_send function
Create a new tapdev.c, as follows:
#include <tapdev.h> #include "enc28j60.h"//ENC28J60 Driver #include <uip.h> //Reference to external files uip.c Declared in uip_ethaddr extern struct uip_eth_addr uip_ethaddr; //network address unsigned char my_mac[6] = {0x29, 0x7C, 0x07, 0x37, 0x24, 0x63}; void tapdev_init(void) { enc28j60_init(my_mac); for (int i = 0; i < 6; i++) { uip_ethaddr.addr[i] = my_mac[i]; } } //Read a package of data unsigned int tapdev_read(void){ enc28j60_packet_receive(uip_buf, MAX_FRAMELEN); } //Send a package of data void tapdev_send(void) { enc28j60_packet_send(uip_buf, MAX_FRAMELEN); }
Put UIP related files together
Finally, the above mentioned unix/uip-conf.h, unix/tapdev.h into the UIP folder, set the header file path to the UIP folder through IDE(keil5)
keil5 adds to the red box shown below. c File
Modify each. c file, change "" to <>, for example:
main.c Implement arp response and icmp response
Before that, you need to ensure that the above files can be compiled and passed properly after you add them:
First at mainc. UIP_declaring UIP in C BUF:
#define UIP_BUF ((struct uip_eth_hdr *)&uip_buf[0])
Processing ICMP request operation:
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI1_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ //Wait some time before initialization for(int i = 0;i < 20;i++) { //enc28j60PhyWrite(PHLCON,0x7a4); HAL_Delay(500); print("begin init enc28j60..."); } tapdev_init();//Initialization enc28j60 print("init enc28j60 success!"); //Initialization UIP uip_init(); uip_ipaddr_t ipaddr; uip_ipaddr(ipaddr, 192, 168, 1, 8);//MCU IP address uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, 192, 168, 1, 1);//gateway,Computers and MCU Use when passing router uip_setdraddr(ipaddr); uip_ipaddr(ipaddr, 255, 255, 252, 0);//Subnet Mask uip_setnetmask(ipaddr); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ //Try to read a package of data uip_len = tapdev_read(); if(uip_len == 0){ //No data read continue; } //Is it ARP request if(UIP_BUF->type == htons(UIP_ETHTYPE_ARP)) { //Assembly ARP Respond to requests uip_arp_arpin(); if(uip_len>0){ //response ARP Request to send data tapdev_send(); } } //Is it IPV4 if(UIP_BUF->type == htons(UIP_ETHTYPE_IP)) { uip_arp_ipin(); //UIP Parse data uip_input(); if(uip_len > 0){ //Must be called, otherwise it will appear ping Incomplete, use the package capture tool to see that received packets checksum bad Checksum Failure uip_arp_out(); tapdev_send(); } } /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
After the MCU is linked on the computer side, you need to turn on the network device and set it to use the following IP: