RZ/A Flexible Software Package Documentation  Release v3.5.0

 
FreeRTOS Plus TCP (rm_freertos_plus_tcp)

Detailed Description

Middleware for using TCP on RZ MPUs.

Overview

FreeRTOS Plus TCP is a TCP stack created for use with FreeRTOS.

This module provides the NetworkInterface required to use FreeRTOS Plus TCP with the Ethernet (r_gether) driver.

Please refer to the FreeRTOS Plus TCP documentation for further details.

Configuration

Build Time Configurations for FreeRTOS_Plus_TCP

The following build time configurations are defined in aws/FreeRTOSIPConfig.h:

ConfigurationOptionsDefaultDescription
Print debug messages
  • Disable
  • Enable
Disable If ipconfigHAS_DEBUG_PRINTF is set to 1 then FreeRTOS_debug_printf should be defined to the function used to print out the debugging messages.
Backward Compatible Mode
  • No
  • Yes
Yes Run the code in backward compatible mode
Enable IPV6
  • Disable
  • Enable
Disable Stack supports handling IPv6 packets (including handling IPv6 header, ND, RA, and so on) when enabled
Print info messages
  • Disable
  • Enable
Disable Set to 1 to print out non debugging messages, for example the output of the FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 then FreeRTOS_printf should be set to the function used to print out the messages.
Byte order of the target MCUpdFREERTOS_LITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN Define the byte order of the target MCU
IP/TCP/UDP checksums
  • Disable
  • Enable
Enable If the network card/driver includes checksum offloading (IP/TCP/UDP checksums) then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software stack repeating the checksum calculations.
Receive Block TimeValue must be a non-negative integer10000 Amount of time FreeRTOS_recv() will block for. The timeouts can be set per socket, using setsockopt().
Send Block TimeValue must be a non-negative integer10000 Amount of time FreeRTOS_send() will block for. The timeouts can be set per socket, using setsockopt().
DNS caching
  • Disable
  • Enable
Enable DNS caching
DNS Request AttemptsValue must be an integer2 When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low and also DNS may use small timeouts.
IP stack task priorityManual EntryconfigMAX_PRIORITIES - 2 Set the priority of the task that executes the IP stack.
Stack size in words (not bytes)Manual EntryconfigMINIMAL_STACK_SIZE * 5 The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP stack.
Network Events call vApplicationIPNetworkEventHook
  • Disable
  • Enable
Enable vApplicationIPNetworkEventHook is called when the network connects or disconnects.
Max UDP send block timeManual Entry15000 / portTICK_PERIOD_MS Max UDP send block time
Use DHCP
  • Disable
  • Enable
Enable If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP address, netmask, DNS server address and gateway address from a DHCP server.
DHCP Register Hostname
  • Disable
  • Enable
Enable Register hostname when using DHCP
DHCP Uses Unicast
  • Disable
  • Enable
Enable DHCP uses unicast.
DHCP Send Discover After Auto IP
  • Disable
  • Enable
Disable DHCP Send Discover After Auto IP
DHCP callback function
  • Disable
  • Enable
Disable Provide an implementation of the DHCP callback function(xApplicationDHCPHook)
Interval between transmissionsManual Entry120000 / portTICK_PERIOD_MS When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at increasing time intervals until either a reply is received from a DHCP server and accepted, or the interval between transmissions reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD.
ARP Cache EntriesValue must be an integer6 The maximum number of entries that can exist in the ARP table at any one time
ARP Request RetransmissionsValue must be an integer5 ARP requests that do not result in an ARP response will be re-transmitted a maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is aborted.
Maximum time before ARP table entry becomes staleValue must be an integer150 The maximum time between an entry in the ARP table being created or refreshed and the entry being removed because it is stale
Use string for IP Address
  • Disable
  • Enable
Enable Take an IP in decimal dot format (for example, "192.168.0.1") as its parameter FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets (for example, 192, 168, 0, 1) as its parameters
Total number of available network buffersValue must be an integer10 Define the total number of network buffer that are available to the IP stack
Set the maximum number of eventsPlease enter a valid function name without spaces or funny charactersipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 Set the maximum number of events that can be queued for processing at any one time. The event queue must be a minimum of 5 greater than the total number of network buffers
Enable FreeRTOS_sendto() without calling Bind
  • Enable
  • Disable
Disable Set to 1 then calling FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP stack automatically binding the socket to a port number from the range socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() on a socket that has not yet been bound will result in the send operation being aborted.
TTL values for UDP packetsValue must be an integer128 Define the Time To Live (TTL) values used in outgoing UDP packets
TTL values for TCP packetsValue must be an integer128 Defines the Time To Live (TTL) values used in outgoing TCP packets
Use TCP and all its features
  • Disable
  • Enable
Enable Use TCP and all its features
Let TCP use windowing mechanism
  • Disable
  • Enable
Disable Let TCP use windowing mechanism
Maximum number of bytes the payload of a network frame can containValue must be an integer1500 Maximum number of bytes the payload of a network frame can contain
Basic DNS client or resolver
  • Disable
  • Enable
Enable Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used through the FreeRTOS_gethostbyname() API function.
Reply to incoming ICMP echo (ping) requests
  • Disable
  • Enable
Enable If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will generate replies to incoming ICMP echo (ping) requests.
FreeRTOS_SendPingRequest() is available
  • Disable
  • Enable
Disable If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the FreeRTOS_SendPingRequest() API function is available.
FreeRTOS_select() (and associated) API function is available
  • Disable
  • Enable
Disable If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() (and associated) API function is available
Filter out non Ethernet II frames.
  • Disable
  • Enable
Enable If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames that are not in Ethernet II format will be dropped. This option is included for potential future IP stack developments
Responsibility of the Ethernet interface to filter out packets
  • Disable
  • Enable
Disable If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the responsibility of the Ethernet interface to filter out packets that are of no interest.
Send RST packets, when receive unknown packets.
  • Disable
  • Enable
Enable TCP will not send RST packets in reply to TCP unknown or out-of-order packets
Block time to simulate MAC interruptsPlease enter a valid function name without spaces or funny characters20 / portTICK_PERIOD_MS The windows simulator cannot really simulate MAC interrupts, and needs to block occasionally to allow other tasks to run
Access 32-bit fields in the IP packetsValue must be an integer2 To access 32-bit fields in the IP packets with 32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits. This has to do with the contents of the IP-packets: all 32-bit fields are 32-bit-aligned, plus 16-bit
Size of the pool of TCP window descriptorsValue must be an integer240 Define the size of the pool of TCP window descriptors
Size of Rx buffer for TCP socketsValue must be an integer3000 Define the size of Rx buffer for TCP sockets
Size of Tx buffer for TCP socketsValue must be an integer3000 Define the size of Tx buffer for TCP sockets
TCP keep-alive
  • Disable
  • Enable
Enable TCP keep-alive is avaiable or not
TCP keep-alive intervalValue must be an integer120 TCP keep-alive interval in second
The socket semaphore to unblock the MQTT task (USER_SEMAPHORE)
  • Disable
  • Enable
Disable The socket semaphore is used to unblock the MQTT task
The socket semaphore to unblock the MQTT task (WAKE_CALLBACK)
  • Disable
  • Enable
Enable The socket semaphore is used to unblock the MQTT task
The socket semaphore to unblock the MQTT task (USE_CALLBACKS)
  • Disable
  • Enable
Disable The socket semaphore is used to unblock the MQTT task
The socket semaphore to unblock the MQTT task (TX_DRIVER)
  • Disable
  • Enable
Disable The socket semaphore is used to unblock the MQTT task
The socket semaphore to unblock the MQTT task (RX_DRIVER)
  • Disable
  • Enable
Disable The socket semaphore is used to unblock the MQTT task
Possible optimisation for expert users
  • Disable
  • Enable
Disable Possible optimisation for expert users - requires network driver support. It is is useful when there is high network traffic. If non-zero value then instead of passing received packets into the IP task one at a time the network interface can chain received packets together and pass them into the IP task in one go. If set to 0 then only one buffer will be sent at a time.

Usage Notes

In order to use the NetworkInterface implementation provided by Renesas for RZ/A devices:

/* Reference used by the NetworkInterface to access the ethernet instance. */
extern ether_instance_t const * gp_freertos_ether;
...
/* Make it reference the configured ether instance. */
ether_instance_t const * gp_freertos_ether = &g_ether_instance;
Note
The MAC address passed to FreeRTOS_IPInit must match the MAC address configured in the r_ether instance.
g_ether_instance must have vEtherISRCallback configured as the callback.
The xApplicationGetRandomNumber and ulApplicationGetNextSequenceNumber functions should be implemented in systems using FreeRTOS Plus TCP without Secure Sockets.
The weak implementations provided of xApplicationGetRandomNumber and ulApplicationGetNextSequenceNumber rely on rand() as implemented by the respective compiler's math library and may require heap allocation to support re-entrant usage. If these implementations are to be used, srand() must be seeded with a truly random value in the application in order to ensure randomness. This should be done using psa_generate_random() from the mbedtls stack. The weak implementations can also be instead overridden with a user-implementation that uses psa_generate_random().
To connect to a server using an IP address the macro ipconfigINCLUDE_FULL_INET_ADDR must be set to 1.

Limitations

Examples

ETHER Dual-port Example

This is a example to send/receive PING between two ports of ETHER in an application.

Note
In this example zero-copy mode is disabled and there are no restrictions on buffer alignment.
#define RANDOM_MASK_7FFF (0x7fffUL)
#define RANDOM_MASK_0003 (0x0003UL)
#define SHIFT_15BITS (15)
#define SHIFT_30BITS (30)
#define PING_TIMEOUT (500)
#define PING_REQ_TIMEOUT (100)
#define TASK_DELAY_TIME (100)
#define MAX_VALUE_32BITS (0xFFFFFFFFUL)
/* IP address of the PC or any Device on the LAN/WAN where the Ping request is sent.
* Note: Users needs to change this according to the LAN settings of your Test PC or device
* when running this project.
*/
static char * gp_remote_ip_address = USR_TEST_PING_IP;
/* Static IP configuration, when DHCP mode is not used for the Example Project.
* This needs to be populated by the user according to the Network Settings of your LAN.
* This sample address taken from the LAN where it is tested. This is different for different LAN.
* get the Address using the PC IPconfig details.
*/
static uint8_t ucMACAddress[2][6];
static uint8_t ucIPAddress[2][4];
static uint8_t ucNetMask[2][4];
static uint8_t ucGatewayAddress[2][4];
static uint8_t ucDNSServerAddress[2][4];
static uint32_t usr_print_ability = RESET_VALUE;
uint32_t usr_ping_count = RESET_VALUE;
ping_data_t ping_data = {RESET_VALUE, RESET_VALUE, RESET_VALUE};
uint32_t timer_counter = RESET_VALUE;
ping_status_t ping_status[USR_PING_COUNT + 1] = {RESET_VALUE};
static char const * const link_status[] =
{
"10Mbps Half Duplex\r\n",
"10Mbps Full Duplex\r\n",
"100Mbps Half Duplex\r\n",
"100Mbps Full Duplex\r\n",
"1000Mbps Half Duplex\r\n",
"1000Mbps Full Duplex\r\n",
"Illegal Value\r\n",
"Illegal Value\r\n"
};
static NetworkInterface_t xInterfaces[2];
extern void * __freertos_plus_tcp_array_start;
extern void * __freertos_plus_tcp_array_end;
/* Generates 32 bit Random number */
BaseType_t xApplicationGetRandomNumber (uint32_t * pulNumber)
{
/* example of a 32-bit random number generator.
* Here rand() returns a 15-bit number. so create 32 bit Random number using 15 bit rand()
*/
uint32_t ulResult = (uint32_t) (
((((uint32_t) user_rand()) & RANDOM_MASK_7FFF)) |
((((uint32_t) user_rand()) & RANDOM_MASK_7FFF) << SHIFT_15BITS) |
((((uint32_t) user_rand()) & RANDOM_MASK_0003) << SHIFT_30BITS));
*pulNumber = ulResult;
return pdPASS;
}
/* Generates 32 sequence number */
uint32_t ulApplicationGetNextSequenceNumber (uint32_t ulSourceAddress,
uint16_t usSourcePort,
uint32_t ulDestinationAddress,
uint16_t usDestinationPort)
{
/* Here we need to get random number for the sequence number.
* This is just for testing purpose, so software rand() is okay.
* This can also be tied to the TRNG.
*/
return (ulSourceAddress + ulDestinationAddress + usSourcePort + usDestinationPort) && ulRand();
}
/* Send ICMP Ping request based on the user input IP Address. */ BaseType_t vSendPing (const char * pcIPAddress)
{
uint32_t ulIPAddress = RESET_VALUE;
/*
* The pcIPAddress parameter holds the destination IP address as a string in
* decimal dot notation (for example, '192.168.0.200'). Convert the string into
* the required 32-bit format.
*/
ulIPAddress = FreeRTOS_inet_addr(pcIPAddress);
/*
* Send a ping request containing 8 data bytes. Wait (in the Blocked state) a
* maximum of 100ms for a network buffer into which the generated ping request
* can be written and sent.
*/
return FreeRTOS_SendPingRequest(ulIPAddress, BYTES_DATA_SEND, PING_REQ_TIMEOUT / portTICK_PERIOD_MS);
}
/* User Hook for the Ping Reply. vApplicationPingReplyHook() is called by the TCP/IP
* stack when the stack receives a ping reply.
*/
void vApplicationPingReplyHook (ePingReplyStatus_t eStatus, uint16_t usIdentifier)
{
switch (eStatus)
{
/* A valid ping reply has been received */
case eSuccess:
{
ping_status[usIdentifier].status = PING_SUCCESS;
break;
}
/* A reply was received but it was not valid. */
case eInvalidData:
default:
{
ping_status[usIdentifier].status = INVALID_DATA;
break;
}
}
ping_status[usIdentifier].id = usIdentifier;
ping_status[usIdentifier].time = timer_counter;
}
/* This is the User Thread for the EP. */
void rm_freertos_plus_tcp_example (void * pvParameters)
{
BaseType_t status = pdFALSE;
fsp_pack_version_t version = {RESET_VALUE};
FSP_PARAMETER_NOT_USED(pvParameters);
/* version get API for FLEX pack information */
R_FSP_VersionGet(&version);
/* Copy GUI settings to application */
network_interface_instance_t ** p_network_instance_list;
uint32_t max_network_instance;
p_network_instance_list = (network_interface_instance_t **) &__freertos_plus_tcp_array_start;
max_network_instance =
(uint32_t) ((uintptr_t) &__freertos_plus_tcp_array_end - (uintptr_t) &__freertos_plus_tcp_array_start) /
sizeof(uintptr_t);
for (uint32_t loop = 0; loop < max_network_instance; loop++)
{
memcpy(ucMACAddress[loop], p_network_instance_list[loop]->pxEther->p_cfg->p_mac_address,
sizeof(ucMACAddress[0]));
memcpy(ucIPAddress[loop], p_network_instance_list[loop]->ucIpv4, sizeof(ucIPAddress[0]));
memcpy(ucNetMask[loop], p_network_instance_list[loop]->ucMask, sizeof(ucNetMask[0]));
memcpy(ucGatewayAddress[loop], p_network_instance_list[loop]->ucGateway, sizeof(ucGatewayAddress[0]));
memcpy(ucDNSServerAddress[loop], p_network_instance_list[loop]->ucDns, sizeof(ucDNSServerAddress[0]));
}
/* Example Project information printed on the RTT */
APP_PRINT(BANNER_INFO,
EP_VERSION,
version.version_id_b.major,
version.version_id_b.minor,
version.version_id_b.patch);
/* Prints the Ethernet Configuration prior to the IP Init*/
APP_PRINT(ETH_PREINIT);
print_ipconfig();
/* FreeRTOS IP Initialization: This init initializes the IP stack */
/* IF the following function should be declared in the NetworkInterface.c
* linked in the project. */
pxFillInterfaceDescriptor(0, &(xInterfaces[0]));
pxFillInterfaceDescriptor(1, &(xInterfaces[1]));
status = FreeRTOS_IPInit_Multi();
if (pdFALSE == status)
{
APP_ERR_PRINT("FreeRTOS_IPInit Failed");
APP_ERR_TRAP(status);
}
APP_PRINT(ETH_POSTINIT);
while (true)
{
/* Check if Both the Ethernet Link and IP link are UP */
if (SUCCESS == isNetworkUp())
{
/* usr_print_ability is added to avoid multiple UP messages or Down Messages repeating*/
if (!(PRINT_UP_MSG_DISABLE & usr_print_ability))
{
uint32_t connection_status;
APP_PRINT("\r\nNetwork is Up");
usr_print_ability |= PRINT_UP_MSG_DISABLE;
usr_print_ability &= (uint32_t) ~PRINT_DOWN_MSG_DISABLE;
if (p_network_instance_list[0]->pxEther->p_cfg->p_ether_phy_instance->p_cfg->channel == 0)
{
connection_status = (R_EMAC0->CXR32 >> 1) & 0x7;
}
else
{
connection_status = (R_EMAC1->CXR32 >> 1) & 0x7;
}
FreeRTOS_OutputARPRequest(FreeRTOS_inet_addr(gp_remote_ip_address));
APP_PRINT("\r\nConnecton: %s\r\n", link_status[connection_status]);
}
if (!(PRINT_NWK_USR_MSG_DISABLE & usr_print_ability))
{
/* Updated IP credentials on to the console */
print_ipconfig();
}
if (!(PRINT_NWK_USR_MSG_DISABLE & usr_print_ability))
{
APP_PRINT(ETH_CHECK_CONNECT);
APP_PRINT("\r\nPinging %s with %d bytes of data:", (char *) gp_remote_ip_address, BYTES_DATA_SEND);
}
while (usr_ping_count < USR_PING_COUNT)
{
/* Send a ICMP Ping request to the requested IP address
* USR_PING_COUNT is used in this Example Project
* For Continuous testing the count can be increased to bigger number
*/
timer_counter = 0;
uint32_t request_num;
request_num = (uint32_t) vSendPing(gp_remote_ip_address);
if (request_num == pdFAIL)
{
/* The ping could not be sent because a network buffer could not be
* obtained within 100ms of FreeRTOS_SendPingRequest() being called. */
ping_data.lost++;
}
else
{
/* The ping was sent. */
ping_data.sent++;
/* Wait 500ms for a reply. */
while ((timer_counter < PING_TIMEOUT) && (ping_status[request_num].status == NO_PING))
{
vTaskDelay(1);
timer_counter++;
}
/* If a ping reply was received?*/
if (ping_status[request_num].status == NO_PING)
{
/* No Ping reply or too long. */
if (timer_counter >= PING_TIMEOUT)
{
ping_data.lost++;
APP_PRINT("\r\nRequest timed out!");
}
}
else
{
/* Was it a reply to the ping just sent? */
if (request_num == ping_status[request_num].id)
{
/* This was a reply to the request just sent. */
ping_data.received++;
switch (ping_status[request_num].status)
{
case PING_SUCCESS:
{
APP_PRINT("\r\nReply from %s: bytes=%d time=%dms",
(char *) gp_remote_ip_address,
BYTES_DATA_SEND,
ping_status[request_num].time);
break;
}
case INVALID_DATA:
{
APP_PRINT("\r\nReply from %s: Invalid Data, time=%dms",
(char *) gp_remote_ip_address,
ping_status[request_num].time);
break;
}
default:
{
break;
}
}
}
}
}
usr_ping_count++;
}
if (!(PRINT_NWK_USR_MSG_DISABLE & usr_print_ability))
{
print_pingResult();
usr_print_ability |= PRINT_NWK_USR_MSG_DISABLE;
}
}
else
{
if (!(PRINT_DOWN_MSG_DISABLE & usr_print_ability))
{
APP_PRINT("\r\nNetwork is Down");
usr_print_ability |= PRINT_DOWN_MSG_DISABLE;
usr_print_ability &= (uint32_t) ~PRINT_UP_MSG_DISABLE;
usr_print_ability &= (uint32_t) ~PRINT_NWK_USR_MSG_DISABLE;
usr_ping_count = RESET_VALUE;
ping_data.sent = RESET_VALUE;
ping_data.received = RESET_VALUE;
ping_data.lost = RESET_VALUE;
memset(ping_status, 0, sizeof(ping_status));
#if (0)
IPStackEvent_t xNetworkDownEvent;
xNetworkDownEvent.eEventType = eNetworkDownEvent;
xSendEventStructToIPTask(&xNetworkDownEvent, 0);
#endif
}
else
{
APP_PRINT(".");
fflush(stdout);
}
}
vTaskDelay(TASK_DELAY_TIME);
}
}
/* Find a maximum time from ping data. */
uint32_t max_time (ping_status_t pings_status[])
{
uint32_t max = RESET_VALUE;
for (uint8_t i = 0; i <= USR_PING_COUNT; i++)
{
if ((pings_status[i].status != NO_PING) && (max < pings_status[i].time))
{
max = pings_status[i].time;
}
}
return max;
}
/* Find a minimum time from ping data. */
uint32_t min_time (ping_status_t pings_status[])
{
uint32_t min = MAX_VALUE_32BITS;
for (uint8_t i = 0; i <= USR_PING_COUNT; i++)
{
if ((pings_status[i].status != NO_PING) && (min > pings_status[i].time))
{
min = pings_status[i].time;
}
}
return min;
}
/* Calculate average time from ping data. */
uint32_t average_time (ping_status_t pings_status[])
{
uint32_t average = 0;
for (uint8_t i = 0; i <= USR_PING_COUNT; i++)
{
if (pings_status[i].status != NO_PING)
{
average += pings_status[i].time;
}
}
average = average / USR_PING_COUNT;
return average;
}
/* Prints the Ping response on to the RTT console */
void print_pingResult (void)
{
APP_PRINT("\r\n\r\nPing Statistics for %s:", gp_remote_ip_address);
APP_PRINT("\r\n Packets: Sent = %02d, Received = %02d, Lost = %d (%d%% loss)\r\n",
ping_data.sent,
ping_data.received,
ping_data.lost,
ping_data.lost * 100 / ping_data.sent);
APP_PRINT("\r\nApproximate round trip times in milli-seconds:");
APP_PRINT("\r\n Maximum = %dms, Minimum = %dms, Average = %dms\r\n",
max_time(ping_status),
min_time(ping_status),
average_time(ping_status));
}
/* Creates and prints the the IP configuration to display on the RTT console */
void print_ipconfig (void)
{
APP_PRINT("\r\nEthernet adapter for Renesas "KIT_NAME ":\r\n");
APP_PRINT("\tDescription . . . . . . . . . . . : Renesas "KIT_NAME " Ethernet\r\n");
APP_PRINT("\tPort 0\r\n");
APP_PRINT("\tPhysical Address. . . . . . . . . : %02x-%02x-%02x-%02x-%02x-%02x\r\n",
ucMACAddress[0][0],
ucMACAddress[0][1],
ucMACAddress[0][2],
ucMACAddress[0][3],
ucMACAddress[0][4],
ucMACAddress[0][5]);
APP_PRINT("\tIPv4 Address. . . . . . . . . . . : %d.%d.%d.%d\r\n",
ucIPAddress[0][0],
ucIPAddress[0][1],
ucIPAddress[0][2],
ucIPAddress[0][3]);
APP_PRINT("\tSubnet Mask . . . . . . . . . . . : %d.%d.%d.%d\r\n",
ucNetMask[0][0],
ucNetMask[0][1],
ucNetMask[0][2],
ucNetMask[0][3]);
APP_PRINT("\tDefault Gateway . . . . . . . . . : %d.%d.%d.%d\r\n",
ucGatewayAddress[0][0],
ucGatewayAddress[0][1],
ucGatewayAddress[0][2],
ucGatewayAddress[0][3]);
APP_PRINT("\tDNS Servers . . . . . . . . . . . : %d.%d.%d.%d\r\n",
ucDNSServerAddress[0][0],
ucDNSServerAddress[0][1],
ucDNSServerAddress[0][2],
ucDNSServerAddress[0][3]);
APP_PRINT("\r\n");
APP_PRINT("\tPort 1\r\n");
APP_PRINT("\tPhysical Address. . . . . . . . . : %02x-%02x-%02x-%02x-%02x-%02x\r\n",
ucMACAddress[1][0],
ucMACAddress[1][1],
ucMACAddress[1][2],
ucMACAddress[1][3],
ucMACAddress[1][4],
ucMACAddress[1][5]);
APP_PRINT("\tIPv4 Address. . . . . . . . . . . : %d.%d.%d.%d\r\n",
ucIPAddress[1][0],
ucIPAddress[1][1],
ucIPAddress[1][2],
ucIPAddress[1][3]);
APP_PRINT("\tSubnet Mask . . . . . . . . . . . : %d.%d.%d.%d\r\n",
ucNetMask[1][0],
ucNetMask[1][1],
ucNetMask[1][2],
ucNetMask[1][3]);
APP_PRINT("\tDefault Gateway . . . . . . . . . : %d.%d.%d.%d\r\n",
ucGatewayAddress[1][0],
ucGatewayAddress[1][1],
ucGatewayAddress[1][2],
ucGatewayAddress[1][3]);
APP_PRINT("\tDNS Servers . . . . . . . . . . . : %d.%d.%d.%d\r\n",
ucDNSServerAddress[1][0],
ucDNSServerAddress[1][1],
ucDNSServerAddress[1][2],
ucDNSServerAddress[1][3]);
}
/* DNS Query for the requested Domain name. Uses the FreeRTOS Client API FreeRTOS_gethostbyname */
void dnsQuerryFunc (char * domain)
{
uint32_t ulIPAddress = RESET_VALUE;
int8_t cBuffer[16] = {RESET_VALUE};
/* Lookup the IP address of the FreeRTOS.org website. */
ulIPAddress = FreeRTOS_gethostbyname(domain);
if (ulIPAddress != 0)
{
/* Convert the IP address to a string. */
FreeRTOS_inet_ntoa(ulIPAddress, (char *) cBuffer);
/* Print out the IP address obtained from the DNS lookup. */
APP_PRINT("\r\nDNS Lookup for \"%s\" is : %s \r\n", domain, cBuffer);
}
else
{
APP_PRINT("\r\nDNS Lookup failed for \"%s\" \r\n", domain);
}
}
/* This Function checks the Network status (Both Ethernet and IP Layer). If the Network is down
* the Application will not send any data on the network.
*/
uint32_t isNetworkUp (void)
{
fsp_err_t eth_link_status[2] = {FSP_ERR_NOT_OPEN, FSP_ERR_NOT_OPEN};
BaseType_t networkUp[2] = {pdFALSE, pdFALSE};
uint32_t network_status = (IP_LINK_UP | ETHERNET_LINK_UP);
network_interface_instance_t ** p_network_instance_list;
uint32_t max_network_instance;
p_network_instance_list = (network_interface_instance_t **) &__freertos_plus_tcp_array_start;
max_network_instance =
(uint32_t) ((uintptr_t) &__freertos_plus_tcp_array_end - (uintptr_t) &__freertos_plus_tcp_array_start) /
sizeof(uintptr_t);
uint32_t loop;
for (loop = 0; loop < max_network_instance; loop++)
{
eth_link_status[loop] = p_network_instance_list[loop]->pxEther->p_api->linkProcess(
p_network_instance_list[loop]->pxEther->p_ctrl);
networkUp[loop] = FreeRTOS_IsEndPointUp(&(p_network_instance_list[loop]->xEndPoint));
}
if ((FSP_SUCCESS == eth_link_status[0]) && (FSP_SUCCESS == eth_link_status[1]) && (pdTRUE == networkUp[0]) &&
(pdTRUE == networkUp[1]))
{
/* Do nothing */
}
else
{
if (FSP_SUCCESS != eth_link_status[0])
{
network_status |= ETHERNET_LINK_DOWN;
}
else if (FSP_SUCCESS == eth_link_status[0])
{
network_status |= ETHERNET_LINK_UP;
}
else
{
/* Do nothing */
}
if (pdTRUE != networkUp[0])
{
network_status |= IP_LINK_DOWN;
}
else if (pdTRUE == networkUp[0])
{
network_status |= IP_LINK_UP;
}
else
{
/* Do nothing */
}
}
return network_status;
}
/* DHCP Hook function to populate the user defined Host name for the Kit. */
#if (ipconfigDHCP_REGISTER_HOSTNAME == 1)
const char * pcApplicationHostnameHook (void)
{
return KIT_NAME;
}
#endif
void vApplicationIPNetworkEventHook (eIPCallbackEvent_t eNetworkEvent)
{
static BaseType_t xTasksAlreadyCreated = pdFALSE;
/* Both eNetworkUp and eNetworkDown events can be processed here. */
if (eNetworkEvent == eNetworkUp)
{
/* Create the tasks that use the TCP/IP stack if they have not already
* been created. */
if (xTasksAlreadyCreated == pdFALSE)
{
/*
* For convenience, tasks that use FreeRTOS-Plus-TCP can be created here
* to ensure they are not created before the network is usable.
*/
xTasksAlreadyCreated = pdTRUE;
}
}
}