Example #1
0
error_t udpEchoStart(void)
{
   error_t error;
   EchoServiceContext *context;
   OsTask *task;

   //Debug message
   TRACE_INFO("Starting UDP echo service...\r\n");

   //Allocate a memory block to hold the context
   context = osMemAlloc(sizeof(EchoServiceContext));
   //Failed to allocate memory?
   if(!context) return ERROR_OUT_OF_MEMORY;

   //Start of exception handling block
   do
   {
      //Open a UDP socket
      context->socket = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_PROTOCOL_UDP);

      //Failed to open socket?
      if(!context->socket)
      {
         //Report an error
         error = ERROR_OPEN_FAILED;
         //Exit immediately
         break;
      }

      //The server listens for incoming datagrams on port 7
      error = socketBind(context->socket, &IP_ADDR_ANY, ECHO_PORT);
      //Unable to bind the socket to the desired port?
      if(error) break;

      //Create a task to handle incoming datagrams
      task = osTaskCreate("UDP Echo", udpEchoTask,
         context, ECHO_SERVICE_STACK_SIZE, ECHO_SERVICE_PRIORITY);

      //Unable to create the task?
      if(task == OS_INVALID_HANDLE)
      {
         //Report an error to the calling function
         error = ERROR_OUT_OF_RESOURCES;
         break;
      }

      //End of exception handling block
   } while(0);

   //Any error to report?
   if(error)
   {
      //Clean up side effects...
      socketClose(context->socket);
      osMemFree(context);
   }

   //Return status code
   return error;
}
Example #2
0
void rprintfInit(void) {
    uint32 val;
    uint16 i;

    rprintfMutex = osSemaphoreCreateMutex();
    rprintfOSInit = TRUE;

    // init robot state to all be inactive (which is enabled)
    for (i = ROBOT_ID_MIN; i <= ROBOT_ID_MAX; ++i) {
        rprintfRemoteRobotState[i] = RPRINTF_REMOTE_ROBOT_STATE_INACTIVE;
    }

    // Initialize the radio command queue and callback behavior.
    radioCommandAddCallback(&radioCmdRprintfHostToRemote, "rprintf-func", rprintfRemoteCallback);
    radioCommandAddQueue(&radioCmdRprintfRemoteToHost, "rprintf-q", RPRINTF_MAX_PACKETS);

    // enable all the robots for remote query
    rprintfEnableRobot(ROBOT_ID_ALL, TRUE);

    // Put the robot in remote task by default.
    rprintfSetHostMode(RPRINTF_REMOTE);

    // Create the host task, which will run if the robot is in host mode.
    osTaskCreate(rprintfHostTask, "rprintfRemote", 2048, NULL, RPRINTFTERMINAL_TASK_PRIORITY);
}
Example #3
0
int main(void) {
    volatile uint32 val1, val2;

    systemPreInit();
    systemInit();
    neighborsInit(NEIGHBOR_ROUND_PERIOD);
    neighborsXmitEnable(TRUE);
    val1 = osTaskCreate(behaviorTask, "behavior", 4096, NULL, BEHAVIOR_TASK_PRIORITY);
    val2 = osTaskCreate(backgroundTask, "background", 1024, NULL, BACKGROUND_TASK_PRIORITY);

    if ((val1 != pdTRUE)) {
        cprintf("could not create a task");
    }

    /* Start the scheduler. */
    osTaskStartScheduler();

    /* Will only get here if there was insufficient memory to create the idle
     task. This is a very bad thing, and should not happen.*/
    return 0;
}
Example #4
0
error_t tcpEchoStart(void)
{
   error_t error;
   Socket *socket;
   OsTask *task;

   //Debug message
   TRACE_INFO("Starting TCP echo service...\r\n");

   //Open a TCP socket
   socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_PROTOCOL_TCP);
   //Failed to open socket?
   if(!socket) return ERROR_OPEN_FAILED;

   //Start of exception handling block
   do
   {
      //Bind the newly created socket to port 7
      error = socketBind(socket, &IP_ADDR_ANY, ECHO_PORT);
      //Failed to bind the socket to the desired port?
      if(error) break;

      //Place the socket into listening mode
      error = socketListen(socket);
      //Any error to report?
      if(error) break;

      //Create a task to handle incoming connection requests
      task = osTaskCreate("TCP Echo Listener", tcpEchoListenerTask,
         socket, ECHO_SERVICE_STACK_SIZE, ECHO_SERVICE_PRIORITY);

      //Unable to create the task?
      if(task == OS_INVALID_HANDLE)
      {
         //Report an error to the calling function
         error = ERROR_OUT_OF_RESOURCES;
         break;
      }

      //End of exception handling block
   } while(0);

   //Any error to report?
   if(error)
   {
      //Clean up side effects...
      socketClose(socket);
   }

   //Return status code
   return error;
}
Example #5
0
int main(void) {
	// init the rone hardware and roneos services
	systemInit();

	// init the behavior system and start the behavior thread
	behaviorSystemInit(behaviorTask, 4096);
	osTaskCreate(backgroundTask, "background", 1536, NULL, BACKGROUND_TASK_PRIORITY);

	// Start the scheduler
	osTaskStartScheduler();

	// should never get here.  If so, you have a bad memory problem in the scheduler
	return 0;
}
Example #6
0
error_t tcpIpStackInit(void)
{
   error_t error;
   uint_t i;
   OsTask *task;

   //Memory pool initialization
   error = memPoolInit();
   //Any error to report?
   if(error) return error;

   //Clear configuration data for each interface
   memset(netInterface, 0, sizeof(netInterface));

   //Loop through network interfaces
   for(i = 0; i < NET_INTERFACE_COUNT; i++)
   {
      //Default interface identifier
      netInterface[i].identifier = i;
      //Default name
      sprintf(netInterface[i].name, "eth%u", i);
   }

   //Socket related initialization
   error = socketInit();
   //Any error to report?
   if(error) return error;

   //Create task to handle periodic operations
   task = osTaskCreate("TCP/IP Stack (Tick)", tcpIpStackTickTask,
      NULL, TCP_IP_TICK_STACK_SIZE, TCP_IP_TICK_PRIORITY);
   //Unable to create the task?
   if(task == OS_INVALID_HANDLE)
      return ERROR_OUT_OF_RESOURCES;

   //The handle can be used for further referencing
   for(i = 0; i < NET_INTERFACE_COUNT; i++)
      netInterface[i].tickTask = task;

   //Return status code
   return error;
}
Example #7
0
void tcpEchoListenerTask(void *param)
{
   error_t error;
   uint16_t clientPort;
   IpAddr clientIpAddr;
   Socket *serverSocket;
   Socket *clientSocket;
   EchoServiceContext *context;
   OsTask *task;

   //Point to the listening socket
   serverSocket = (Socket *) param;

   //Main loop
   while(1)
   {
      //Accept an incoming connection
      clientSocket = socketAccept(serverSocket, &clientIpAddr, &clientPort);
      //Check whether a valid connection request has been received
      if(!clientSocket) continue;

      //Debug message
      TRACE_INFO("Echo service: connection established with client %s port %u\r\n",
         ipAddrToString(&clientIpAddr, NULL), clientPort);

      //The socket operates in non-blocking mode
      error = socketSetTimeout(clientSocket, 0);

      //Any error to report?
      if(error)
      {
         //Close socket
         socketClose(clientSocket);
         //Wait for an incoming connection attempt
         continue;
      }

      //Allocate resources for the new connection
      context = osMemAlloc(sizeof(EchoServiceContext));

      //Failed to allocate memory?
      if(!context)
      {
         //Close socket
         socketClose(clientSocket);
         //Wait for an incoming connection attempt
         continue;
      }

      //Record the handle of the newly created socket
      context->socket = clientSocket;

      //Create a task to service the current connection
      task = osTaskCreate("TCP Echo Connection", tcpEchoConnectionTask,
         context, ECHO_SERVICE_STACK_SIZE, ECHO_SERVICE_PRIORITY);

      //Did we encounter an error?
      if(task == OS_INVALID_HANDLE)
      {
         //Close socket
         socketClose(clientSocket);
         //Release resources
         osMemFree(context);
      }
   }
}
Example #8
0
error_t tcpIpStackConfigInterface(NetInterface *interface)
{
   error_t error;

//IPv6 specific variables
#if (IPV6_SUPPORT == ENABLED)
   Ipv6Addr solicitedNodeAddr;
#endif

   //Disable Ethernet controller interrupts
   interface->nicDriver->disableIrq(interface);

   //Start of exception handling block
   do
   {
      //Receive notifications when the transmitter is ready to send
      interface->nicTxEvent = osEventCreate(FALSE, FALSE);
      //Out of resources?
      if(interface->nicTxEvent == OS_INVALID_HANDLE)
      {
         //Report an error
         error = ERROR_OUT_OF_RESOURCES;
         //Stop immediately
         break;
      }

      //Receive notifications when a Ethernet frame has been received,
      //or the link status has changed
      interface->nicRxEvent = osEventCreate(FALSE, FALSE);
      //Out of resources?
      if(interface->nicRxEvent == OS_INVALID_HANDLE)
      {
         //Report an error
         error = ERROR_OUT_OF_RESOURCES;
         //Stop immediately
         break;
      }

      //Create a mutex to prevent simultaneous access to the NIC driver
      interface->nicDriverMutex = osMutexCreate(FALSE);
      //Out of resources?
      if(interface->nicDriverMutex == OS_INVALID_HANDLE)
      {
         //Report an error
         error = ERROR_OUT_OF_RESOURCES;
         //Stop immediately
         break;
      }

      //Ethernet controller configuration
      error = interface->nicDriver->init(interface);
      //Any error to report?
      if(error) break;

      //Ethernet related initialization
      error = ethInit(interface);
      //Any error to report?
      if(error) break;

//IPv4 specific initialization
#if (IPV4_SUPPORT == ENABLED)
      //Network layer initialization
      error = ipv4Init(interface);
      //Any error to report?
      if(error) break;

      //ARP cache initialization
      error = arpInit(interface);
      //Any error to report?
      if(error) break;

#if (IGMP_SUPPORT == ENABLED)
      //IGMP related initialization
      error = igmpInit(interface);
      //Any error to report?
      if(error) break;

      //Join the all-systems group
      error = ipv4JoinMulticastGroup(interface, IGMP_ALL_SYSTEMS_ADDR);
      //Any error to report?
      if(error) break;
#endif
#endif

//IPv6 specific initialization
#if (IPV6_SUPPORT == ENABLED)
      //Network layer initialization
      error = ipv6Init(interface);
      //Any error to report?
      if(error) break;

      //Neighbor cache initialization
      error = ndpInit(interface);
      //Any error to report?
      if(error) break;

#if (MLD_SUPPORT == ENABLED)
      ///MLD related initialization
      error = mldInit(interface);
      //Any error to report?
      if(error) break;
#endif
      //Join the All-Nodes multicast address
      error = ipv6JoinMulticastGroup(interface, &IPV6_LINK_LOCAL_ALL_NODES_ADDR);
      //Any error to report?
      if(error) break;

      //Form the Solicited-Node address for the link-local address
      error = ipv6ComputeSolicitedNodeAddr(&interface->ipv6Config.linkLocalAddr, &solicitedNodeAddr);
      //Any error to report?
      if(error) break;

      //Join the Solicited-Node multicast group for each assigned address
      error = ipv6JoinMulticastGroup(interface, &solicitedNodeAddr);
      //Any error to report?
      if(error) break;
#endif

      //Create a task to process incoming frames
      interface->rxTask = osTaskCreate("TCP/IP Stack (RX)", tcpIpStackRxTask,
         interface, TCP_IP_RX_STACK_SIZE, TCP_IP_RX_PRIORITY);

      //Unable to create the task?
      if(interface->rxTask == OS_INVALID_HANDLE)
         error = ERROR_OUT_OF_RESOURCES;

      //End of exception handling block
   } while(0);

   //Check whether the interface is fully configured
   if(!error)
   {
      //Successful interface configuration
      interface->configured = TRUE;
      //Interrupts can be safely enabled
      interface->nicDriver->enableIrq(interface);
   }
   else
   {
      //Clean up side effects before returning
      osEventClose(interface->nicTxEvent);
      osEventClose(interface->nicRxEvent);
      osMutexClose(interface->nicDriverMutex);
   }

   //Return status code
   return error;
}
Example #9
0
error_t dhcpv6RelayStart(Dhcpv6RelayCtx *context, const Dhcpv6RelaySettings *settings)
{
   error_t error;
   uint_t i;
   OsTask *task;

   //Debug message
   TRACE_INFO("Starting DHCPv6 relay agent...\r\n");

   //Ensure the parameters are valid
   if(!context || !settings)
      return ERROR_INVALID_PARAMETER;
   //The pointer to the network-facing interface shall be valid
   if(!settings->serverInterface)
      return ERROR_INVALID_INTERFACE;
   //Check the number of client-facing interfaces
   if(!settings->clientInterfaceCount)
      return ERROR_INVALID_PARAMETER;
   if(settings->clientInterfaceCount >= DHCPV6_RELAY_MAX_CLIENT_IF)
      return ERROR_INVALID_PARAMETER;

   //Loop through the client-facing interfaces
   for(i = 0; i < settings->clientInterfaceCount; i++)
   {
      //A valid pointer is required for each interface
      if(!settings->clientInterface[i])
         return ERROR_INVALID_INTERFACE;
   }

   //Check the address to be used when forwarding messages to the server
   if(ipv6CompAddr(&settings->serverAddress, &IPV6_UNSPECIFIED_ADDR))
      return ERROR_INVALID_ADDRESS;

   //Clear the DHCPv6 relay agent context
   memset(context, 0, sizeof(Dhcpv6RelayCtx));

   //Save the network-facing interface
   context->serverInterface = settings->serverInterface;
   //Save the number of client-facing interfaces
   context->clientInterfaceCount = settings->clientInterfaceCount;
   //Save all the client-facing interfaces
   for(i = 0; i < context->clientInterfaceCount; i++)
      context->clientInterface[i] = settings->clientInterface[i];

   //Save the address to be used when relaying client messages to the server
   context->serverAddress = settings->serverAddress;

   //Join the All_DHCP_Relay_Agents_and_Servers multicast group
   //for each client-facing interface
   error = dhcpv6RelayJoinMulticastGroup(context);
   //Any error to report?
   if(error) return error;

   //Start of exception handling block
   do
   {
      //Open a UDP socket to handle the network-facing interface
      context->serverSocket = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_IP_PROTO_UDP);
      //Failed to open socket?
      if(!context->serverSocket)
      {
         //Report an error
         error = ERROR_OPEN_FAILED;
         //Stop processing
         break;
      }

      //Explicitly associate the socket with the relevant interface
      error = socketBindToInterface(context->serverSocket, context->serverInterface);
      //Unable to bind the socket to the desired interface?
      if(error) break;

      //Relay agents listen for DHCPv6 messages on UDP port 547
      error = socketBind(context->serverSocket, &IP_ADDR_ANY, DHCPV6_SERVER_PORT);
      //Unable to bind the socket to the desired port?
      if(error) break;

      //Only accept datagrams with source port number 547
      error = socketConnect(context->serverSocket, &IP_ADDR_ANY, DHCPV6_SERVER_PORT);
      //Any error to report?
      if(error) break;

      //If the relay agent relays messages to the All_DHCP_Servers address
      //or other multicast addresses, it sets the Hop Limit field to 32

      //Loop through the client-facing interfaces
      for(i = 0; i < context->clientInterfaceCount; i++)
      {
         //Open a UDP socket to handle the current interface
         context->clientSocket[i] = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_IP_PROTO_UDP);
         //Failed to open socket?
         if(!context->clientSocket[i])
         {
            //Report an error
            error = ERROR_OPEN_FAILED;
            //Stop processing
            break;
         }

         //Explicitly associate the socket with the relevant interface
         error = socketBindToInterface(context->clientSocket[i], context->clientInterface[i]);
         //Unable to bind the socket to the desired interface?
         if(error) break;

         //Relay agents listen for DHCPv6 messages on UDP port 547
         error = socketBind(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_SERVER_PORT);
         //Unable to bind the socket to the desired port?
         if(error) break;

         //Only accept datagrams with source port number 546
         error = socketConnect(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_CLIENT_PORT);
         //Any error to report?
         if(error) break;
      }

      //Propagate exception if necessary...
      if(error) break;

      //Create event objects
      context->event = osEventCreate(FALSE);
      context->ackEvent = osEventCreate(FALSE);

      //Out of resources?
      if(context->event == OS_INVALID_HANDLE ||
         context->ackEvent == OS_INVALID_HANDLE)
      {
         //Report an error
         error = ERROR_OUT_OF_RESOURCES;
         //Stop processing
         break;
      }

      //The DHCPv6 relay agent is now running
      context->running = TRUE;

      //Start the DHCPv6 relay agent service
      task = osTaskCreate("DHCPv6 Relay", dhcpv6RelayTask,
         context, DHCPV6_RELAY_STACK_SIZE, DHCPV6_RELAY_PRIORITY);

      //Unable to create the task?
      if(task == OS_INVALID_HANDLE)
         error = ERROR_OUT_OF_RESOURCES;

      //End of exception handling block
   } while(0);

   //Did we encounter an error?
   if(error)
   {
      //Close the socket associated with the network-facing interface
      socketClose(context->serverSocket);

      //Close the socket associated with each client-facing interface
      for(i = 0; i < context->clientInterfaceCount; i++)
         socketClose(context->clientSocket[i]);

      //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
      //for each client-facing interface
      dhcpv6RelayLeaveMulticastGroup(context);

      //Close event objects
      osEventClose(context->event);
      osEventClose(context->ackEvent);
   }

   //Return status code
   return error;
}
Example #10
0
/*
 * 	@brief Initializes serial command processing
 *
 *	@returns void
 */
void serialCommandInit() {
	// Make a thread to process serial command strings
	osTaskCreate(serialCommandTask, "serialCommand", 2048, NULL, SERIALIO_TASK_PRIORITY);
}
Example #11
0
int_t main(void)
{
   error_t error;
   NetInterface *interface;
   OsTask *task;

   static DhcpClientSettings dhcpClientSettings;
   static DhcpClientCtx dhcpClientContext;

   //Update system core clock
   SystemCoreClockUpdate();
   //Configure debug UART
   debugInit(115200);

   //Start-up message
   TRACE_INFO("\r\n");
   TRACE_INFO("**********************************\r\n");
   TRACE_INFO("*** CycloneTCP FTP Client Demo ***\r\n");
   TRACE_INFO("**********************************\r\n");
   TRACE_INFO("Copyright: 2010-2013 Oryx Embedded\r\n");
   TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__);
   TRACE_INFO("Target: SAM4E\r\n");
   TRACE_INFO("\r\n");

   //IO configuration
   ioInit();

   //Initialize LCD display
   GLCD_Init();
   GLCD_SetBackColor(Blue);
   GLCD_SetTextColor(White);
   GLCD_Clear(Blue);

   //Welcome message
   lcdSetCursor(0, 0);
   printf("FTP Client Demo\r\n");

   //TCP/IP stack initialization
   error = tcpIpStackInit();

   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n");
   }

   //Configure the first Ethernet interface
   interface = &netInterface[0];
   //Select the relevant network adapter
   interface->nicDriver = &sam4eEthDriver;
   interface->phyDriver = &ksz8051PhyDriver;
   //Interface name
   strcpy(interface->name, "eth0");
   //Set host MAC address
   macStringToAddr("00-AB-CD-EF-04-16", &interface->macAddr);

#if (IPV6_SUPPORT == ENABLED)
   //Set link-local IPv6 address
   ipv6StringToAddr("fe80::00ab:cdef:0416", &interface->ipv6Config.linkLocalAddr);
#endif

   //Initialize network interface
   error = tcpIpStackConfigInterface(interface);

   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name);
   }

#if 1
   //Set the network interface to be configured by DHCP
   dhcpClientSettings.interface = &netInterface[0];
   //Disable rapid commit option
   dhcpClientSettings.rapidCommit = FALSE;
   //Start DHCP client
   error = dhcpClientStart(&dhcpClientContext, &dhcpClientSettings);

   //Failed to start DHCP client?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to start DHCP client!\r\n");
   }
#else
   //Manual configuration
   interface = &netInterface[0];

   //IPv4 address
   ipv4StringToAddr("192.168.0.20", &interface->ipv4Config.addr);
   //Subnet mask
   ipv4StringToAddr("255.255.255.0", &interface->ipv4Config.subnetMask);
   //Default gateway
   ipv4StringToAddr("192.168.0.254", &interface->ipv4Config.defaultGateway);

   //Primary and secondary DNS servers
   interface->ipv4Config.dnsServerCount = 2;
   ipv4StringToAddr("212.27.40.240", &interface->ipv4Config.dnsServer[0]);
   ipv4StringToAddr ("212.27.40.241", &interface->ipv4Config.dnsServer[1]);
#endif

   //Create user task
   task = osTaskCreate("User Task", userTask, NULL, 500, 1);
   //Failed to create the task?
   if(task == OS_INVALID_HANDLE)
   {
      //Debug message
      TRACE_ERROR("Failed to create task!\r\n");
   }

   //Create a task to blink the LED
   task = osTaskCreate("Blink", blinkTask, NULL, 500, 1);
   //Failed to create the task?
   if(task == OS_INVALID_HANDLE)
   {
      //Debug message
      TRACE_ERROR("Failed to create task!\r\n");
   }

   //Start the execution of tasks
   osStart();

   //This function should never return
   return 0;
}
Example #12
0
error_t icecastClientStart(IcecastClientContext *context,
   const IcecastClientSettings *settings)
{
   error_t error;
   OsTask *task;

   //Debug message
   TRACE_INFO("Starting Icecast client...\r\n");

   //Ensure the parameters are valid
   if(!context || !settings)
      return ERROR_INVALID_PARAMETER;

   //Clear the Icecast client context
   memset(context, 0, sizeof(IcecastClientContext));
   //Save user settings
   context->settings = *settings;

   //Get the size of the circular buffer
   context->bufferSize = settings->bufferSize;

   //Start of exception handling block
   do
   {
      //Allocate a memory block to hold the circular buffer
      context->streamBuffer = osMemAlloc(context->bufferSize);

      //Failed to allocate memory?
      if(!context->streamBuffer)
      {
         //Report an error to the calling function
         error = ERROR_OUT_OF_MEMORY;
         break;
      }

      //Create mutex object to protect critical sections
      context->mutex = osMutexCreate(FALSE);

      //Failed to create mutex object?
      if(context->mutex == OS_INVALID_HANDLE)
      {
         //Report an error to the calling function
         error = ERROR_OUT_OF_RESOURCES;
         break;
      }

      //Create events to get notified when the buffer is writable/readable
      context->writeEvent = osEventCreate(FALSE, TRUE);
      context->readEvent = osEventCreate(FALSE, FALSE);

      //Failed to create event object?
      if(context->writeEvent == OS_INVALID_HANDLE ||
         context->readEvent == OS_INVALID_HANDLE)
      {
         //Report an error to the calling function
         error = ERROR_OUT_OF_RESOURCES;
         break;
      }

      //Create the Icecast client task
      task = osTaskCreate("Icecast client", icecastClientTask,
         context, ICECAST_CLIENT_STACK_SIZE, ICECAST_CLIENT_PRIORITY);

      //Unable to create the task?
      if(task == OS_INVALID_HANDLE)
      {
         //Report an error to the calling function
         error = ERROR_OUT_OF_RESOURCES;
         break;
      }

      //Successful initialization
      error = NO_ERROR;

      //End of exception handling block
   } while(0);

   //Check whether an error occurred
   if(error)
   {
      //Clean up side effects...
      osMemFree(context->streamBuffer);
      osMutexClose(context->mutex);
      osEventClose(context->writeEvent);
      osEventClose(context->readEvent);
   }

   //Return status code
   return error;
}
Example #13
0
int_t main(void)
{
   error_t error;
   NetInterface *interface;
   OsTask *task;

#if USE_DHCP
   static DhcpClientSettings dhcpClientSettings;
   static DhcpClientCtx dhcpClientContext;
#endif
   static HttpServerSettings httpServerSettings;
   static HttpServerContext httpServerContext;

   SystemInit();

   //Configure debug UART
   debugInit();

   //Start-up message
   TRACE_INFO("\r\n");
   TRACE_INFO("***********************************\r\n");
   TRACE_INFO("*** CycloneTCP HTTP Client Demo ***\r\n");
   TRACE_INFO("***********************************\r\n");
   TRACE_INFO("Copyright: 2010-2013 Oryx Embedded\r\n");
   TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__);
   TRACE_INFO("Target: STM32F407\r\n");
   TRACE_INFO("\r\n");

   //LED configuration
   STM_EVAL_LEDInit(LED3);
   STM_EVAL_LEDInit(LED4);
   STM_EVAL_LEDInit(LED5);
   STM_EVAL_LEDInit(LED6);

   //Clear LEDs
   STM_EVAL_LEDOff(LED3);
   STM_EVAL_LEDOff(LED4);
   STM_EVAL_LEDOff(LED5);
   STM_EVAL_LEDOff(LED6);

   //Initialize user button
   STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_GPIO);

   //PRNG initialization
   error = yarrowInit(&yarrowContext);

   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to initialize PRNG!\r\n");
   }

   //Generate a random seed

   //Properly seed the PRNG
   error = yarrowSeed(&yarrowContext, seed, sizeof(seed));

   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to seed PRNG!\r\n");
   }

   //TCP/IP stack initialization
   error = tcpIpStackInit();

   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n");
   }

   //Configure the first Ethernet interface
   interface = &netInterface[0];
   //Select the relevant network adapter
   interface->nicDriver = &stm32f4x7EthDriver;
   interface->phyDriver = &dp83848PhyDriver;
   //Interface name
   strcpy(interface->name, "eth0");
   //Set host MAC address
   macStringToAddr("00-AB-CD-EF-04-07", &interface->macAddr);

#if (IPV6_SUPPORT == ENABLED)
   //Set link-local IPv6 address
   ipv6StringToAddr("fe80::00ab:cdef:0407", &interface->ipv6Config.linkLocalAddr);
#endif

   //Initialize network interface
   error = tcpIpStackConfigInterface(interface);

   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name);
   }

#if USE_DHCP
   //Set the network interface to be configured by DHCP
   dhcpClientSettings.interface = &netInterface[0];
   //Disable rapid commit option
   dhcpClientSettings.rapidCommit = FALSE;
   //Start DHCP client
   error = dhcpClientStart(&dhcpClientContext, &dhcpClientSettings);

   //Failed to start DHCP client?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to start DHCP client!\r\n");
   }
#else
   //Manual configuration
   interface = &netInterface[0];

   //IPv4 address
   ipv4StringToAddr(IPV4_STATIC_IP, &interface->ipv4Config.addr);
   //Subnet mask
   ipv4StringToAddr(IPV4_STATIC_MASK, &interface->ipv4Config.subnetMask);
   //Default gateway
   ipv4StringToAddr(IPV4_STATIC_GW, &interface->ipv4Config.defaultGateway);

   //Primary and secondary DNS servers
   interface->ipv4Config.dnsServerCount = 2;
   ipv4StringToAddr(IPV4_STATIC_DNS0, &interface->ipv4Config.dnsServer[0]);
   ipv4StringToAddr(IPV4_STATIC_DNS1, &interface->ipv4Config.dnsServer[1]);
#endif
   //Bind HTTP server to the desired interface
   httpServerSettings.interface = &netInterface[0];
   //Listen to port 80
   httpServerSettings.port = HTTP_PORT;
   //Specify the server's root directory
   strcpy(httpServerSettings.rootDirectory, "/www/");
   //Set default home page
   strcpy(httpServerSettings.defaultDocument, "index.shtm");
   //Callback functions
   httpServerSettings.cgiCallback = httpServerCgiCallback;
   httpServerSettings.uriNotFoundCallback = httpServerUriNotFoundCallback;
   //Start HTTP server
   error = httpServerStart(&httpServerContext, &httpServerSettings);

   //Failed to start HTTP server?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Failed to start HTTP server!\r\n");
   }

   //Create user task
   task = osTaskCreate("User Task", userTask, interface, 500, 1);
   //Failed to create the task?
   if(task == OS_INVALID_HANDLE)
   {
      //Debug message
      TRACE_ERROR("Failed to create task!\r\n");
   }

   //Create a task to blink the LED
   task = osTaskCreate("Blink", blinkTask, NULL, 500, 1);
   //Failed to create the task?
   if(task == OS_INVALID_HANDLE)
   {
      //Debug message
      TRACE_ERROR("Failed to create task!\r\n");
   }

   //Start the execution of tasks
   osStart();

   //This function should never return
   return 0;
}