Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.c
00001 /** 00002 * @file main.c 00003 * @brief Main routine 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software Foundation, 00021 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00022 * 00023 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00024 * @version 1.7.6 00025 **/ 00026 00027 //Dependencies 00028 #include <stdlib.h> 00029 #include "stm32f7xx.h" 00030 #include "stm32f7xx_hal.h" 00031 #include "stm32f7xx_nucleo_144.h" 00032 #include "os_port.h" 00033 #include "core/net.h" 00034 #include "drivers/stm32f7xx_eth.h" 00035 #include "drivers/lan8742.h" 00036 #include "dhcp/dhcp_client.h" 00037 #include "ipv6/slaac.h" 00038 #include "http/http_server.h" 00039 #include "http/mime.h" 00040 #include "path.h" 00041 #include "date_time.h" 00042 #include "resource_manager.h" 00043 #include "debug.h" 00044 00045 //Application configuration 00046 #define APP_MAC_ADDR "00-AB-CD-EF-07-46" 00047 00048 #define APP_USE_DHCP ENABLED 00049 #define APP_IPV4_HOST_ADDR "192.168.0.20" 00050 #define APP_IPV4_SUBNET_MASK "255.255.255.0" 00051 #define APP_IPV4_DEFAULT_GATEWAY "192.168.0.254" 00052 #define APP_IPV4_PRIMARY_DNS "8.8.8.8" 00053 #define APP_IPV4_SECONDARY_DNS "8.8.4.4" 00054 00055 #define APP_USE_SLAAC ENABLED 00056 #define APP_IPV6_LINK_LOCAL_ADDR "fe80::746" 00057 #define APP_IPV6_PREFIX "2001:db8::" 00058 #define APP_IPV6_PREFIX_LENGTH 64 00059 #define APP_IPV6_GLOBAL_ADDR "2001:db8::746" 00060 #define APP_IPV6_ROUTER "fe80::1" 00061 #define APP_IPV6_PRIMARY_DNS "2001:4860:4860::8888" 00062 #define APP_IPV6_SECONDARY_DNS "2001:4860:4860::8844" 00063 00064 #define APP_HTTP_MAX_CONNECTIONS 8 00065 00066 //Global variables 00067 DhcpClientSettings dhcpClientSettings; 00068 DhcpClientContext dhcpClientContext; 00069 SlaacSettings slaacSettings; 00070 SlaacContext slaacContext; 00071 HttpServerSettings httpServerSettings; 00072 HttpServerContext httpServerContext; 00073 HttpConnection httpConnections[APP_HTTP_MAX_CONNECTIONS]; 00074 00075 //Forward declaration of functions 00076 error_t httpServerCgiCallback(HttpConnection *connection, 00077 const char_t *param); 00078 00079 error_t httpServerUriNotFoundCallback(HttpConnection *connection, 00080 const char_t *uri); 00081 00082 00083 /** 00084 * @brief System clock configuration 00085 **/ 00086 00087 void SystemClock_Config(void) 00088 { 00089 RCC_OscInitTypeDef RCC_OscInitStruct; 00090 RCC_ClkInitTypeDef RCC_ClkInitStruct; 00091 00092 //Enable Power Control clock 00093 __HAL_RCC_PWR_CLK_ENABLE(); 00094 00095 //Enable HSE Oscillator and activate PLL with HSE as source 00096 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 00097 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; 00098 RCC_OscInitStruct.HSIState = RCC_HSI_OFF; 00099 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 00100 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 00101 RCC_OscInitStruct.PLL.PLLM = 8; 00102 RCC_OscInitStruct.PLL.PLLN = 432; 00103 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 00104 RCC_OscInitStruct.PLL.PLLQ = 9; 00105 HAL_RCC_OscConfig(&RCC_OscInitStruct); 00106 00107 //Enable overdrive mode 00108 HAL_PWREx_EnableOverDrive(); 00109 00110 //Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 00111 //clocks dividers 00112 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; 00113 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 00114 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 00115 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 00116 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 00117 HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); 00118 } 00119 00120 00121 /** 00122 * @brief MPU configuration 00123 **/ 00124 00125 void MPU_Config(void) 00126 { 00127 MPU_Region_InitTypeDef MPU_InitStruct; 00128 00129 //Disable MPU 00130 HAL_MPU_Disable(); 00131 00132 //SRAM 00133 MPU_InitStruct.Enable = MPU_REGION_ENABLE; 00134 MPU_InitStruct.Number = MPU_REGION_NUMBER0; 00135 MPU_InitStruct.BaseAddress = 0x20000000; 00136 MPU_InitStruct.Size = MPU_REGION_SIZE_512KB; 00137 MPU_InitStruct.SubRegionDisable = 0; 00138 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; 00139 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; 00140 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; 00141 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; 00142 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; 00143 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; 00144 HAL_MPU_ConfigRegion(&MPU_InitStruct); 00145 00146 //SRAM2 00147 MPU_InitStruct.Enable = MPU_REGION_ENABLE; 00148 MPU_InitStruct.Number = MPU_REGION_NUMBER1; 00149 MPU_InitStruct.BaseAddress = 0x2004C000; 00150 MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; 00151 MPU_InitStruct.SubRegionDisable = 0; 00152 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; 00153 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; 00154 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; 00155 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; 00156 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; 00157 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; 00158 HAL_MPU_ConfigRegion(&MPU_InitStruct); 00159 00160 //Enable MPU 00161 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); 00162 } 00163 00164 00165 /** 00166 * @brief LED blinking task 00167 **/ 00168 00169 void blinkTask(void *param) 00170 { 00171 //Endless loop 00172 while(1) 00173 { 00174 BSP_LED_On(LED1); 00175 osDelayTask(100); 00176 BSP_LED_Off(LED1); 00177 osDelayTask(900); 00178 } 00179 } 00180 00181 00182 /** 00183 * @brief Main entry point 00184 * @return Unused value 00185 **/ 00186 00187 int_t main(void) 00188 { 00189 error_t error; 00190 NetInterface *interface; 00191 OsTask *task; 00192 MacAddr macAddr; 00193 #if (APP_USE_DHCP == DISABLED) 00194 Ipv4Addr ipv4Addr; 00195 #endif 00196 #if (APP_USE_SLAAC == DISABLED) 00197 Ipv6Addr ipv6Addr; 00198 #endif 00199 00200 //MPU configuration 00201 MPU_Config(); 00202 //HAL library initialization 00203 HAL_Init(); 00204 //Configure the system clock 00205 SystemClock_Config(); 00206 00207 //Enable I-cache and D-cache 00208 SCB_EnableICache(); 00209 SCB_EnableDCache(); 00210 00211 //Initialize kernel 00212 osInitKernel(); 00213 //Configure debug UART 00214 debugInit(115200); 00215 00216 //Start-up message 00217 TRACE_INFO("\r\n"); 00218 TRACE_INFO("**********************************\r\n"); 00219 TRACE_INFO("*** CycloneTCP Web Server Demo ***\r\n"); 00220 TRACE_INFO("**********************************\r\n"); 00221 TRACE_INFO("Copyright: 2010-2017 Oryx Embedded SARL\r\n"); 00222 TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__); 00223 TRACE_INFO("Target: STM32F746\r\n"); 00224 TRACE_INFO("\r\n"); 00225 00226 //LED configuration 00227 BSP_LED_Init(LED1); 00228 BSP_LED_Init(LED2); 00229 BSP_LED_Init(LED3); 00230 00231 //Clear LEDs 00232 BSP_LED_Off(LED1); 00233 BSP_LED_Off(LED2); 00234 BSP_LED_Off(LED3); 00235 00236 //Initialize user button 00237 BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); 00238 00239 //TCP/IP stack initialization 00240 error = netInit(); 00241 //Any error to report? 00242 if(error) 00243 { 00244 //Debug message 00245 TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n"); 00246 } 00247 00248 //Configure the first Ethernet interface 00249 interface = &netInterface[0]; 00250 00251 //Set interface name 00252 netSetInterfaceName(interface, "eth0"); 00253 //Set host name 00254 netSetHostname(interface, "WebServerDemo"); 00255 //Select the relevant network adapter 00256 netSetDriver(interface, &stm32f7xxEthDriver); 00257 netSetPhyDriver(interface, &lan8742PhyDriver); 00258 //Set host MAC address 00259 macStringToAddr(APP_MAC_ADDR, &macAddr); 00260 netSetMacAddr(interface, &macAddr); 00261 00262 //Initialize network interface 00263 error = netConfigInterface(interface); 00264 //Any error to report? 00265 if(error) 00266 { 00267 //Debug message 00268 TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name); 00269 } 00270 00271 #if (IPV4_SUPPORT == ENABLED) 00272 #if (APP_USE_DHCP == ENABLED) 00273 //Get default settings 00274 dhcpClientGetDefaultSettings(&dhcpClientSettings); 00275 //Set the network interface to be configured by DHCP 00276 dhcpClientSettings.interface = interface; 00277 //Disable rapid commit option 00278 dhcpClientSettings.rapidCommit = FALSE; 00279 00280 //DHCP client initialization 00281 error = dhcpClientInit(&dhcpClientContext, &dhcpClientSettings); 00282 //Failed to initialize DHCP client? 00283 if(error) 00284 { 00285 //Debug message 00286 TRACE_ERROR("Failed to initialize DHCP client!\r\n"); 00287 } 00288 00289 //Start DHCP client 00290 error = dhcpClientStart(&dhcpClientContext); 00291 //Failed to start DHCP client? 00292 if(error) 00293 { 00294 //Debug message 00295 TRACE_ERROR("Failed to start DHCP client!\r\n"); 00296 } 00297 #else 00298 //Set IPv4 host address 00299 ipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr); 00300 ipv4SetHostAddr(interface, ipv4Addr); 00301 00302 //Set subnet mask 00303 ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr); 00304 ipv4SetSubnetMask(interface, ipv4Addr); 00305 00306 //Set default gateway 00307 ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr); 00308 ipv4SetDefaultGateway(interface, ipv4Addr); 00309 00310 //Set primary and secondary DNS servers 00311 ipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr); 00312 ipv4SetDnsServer(interface, 0, ipv4Addr); 00313 ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr); 00314 ipv4SetDnsServer(interface, 1, ipv4Addr); 00315 #endif 00316 #endif 00317 00318 #if (IPV6_SUPPORT == ENABLED) 00319 #if (APP_USE_SLAAC == ENABLED) 00320 //Get default settings 00321 slaacGetDefaultSettings(&slaacSettings); 00322 //Set the network interface to be configured 00323 slaacSettings.interface = interface; 00324 00325 //SLAAC initialization 00326 error = slaacInit(&slaacContext, &slaacSettings); 00327 //Failed to initialize SLAAC? 00328 if(error) 00329 { 00330 //Debug message 00331 TRACE_ERROR("Failed to initialize SLAAC!\r\n"); 00332 } 00333 00334 //Start IPv6 address autoconfiguration process 00335 error = slaacStart(&slaacContext); 00336 //Failed to start SLAAC process? 00337 if(error) 00338 { 00339 //Debug message 00340 TRACE_ERROR("Failed to start SLAAC!\r\n"); 00341 } 00342 #else 00343 //Set link-local address 00344 ipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr); 00345 ipv6SetLinkLocalAddr(interface, &ipv6Addr); 00346 00347 //Set IPv6 prefix 00348 ipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr); 00349 ipv6SetPrefix(interface, 0, &ipv6Addr, APP_IPV6_PREFIX_LENGTH); 00350 00351 //Set global address 00352 ipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr); 00353 ipv6SetGlobalAddr(interface, 0, &ipv6Addr); 00354 00355 //Set default router 00356 ipv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr); 00357 ipv6SetDefaultRouter(interface, 0, &ipv6Addr); 00358 00359 //Set primary and secondary DNS servers 00360 ipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr); 00361 ipv6SetDnsServer(interface, 0, &ipv6Addr); 00362 ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr); 00363 ipv6SetDnsServer(interface, 1, &ipv6Addr); 00364 #endif 00365 #endif 00366 00367 //Get default settings 00368 httpServerGetDefaultSettings(&httpServerSettings); 00369 //Bind HTTP server to the desired interface 00370 httpServerSettings.interface = &netInterface[0]; 00371 //Listen to port 80 00372 httpServerSettings.port = HTTP_PORT; 00373 //Client connections 00374 httpServerSettings.maxConnections = APP_HTTP_MAX_CONNECTIONS; 00375 httpServerSettings.connections = httpConnections; 00376 //Specify the server's root directory 00377 strcpy(httpServerSettings.rootDirectory, "/www/"); 00378 //Set default home page 00379 strcpy(httpServerSettings.defaultDocument, "index.shtm"); 00380 //Callback functions 00381 httpServerSettings.cgiCallback = httpServerCgiCallback; 00382 httpServerSettings.uriNotFoundCallback = httpServerUriNotFoundCallback; 00383 00384 //HTTP server initialization 00385 error = httpServerInit(&httpServerContext, &httpServerSettings); 00386 //Failed to initialize HTTP server? 00387 if(error) 00388 { 00389 //Debug message 00390 TRACE_ERROR("Failed to initialize HTTP server!\r\n"); 00391 } 00392 00393 //Start HTTP server 00394 error = httpServerStart(&httpServerContext); 00395 //Failed to start HTTP server? 00396 if(error) 00397 { 00398 //Debug message 00399 TRACE_ERROR("Failed to start HTTP server!\r\n"); 00400 } 00401 00402 //Create a task to blink the LED 00403 task = osCreateTask("Blink", blinkTask, NULL, 500, OS_TASK_PRIORITY_NORMAL); 00404 //Failed to create the task? 00405 if(task == OS_INVALID_HANDLE) 00406 { 00407 //Debug message 00408 TRACE_ERROR("Failed to create task!\r\n"); 00409 } 00410 00411 //Start the execution of tasks 00412 osStartKernel(); 00413 00414 //This function should never return 00415 return 0; 00416 } 00417 00418 00419 /** 00420 * @brief CGI callback function 00421 * @param[in] connection Handle referencing a client connection 00422 * @param[in] param NULL-terminated string that contains the CGI parameter 00423 * @return Error code 00424 **/ 00425 00426 error_t httpServerCgiCallback(HttpConnection *connection, 00427 const char_t *param) 00428 { 00429 static uint_t pageCounter = 0; 00430 uint_t length; 00431 MacAddr macAddr; 00432 #if (IPV4_SUPPORT == ENABLED) 00433 Ipv4Addr ipv4Addr; 00434 #endif 00435 #if (IPV6_SUPPORT == ENABLED) 00436 uint_t n; 00437 Ipv6Addr ipv6Addr; 00438 #endif 00439 00440 //Underlying network interface 00441 NetInterface *interface = connection->socket->interface; 00442 00443 //Check parameter name 00444 if(!strcasecmp(param, "PAGE_COUNTER")) 00445 { 00446 pageCounter++; 00447 sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : ""); 00448 } 00449 else if(!strcasecmp(param, "BOARD_NAME")) 00450 { 00451 strcpy(connection->buffer, "Nucleo-F746ZG"); 00452 } 00453 else if(!strcasecmp(param, "SYSTEM_TIME")) 00454 { 00455 systime_t time = osGetSystemTime(); 00456 formatSystemTime(time, connection->buffer); 00457 } 00458 else if(!strcasecmp(param, "MAC_ADDR")) 00459 { 00460 netGetMacAddr(interface, &macAddr); 00461 macAddrToString(&macAddr, connection->buffer); 00462 } 00463 else if(!strcasecmp(param, "IPV4_ADDR")) 00464 { 00465 ipv4GetHostAddr(interface, &ipv4Addr); 00466 ipv4AddrToString(ipv4Addr, connection->buffer); 00467 } 00468 else if(!strcasecmp(param, "SUBNET_MASK")) 00469 { 00470 ipv4GetSubnetMask(interface, &ipv4Addr); 00471 ipv4AddrToString(ipv4Addr, connection->buffer); 00472 } 00473 else if(!strcasecmp(param, "DEFAULT_GATEWAY")) 00474 { 00475 ipv4GetDefaultGateway(interface, &ipv4Addr); 00476 ipv4AddrToString(ipv4Addr, connection->buffer); 00477 } 00478 else if(!strcasecmp(param, "IPV4_PRIMARY_DNS")) 00479 { 00480 ipv4GetDnsServer(interface, 0, &ipv4Addr); 00481 ipv4AddrToString(ipv4Addr, connection->buffer); 00482 } 00483 else if(!strcasecmp(param, "IPV4_SECONDARY_DNS")) 00484 { 00485 ipv4GetDnsServer(interface, 1, &ipv4Addr); 00486 ipv4AddrToString(ipv4Addr, connection->buffer); 00487 } 00488 #if (IPV6_SUPPORT == ENABLED) 00489 else if(!strcasecmp(param, "LINK_LOCAL_ADDR")) 00490 { 00491 ipv6GetLinkLocalAddr(interface, &ipv6Addr); 00492 ipv6AddrToString(&ipv6Addr, connection->buffer); 00493 } 00494 else if(!strcasecmp(param, "GLOBAL_ADDR")) 00495 { 00496 ipv6GetGlobalAddr(interface, 0, &ipv6Addr); 00497 ipv6AddrToString(&ipv6Addr, connection->buffer); 00498 } 00499 else if(!strcasecmp(param, "IPV6_PREFIX")) 00500 { 00501 ipv6GetPrefix(interface, 0, &ipv6Addr, &n); 00502 ipv6AddrToString(&ipv6Addr, connection->buffer); 00503 length = strlen(connection->buffer); 00504 sprintf(connection->buffer + length, "/%u", n); 00505 } 00506 else if(!strcasecmp(param, "ROUTER")) 00507 { 00508 ipv6GetDefaultRouter(interface, 0, &ipv6Addr); 00509 ipv6AddrToString(&ipv6Addr, connection->buffer); 00510 } 00511 else if(!strcasecmp(param, "IPV6_PRIMARY_DNS")) 00512 { 00513 ipv6GetDnsServer(interface, 0, &ipv6Addr); 00514 ipv6AddrToString(&ipv6Addr, connection->buffer); 00515 } 00516 else if(!strcasecmp(param, "IPV6_SECONDARY_DNS")) 00517 { 00518 ipv6GetDnsServer(interface, 1, &ipv6Addr); 00519 ipv6AddrToString(&ipv6Addr, connection->buffer); 00520 } 00521 #endif 00522 else 00523 { 00524 return ERROR_INVALID_TAG; 00525 } 00526 00527 //Get the length of the resulting string 00528 length = strlen(connection->buffer); 00529 00530 //Send the contents of the specified environment variable 00531 return httpWriteStream(connection, connection->buffer, length); 00532 } 00533 00534 00535 /** 00536 * @brief URI not found callback 00537 * @param[in] connection Handle referencing a client connection 00538 * @param[in] uri NULL-terminated string containing the path to the requested resource 00539 * @return Error code 00540 **/ 00541 00542 error_t httpServerUriNotFoundCallback(HttpConnection *connection, 00543 const char_t *uri) 00544 { 00545 //Not implemented 00546 return ERROR_NOT_FOUND; 00547 } 00548 00549
Generated on Tue Jul 12 2022 17:10:14 by
1.7.2