前辈们,能否帮我简单解释一下一下代码, #include <stdio.h> #include <ctype.h> #include <string.h> #include "alt_lwip_dev.h" #include "alt_types.h" #include "sys/alt_flash.h" #include "includes.h" #include "io.h" #include "user.h" /* * The "adapter" storage here is declared so that when LWIP calls the * get_ip_addr() routine, the adapter struct will be populated with the * network device (Ethernet MAC) that LWIP is currently trying to setup an IP * address for. This is later used in the dhcp_timeout_task() routine to * determine if DHCP was successful for the particular adapter. */ struct netif* adapter; /* * MicroC/OS-II semaphores are used to signal when an IP address has been * aquired (declared in web_serer.c), and when the LCD may be opened for * write. */ extern OS_EVENT *attained_ip_address_sem; #ifdef LCD_DISPLAY_NAME OS_EVENT *lcd_sem; /* File handle for writing to LCD display. Defined in web_server.c */ extern FILE* lcdDevice; #endif /* LCD_DISPLAY_NAME */ /* * die_with_error() * * This routine is just called when a blocking error occurs with the example * design. It deletes the current task. */ void die_with_error(char err_msg[DIE_WITH_ERROR_BUFFER]) { printf("\n%s\n", err_msg); OSTaskDel(OS_PRIO_SELF);
while(1); } /* * generate_and_store_mac_addr() * * This routine is called when, upon program initialization, we discover * that there is no valid network settings (including MAC address) programmed * into flash memory. The user is prompted for their Nios development board's * serial number, and a unique MAC address within the Altera pool generated * based on that number. * * It should be noted that this number, while unique, will likely differ from * the also unique (but now lost forever) MAC address programmed into the * development board on the production line. * * As we are erasing the entire flash sector, we'll re-program it with not * only the MAC address, but static IP, subnet, gateway, and "Use DHCP" * sections. These fail-safe static settings are compatible with previous * Nios Ethernet designs, and allow the "factory-safe" design to behave * as expected if the last flash sector is erased. */ err_t generate_and_store_mac_addr() { err_t ret_code = ERR_IF; alt_u32 ser_num = 0; char serial_number[9], flash_content[32]; alt_flash_fd* flash_handle; int i = 0;
printf("Can't read the MAC address from your board (this probably means\n"); printf("that your flash was erased). We will assign you a MAC address and\n"); printf("static network settings\n\n");
while(!ser_num) { printf("Please enter your 9-digit serial number. This is printed on a \n"); printf("label under your Nios dev. board. The first 3 digits of the \n"); printf("label are ASJ and the serial number follows this.\n -->");
for(i=0; i<9; i++) { serial_number = getchar(); putchar(serial_number);
/* Handle backspaces. How civilized. */ if ((serial_number == 0x08) && (i >= 0)) { i--; } } printf("\n");
for(i=0; i<9; i++) { if (isdigit(serial_number)) { ser_num *= 10; ser_num += serial_number - '0'; } else { ser_num = 0; printf("Serial number only contains decimal digits and is non-zero\n"); break; } }
if (ser_num) { /* This says the image is safe */ flash_content[0] = 0xfe; flash_content[1] = 0x5a; flash_content[2] = 0x0; flash_content[3] = 0x0;
/* This is the Altera Vendor ID */ flash_content[4] = 0x0; flash_content[5] = 0x7; flash_content[6] = 0xed;
/* Reserverd Board identifier for erase boards */ flash_content[7] = 0xFF; flash_content[8] = (ser_num & 0xff00) >> 8; flash_content[9] = ser_num & 0xff; /* Then comes a 16-bit "flags" field (not used with LWIP) */ flash_content[10] = 0xFF; flash_content[11] = 0xFF;
/* Then comes the static IP address */ flash_content[12] = IPADDR0; flash_content[13] = IPADDR1; flash_content[14] = IPADDR2; flash_content[15] = IPADDR3;
/* Then comes the static nameserver address (not used with LWIP) */ flash_content[16] = 0xFF; flash_content[17] = 0xFF; flash_content[18] = 0xFF; flash_content[19] = 0xFF;
/* Then comes the static subnet mask */ flash_content[20] = MSKADDR0; flash_content[21] = MSKADDR1; flash_content[22] = MSKADDR2; flash_content[23] = MSKADDR3;
/* Then comes the static gateway address */ flash_content[24] = GWADDR0; flash_content[25] = GWADDR1; flash_content[26] = GWADDR2; flash_content[27] = GWADDR3;
/* And finally whether to use DHCP - set all bits to be safe */ flash_content[28] = 0xFF; flash_content[29] = 0xFF; flash_content[30] = 0xFF; flash_content[31] = 0xFF;
/* Write the MAC address to flash */ /* flash_handle = alt_flash_open_dev(EXT_FLASH_NAME); if (flash_handle) { alt_write_flash(flash_handle, LAST_SECTOR_OFFSET, flash_content, 32); alt_flash_close_dev(flash_handle); ret_code = ERR_OK; } */ } } return ret_code; } /* * get_mac_addr() * * Read the MAC address in a board specific way. This routine must be provided * by the LWIP user as each board will have its MAC address stored in a * different way. */ err_t get_mac_addr(alt_lwip_dev* lwip_dev) { err_t ret_code = ERR_OK; alt_u32 signature; struct netif* netif = lwip_dev->netif;
netif->hwaddr[0] = 0x00; netif->hwaddr[1] = 0x88; netif->hwaddr[2] = 0x88; netif->hwaddr[3] = 0x52; netif->hwaddr[4] = 0x3b; netif->hwaddr[5] = 0x95;
return ret_code; } /* * get_ip_addr() * * This routine is called by LWIP to obtain an IP address for the specified * network adapter. Like the MAC address, obtaining an IP address is very * system-dependant and therefore this function is exported for the developer * to control. * * In our system, we are either attempting DHCP auto-negotiation of IP address, * or we are setting our own static IP, Gateway, and Subnet Mask addresses our * self. This routine is where that happens. */ int get_ip_addr(alt_lwip_dev* lwip_dev, struct ip_addr* ipaddr, struct ip_addr* netmask, struct ip_addr* gw, int* use_dhcp) { int ret_code = 0; IP4_ADDR(ipaddr, IPADDR0,IPADDR1,IPADDR2,IPADDR3); IP4_ADDR(gw, GWADDR0,GWADDR1,GWADDR2,GWADDR3); IP4_ADDR(netmask, MSKADDR0,MSKADDR1,MSKADDR2,MSKADDR3); *use_dhcp = 0; printf("Static IP Address is %d.%d.%d.%d\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr)); ret_code = 1;
return ret_code; } /* * dhcp_timeout_task() * * This LWIP-called routine is responsible for checking to see whether DHCP * was sucessful. Here we check to see whether a timeout (120 seconds in this * case) has elapsed. If so, display an error, assign a static address, and * bail out. If not, continue checking for DHCP success and bail out once * a DHCP address assignment is complete. * * This routine also displays the assigned IP address to the user (via STDOUT * and, if equipped, LCD screen. * * Note: LCD_DISPLAY_NAME is defined in user.h to be the LCD interface for * the "standard" example design. */ #if LWIP_DHCP == 1 void dhcp_timeout_task() { int have_address = 0, timeout_dhcp = 0; struct ip_addr ipaddr, netmask, gw; INT8U return_code = OS_NO_ERR;
#ifdef LCD_DISPLAY_NAME lcd_sem = OSSemCreate(1); #endif /* LCD_DISPLAY_NAME */ OSSemPend(attained_ip_address_sem, 0, &return_code);
#ifdef LCD_DISPLAY_NAME OSSemPend(lcd_sem, 0, &return_code); #endif /* LCD_DISPLAY_NAME */
#ifdef LCD_DISPLAY_NAME lcdDevice = fopen(LCD_DISPLAY_NAME, "w"); #endif /* LCD_DISPLAY_NAME */ while(1) { OSTimeDlyHMSM(0,0,0,100); /* * For demo purposes we need to use DHCP to allocate an IP Address * and LWIP had no mechanism to tell us one is allocated. Wait two * minutes if we don't have one we use a static IP address */ if((timeout_dhcp < DHCP_TIMEOUT) && (have_address == 0)) { timeout_dhcp++; if (!ip_addr_isany(&adapter->ip_addr)) { have_address = 1; printf("Assigned IP Address is %d.%d.%d.%d\n\n", ip4_addr1(&adapter->ip_addr), ip4_addr2(&adapter->ip_addr), ip4_addr3(&adapter->ip_addr), ip4_addr4(&adapter->ip_addr)); #ifdef LCD_DISPLAY_NAME /* Clear screen */ fprintf(lcdDevice, "\x1b"); fprintf(lcdDevice, "[2J"); fprintf(lcdDevice, "DHCP IP Addr is \n %d.%d.%d.%d", ip4_addr1(&adapter->ip_addr), ip4_addr2(&adapter->ip_addr), ip4_addr3(&adapter->ip_addr), ip4_addr4(&adapter->ip_addr)); #endif /* LCD_DISPLAY_NAME */ } } /* * You're in a bit of trouble if this happens, you could assign a static * IP address but how do we choose it? */ if (timeout_dhcp == DHCP_TIMEOUT) { dhcp_stop(adapter); IP4_ADDR(&ipaddr, IPADDR0,IPADDR1,IPADDR2,IPADDR3); IP4_ADDR(&gw, GWADDR0,GWADDR1,GWADDR2,GWADDR3); IP4_ADDR(&netmask, MSKADDR0,MSKADDR1,MSKADDR2,MSKADDR3);
netif_set_addr( adapter,&ipaddr, &netmask, &gw); netif_set_up(adapter);
printf("DHCP Failed to assign an IP Address\n\n"); printf("\nUsing static address: %d.%d.%d.%d\n\n\n", ip4_addr1(&adapter->ip_addr), ip4_addr2(&adapter->ip_addr), ip4_addr3(&adapter->ip_addr), ip4_addr4(&adapter->ip_addr)); #ifdef LCD_DISPLAY_NAME /* Clear the LCD screen */ fprintf(lcdDevice, "\x1b"); fprintf(lcdDevice, "[2J"); fprintf(lcdDevice, "DHCP Failed using\n %d.%d.%d.%d", ip4_addr1(&adapter->ip_addr), ip4_addr2(&adapter->ip_addr), ip4_addr3(&adapter->ip_addr), ip4_addr4(&adapter->ip_addr)); #endif /* LCD_DISPLAY_NAME */ have_address = 1; }
if (have_address == 1) { /* * We have an IP address this task has served it's purpose - kill it. */ #ifdef LCD_DISPLAY_NAME fclose(lcdDevice); #endif /* LCD_DISPLAY_NAME */ OSSemPost(attained_ip_address_sem); #ifdef LCD_DISPLAY_NAME OSSemPost(lcd_sem); #endif /* LCD_DISPLAY_NAME */ OSTaskDel(OS_PRIO_SELF); } } } #endif /* LWIP_DHCP */ |