Hello,
Summary:
- Environnement
- Previous post
- What I want to do
- What I have done
- What my problem is
- Questions
- Code sample
##### ENVIRONMENT #####
Card : STM32H723ZG
PC : Computer with Windows 10
IDE : stm32cubeIDE
Compiler : GCC 9.2.0
FreeRTOS : 202212.01TCP client cannot connect to Pythons TCP server: timeout
##### PREVIOUS POST #####
##### WHAT I WANT TO DO #####
I want to create a TCP connection between an stm32h723zg and a computer running a TCP server in Python.
##### What I have done #####
I was able to make a simple FreeRTOS project with 2 tasks. I then moved to to initializing FreeRTOS plus TCP. I made a server.
Regarding the client part : I created the socket and binded it to a port.
Regarding the PC part in Python : I made a server that waits for a connection and a client that connects by specifying the port and the IP and sends a message. When a client connects to the pyhton server, the server output the infromations of the client (IP and port).
##### What my problem is #####
I am now trying to connect the client to the remote server that I know the IP and port of.
I have tried 3 approaches :
-
Create the socket in the task then call a function to connect then call a function to send data
-
Make it as close as possible from the exemple : TCP Networking Tutorial - Send Data Using a TCP Socket
-
Make it as close as possible to the demo “FreeRTOS_Plus_TCP_Echo_Posix”
For each approaches I went into debug mode and tried to find the issue but I just ended up entering functions after functions and looping inside the same functions without knowing what their purpose was.
This debut method wasn’t very successful, that’s why I added prints everywhere. In the code I share I greatly reduce the amount of prints.
Approach 1
I follow this example to create the task createClientSocket :
I followed this exemple to create the connect function and the send data function (however, I did not create the socket in the send function as I already created it previously) :
When I run it, nothing changes in the console running the TCP server (same for all 3 approaches) and in the Putty terminal I get :
GG : Init successful, starting scheduler. (main.c)
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 56 lowest 56
Link Status is high
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Network buffers: 56 lowest 55
RX descriptors 7/8
vDHCPProcess: offer a012364ip
vDHCPProcess: reply a012364ip
vDHCPProcess: offer a012364ip
vDHCPProcess: acked a012364ip
IP Address: 10.1.35.100
Subnet Mask: 255.255.255.0
Gateway Address: 10.1.35.254
DNS Client Address: 192.168.73.220
GG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 1. (main.c)
GG : Entered prvClientConnectToServer. (main.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
FreeRTOS_connect: 39001 to a012372ip:50053
GG : xSendEventToIPTask started. (FreeRTOS_Sockets.c)
ARP for a012372ip (using a012372ip): rc=0 00:00:00 00:00:00
Coap: current 20320 lowest 20320
meout 1: 500 ms
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Entered "if" : TCPconnectStart succeeded (FreeRTOS_connect FreeRTOS_Sockets.c).
prvSocketSetMSS: 536 bytes for a012372ip:50053
Connect[a012372ip:50053]: next timeout 1: 3000 ms
Connect[a012372ip:50053]: next timeout 2: 6000 ms
Connect[a012372ip:50053]: next timeout 3: 11000 ms
Connect: giving up a012372ip:50053
Move from eCONNECT_SYN to eCLOSE_WAIT
FreeRTOS_connect() stopped due to an error
GG : Client connection to server FAILED. (main.c)
Note that the lines starting by "GG : " are debug prints that I added.
The STM tries to connect but gets timedout.
I tried increasing the network buffer descriptors from 60 to 64 as 56 seemed dangerously close to 55.
I also tried decreasing the Rx Descriptors from 8 to 7 because “RX descriptors 7/8”, in this case, that line change to “RX descriptors 6/7”.
The IP I am trying to connect to is 10.1.35.114 which in hexa is 0x0a012364 and we can read a012364ip. It seemed the initial 0 is missing but I don’t think it is the issue.
Approach 2
I tried to make it as close as possible to the send data exemple because they do eevrything inside a function.
Here is the putty output I get :
GG : Init successful, starting scheduler. (main.c)
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 56 lowest 56
Link Status is high
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Network buffers: 56 lowest 55
RX descriptors 7/8
vDHCPProcess: offer a012364ip
vDHCPProcess: reply a012364ip
vDHCPProcess: offer a012364ip
vDHCPProcess: acked a012364ip
IP Address: 10.1.35.100
Subnet Mask: 255.255.255.0
Gateway Address: 10.1.35.254
DNS Client Address: 192.168.73.220
GG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 2. (main.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
Here it didn’t even try to connect.
Approach 3
I tried to make it as close as possible to the demo example (that I did not implement by itself. The whole process seemed weird is it is quite different than my first approach like they are using win, they are setting the IP as static (while I have to use DHCP).
It basicaly gave me the same results as the first approach :
GG : Init successful, starting scheduler. (main.c)
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Link Status is high
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Network buffers: 60 lowest 59
RX descriptors 7/8
vDHCPProcess: offer a012364ip
vDHCPProcess: reply a012364ip
vDHCPProcess: offer a012364ip
vDHCPProcess: acked a012364ip
IP Address: 10.1.35.100
Subnet Mask: 255.255.255.0
Gateway Address: 10.1.35.254
DNS Client Address: 192.168.73.220
GG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 3. (main.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
Note that I did not copy apste everything because the call to the connect function is inside a for( ; ; ) so we get the same prints all the time.
Note also that I changed the FreeRTOSIPConfig.h file to the one given in the demo, making sure to set USETCP and USEDHCP to 1.
##### QUESTION #####
Project download : Download files - Filemail
Is there an obvious mistake I made?
What is causing the stm32 to not be able to connect (timeout)?
##### CODE SAMPLE #####
To test the different approaches you have to change GG_CLIENT_TEST to either 1, 2 or 3 in the FreeRTOSIPConfig.h file.
Project download : Download files - Filemail
FreeRTOSIPConfig.h (note that there is both my config and the demo config):
#ifndef FREERTOS_IP_CONFIG_H
#define FREERTOS_IP_CONFIG_H
#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
#define GG_CLIENT_TEST 3
// Config from the demo
/*
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 )
#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 )
#define ipconfigUSE_DNS_CACHE ( 1 )
#define ipconfigDNS_CACHE_NAME_LENGTH ( 16 )
#define ipconfigDNS_CACHE_ENTRIES ( 4 )
#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 )
#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 )
extern UBaseType_t uxRand();
#define ipconfigRAND32() uxRand()
#define ipconfigUSE_NETWORK_EVENT_HOOK 1
#define ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS pdMS_TO_TICKS( 2500U ) //For a DNS lookup, it is important to set the following config items:
#define ipconfigDNS_SEND_BLOCK_TIME_TICKS pdMS_TO_TICKS( 2500U ) // source : https://forums.freertos.org/t/failed-to-connect-to-server-freertos-connect-failed-returncode-116-freertos-tcp/15620/11
#define ipconfigUSE_DHCP 1
#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS )
#define ipconfigARP_CACHE_ENTRIES 6
#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
#define ipconfigMAX_ARP_AGE 150
#define ipconfigINCLUDE_FULL_INET_ADDR 1
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60
#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
#define ipconfigUDP_TIME_TO_LIVE 128
#define ipconfigTCP_TIME_TO_LIVE 128
#define ipconfigUSE_TCP 1
#define ipconfigUSE_TCP_WIN 0 //win
#define ipconfigNETWORK_MTU 1200U
#define ipconfigUSE_DNS 0
#define ipconfigREPLY_TO_INCOMING_PINGS 1
#define ipconfigSUPPORT_OUTGOING_PINGS 0
#define ipconfigSUPPORT_SELECT_FUNCTION 1
#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS )
#define ipconfigPACKET_FILLER_SIZE 2U
#define ipconfigTCP_WIN_SEG_COUNT 240
#define ipconfigTCP_RX_BUFFER_LENGTH ( 1000 )
#define ipconfigTCP_TX_BUFFER_LENGTH ( 1000 )
#define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL )
#define ipconfigTCP_HANG_PROTECTION ( 1 )
#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 )
#define ipconfigTCP_KEEP_ALIVE ( 1 )
#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 )//in seconds
#define portINLINE __inline
*/
// My own config
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 64 //a small number, idk how small...
#define ipconfigUSE_NETWORK_EVENT_HOOK 1 // If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the network event hook at the appropriate times
#define ipconfigZERO_COPY_RX_DRIVER 1
#define ipconfigZERO_COPY_TX_DRIVER 1
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
#define ipconfigUSE_NETWORK_EVENT_HOOK 1
#define ipconfigDNS_USE_CALLBACKS 1
#define ipconfigDNS_CACHE_NAME_LENGTH 20
#define ipconfigUSE_TCP 1 //if 0, use UDP by default
#define ipconfigTCP_KEEP_ALIVE 0 //If FreeRTOS-Plus-TCP does not receive a reply to a keep alive message then the connection will be broken
#define ipconfigTCP_HANG_PROTECTION 1 //will mark a socket as closed if there is no status change on the socket
#define ipconfigTCP_HANG_PROTECTION_TIME 60 //within the period of time specified in seconds
#define ipconfigUSE_TCP_WIN 0 //If you have a tiny CPU with less than 64KB of RAM, do not use sliding Windows
//define below based on freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration_Examples.html
#define ipconfigTCP_TX_BUFFER_LENGTH ( 2 * ipconfigTCP_MSS )
#define ipconfigTCP_RX_BUFFER_LENGTH ( 2 * ipconfigTCP_MSS )
#define ipconfigNETWORK_MTU 586
#define ipconfigTCP_MSS 522
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 // Should allow freertos to select a working port if no one is given
#define ipconfigHAS_PRINTF 1
#define FreeRTOS_debug_printf( x ) printf x
#define FreeRTOS_printf( x ) printf x
#endif /* FREERTOS_IP_CONFIG_H */
main.c :
/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <ctype.h>
/* cubeMX/HAL includes */
#include "main.h"
#include "string.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_DHCP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "phyHandling.h"
#if( ipconfigMULTI_INTERFACE != 0 )
#include "FreeRTOS_Routing.h"
#include "FreeRTOS_ND.h"
#endif
/* Macro to check if socket is bound, copy pasted from FreeRTOS_Socket.c */
#define socketSOCKET_IS_BOUND( pxSocket ) ( listLIST_ITEM_CONTAINER( &( pxSocket )->xBoundSocketListItem ) != NULL )
#define usUsedStackSize 128
#define BUFFER_SIZE 512
/* cube mx generated handler */
ETH_HandleTypeDef heth;
UART_HandleTypeDef huart3;
ETH_TxPacketConfig TxConfig;
/* The MAC address array is not declared const as the MAC address will
normally be read from an EEPROM and not hard coded (in real deployed applications).*/
static uint8_t ucMACAddress[ 6 ] = { 0x00, 0x80, 0xE1, 0x00, 0x00, 0x00 };
/* Define the network addressing. These parameters will be used if either
ipconfigUDE_DHCP is 0 or if ipconfigUSE_DHCP is 1 but DHCP auto configuration failed. */
static const uint8_t ucIPAddress[ 4 ];
static const uint8_t ucNetMask[ 4 ];
static const uint8_t ucGatewayAddress[ 4 ];
/* The following is the address of the DNS client. */
static const uint8_t ucDNSClientAddress[ 4 ] = { 192, 168, 73, 220 };
/* Random Number Generator variable. */
static RNG_HandleTypeDef hrng;
/* cube MX generated function definitions */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USB_OTG_HS_USB_Init(void);
static void MX_RNG_Init(void);
/* TCP function definition */
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent );
BaseType_t xApplicationGetRandomNumber( uint32_t *pulValue );
void prvClientConnectToServer(Socket_t xSocket);
void prvClientSendData(Socket_t xSocket);
void vTCPSend(void);
/* TCP task function definitions (the ones that do tcp thing */
static void vCreateTCPClientSocket(void *pvParameters);
/* Functions */
int main(void)
{
/* cube mx init */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART3_UART_Init();
MX_USB_OTG_HS_USB_Init();
/*Rng init*/
MX_RNG_Init();
/* TCP init */
FreeRTOS_IPInit(ucIPAddress,
ucNetMask,
ucGatewayAddress,
ucDNSClientAddress,
ucMACAddress );
/* task creation */
NVIC_EnableIRQ(ETH_IRQn);
NVIC_SetPriority(ETH_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
/* starting rtos scheduler */
FreeRTOS_printf( ( "\033[2J") ); /* Clean putty */
FreeRTOS_printf( ( "\r\nGG : Init successful, starting scheduler. (main.c)\r\n") );
vTaskStartScheduler();
}
static void vCreateTCPClientSocket(void *pvParameters)
{
#if GG_CLIENT_TEST == 1 //create socket in task then call function to connect then call function to send data
/* Variables */
struct freertos_sockaddr xClient, xRemoteAddress;
Socket_t xClientSocket;
socklen_t xSize = sizeof( xClient );
static const TickType_t xTimeOut = portMAX_DELAY;
FreeRTOS_printf(("\tGG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 1. (main.c)\r\n"));
/* Socket creation. */
xClientSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP); /* Attempt to open the socket. */
configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); /* Check the socket was created. */
/* Binding (not necessary) */
xClient.sin_port = FreeRTOS_htons(585); // en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
FreeRTOS_bind(xClientSocket, &xClient, xSize);
/* Set a time out so accept() will just wait for a connection. */
FreeRTOS_setsockopt(xClientSocket, 0, FREERTOS_SO_RCVTIMEO, &xTimeOut, sizeof(xTimeOut));
FreeRTOS_setsockopt(xClientSocket, 0, FREERTOS_SO_SNDTIMEO, &xTimeOut, sizeof(xTimeOut));
/*Function to connect to the server */
prvClientConnectToServer(xClientSocket);
#elif GG_CLIENT_TEST == 2 //make it as close as the example from the website : freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial_Sending_TCP_Data.html
/* Variables */
Socket_t xSocket;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
// unused TaskHandle_t xRxTask = NULL;
size_t xLenToSend;
/* The 2 variables below are parameters of the function in the example but I don't use this code as a function so I have to init them */
char *pcBufferToTransmit = "Hey buddy!";
const size_t xTotalLengthToSend = 10;
FreeRTOS_printf(("\tGG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 2. (main.c)\r\n"));
/* Set the IP address and port of the remote socket to which this client socket will transmit. */
xRemoteAddress.sin_port = FreeRTOS_htons(50053);
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);
/* Create a socket. */
xSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
configASSERT(xSocket != FREERTOS_INVALID_SOCKET);
/* Connect to the remote socket. The socket has not previously been bound to a local port number so will get automatically bound. */
if( FreeRTOS_connect(xSocket, &xRemoteAddress, sizeof(xRemoteAddress)) == 0)
{
while(xAlreadyTransmitted < xTotalLengthToSend) /* Keep sending until the entire buffer has been sent. */
{
xLenToSend = xTotalLengthToSend - xAlreadyTransmitted; /* How many bytes are left to send? */
xBytesSent = FreeRTOS_send(xSocket, &(pcBufferToTransmit[xAlreadyTransmitted]), xLenToSend, 0);
if(xBytesSent >= 0) xAlreadyTransmitted += xBytesSent;
else break;
}
}
/* Initiate graceful shutdown. */
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );
/* Wait for the socket to disconnect gracefully before closing the socket. */
while(FreeRTOS_recv(xSocket, pcBufferToTransmit, xTotalLengthToSend, 0) >= 0)
{
vTaskDelay(pdMS_TO_TICKS(250)); /* Wait for shutdown to complete. */
/* Note - real applications should implement a timeout here, not just loop forever. */
}
/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket(xSocket);
#elif GG_CLIENT_TEST == 3 //everything in a single task (like the demo)
/* Variables */
struct freertos_sockaddr xRemoteAddress;
Socket_t xClientSocket;
BaseType_t ret;
FreeRTOS_printf(("\tGG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 3. (main.c)\r\n"));
/* Set the IP address and port*/
xRemoteAddress.sin_port = FreeRTOS_htons(50053);
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);
for(;;)
{
/* Socket creation. */
xClientSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP); /* Attempt to open the socket. */
configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); /* Check the socket was created. */
ret = FreeRTOS_connect(xClientSocket, &xRemoteAddress, sizeof(xRemoteAddress));
if( ret == 0 ) FreeRTOS_printf(("GG : Client connection to server. (main.c)\r\n"));
}
#else
#error Unsupported choice setting
#endif /* end #if GG_CLIENT_TEST */
}
void prvClientConnectToServer(Socket_t xSocket) /* case 1 */
{
struct freertos_sockaddr xRemoteAddress;
FreeRTOS_printf(("\n\tGG : Entered prvClientConnectToServer. (main.c)\r\n"));
/* Set the IP address and port*/
xRemoteAddress.sin_port = FreeRTOS_htons(50053);
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);
if( FreeRTOS_connect(xSocket, &xRemoteAddress, sizeof(xRemoteAddress)) == 0)
{
FreeRTOS_printf(("GG : Client connection to server successful. (main.c)\r\n"));
prvClientSendData(xSocket);
}
else FreeRTOS_printf(("GG : Client connection to server FAILED. (main.c)\r\n"));
}
void prvClientSendData(Socket_t xSocket) /* case 1 */
{
//struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
size_t xLenToSend;
char *pcBufferToTransmit = "Hey buddy!";
const size_t xTotalLengthToSend = 10;
FreeRTOS_printf(("\tGG : Entered prvClientSendData. (main.c)\r\n"));
/* Ensure termination */
//pcBufferToTransmit[xTotalLengthToSend] = '\0';
if( !socketSOCKET_IS_BOUND( xSocket ) ) /* if client socket had already be bound (bind) we can continue */
{ FreeRTOS_printf(("GG : rtos connected. (main.c)\r\n"));
/* Keep sending until the entire buffer has been sent. */
while(xAlreadyTransmitted < xTotalLengthToSend)
{ FreeRTOS_printf(("GG : entered while. (main.c)\r\n"));
/* How many bytes are left to send? */
xLenToSend = xTotalLengthToSend - xAlreadyTransmitted;
xBytesSent = FreeRTOS_send(/* The socket being sent to. */
xSocket,
/* The data being sent. */
&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
/* The remaining length of data to send. */
xLenToSend,
/* ulFlags. */
0 );
if( xBytesSent >= 0 )
{ /* Data was sent successfully. */
xAlreadyTransmitted += xBytesSent;
}
else
{ /* Error - break out of the loop for graceful socket close. */
break;
}
}
}
FreeRTOS_printf(("GG : Done transmiting, starting clean exit. (main.c)\r\n"));
/* Initiate graceful shutdown. */
FreeRTOS_shutdown(xSocket, FREERTOS_SHUT_RDWR);
/* Wait for the socket to disconnect gracefully before closing the socket. */
while( FreeRTOS_recv(xSocket, pcBufferToTransmit, xTotalLengthToSend, 0) >= 0)
{
/* Wait for shutdown to complete. */
vTaskDelay(pdMS_TO_TICKS(250));
/* Note - real applications should implement a timeout here, not just
loop forever. */
}
/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket( xSocket );
FreeRTOS_printf(("GG : Clean exit finished. (main.c)\r\n"));
}
void vTCPSend(void)
{
Socket_t xSocket;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
TaskHandle_t xRxTask = NULL;
size_t xLenToSend;
FreeRTOS_printf(("\tGG : Entered vTCPSend. (main.c)\r\n"));
char *pcBufferToTransmit = "Hey buddy!";
const size_t xTotalLengthToSend = 10;
/* Set the IP address and port of the remote socket to which this client socket will transmit. */
xRemoteAddress.sin_port = FreeRTOS_htons( 50053 );
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);
/* Create a socket. */
xSocket = FreeRTOS_socket( FREERTOS_AF_INET,
FREERTOS_SOCK_STREAM,/* FREERTOS_SOCK_STREAM for TCP. */
FREERTOS_IPPROTO_TCP );
FreeRTOS_printf(("GG : Testing config assert.\r\n"));
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
FreeRTOS_printf(("GG : Config assert passed, creating connection. (main.c)\r\n"));
/* Connect to the remote socket. The socket has not previously been bound to
a local port number so will get automatically bound to a local port inside
the FreeRTOS_connect() function. */
if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
{
FreeRTOS_printf(("GG : Connection successful. (main.c)\r\n"));
/* Keep sending until the entire buffer has been sent. */
while( xAlreadyTransmitted < xTotalLengthToSend )
{
/* How many bytes are left to send? */
xLenToSend = xTotalLengthToSend - xAlreadyTransmitted;
xBytesSent = FreeRTOS_send( /* The socket being sent to. */
xSocket,
/* The data being sent. */
&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
/* The remaining length of data to send. */
xLenToSend,
/* ulFlags. */
0 );
if( xBytesSent >= 0 )
{
/* Data was sent successfully. */
xAlreadyTransmitted += xBytesSent;
}
else
{
/* Error - break out of the loop for graceful socket close. */
break;
}
}
}
else FreeRTOS_printf(("GG : Connection failed. (main.c)\r\n"));
/* Initiate graceful shutdown. */
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );
/* Wait for the socket to disconnect gracefully (indicated by FreeRTOS_recv()
returning a -pdFREERTOS_ERRNO_EINVAL error) before closing the socket. */
while( FreeRTOS_recv( xSocket, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 )
{
/* Wait for shutdown to complete. If a receive block time is used then
this delay will not be necessary as FreeRTOS_recv() will place the RTOS task
into the Blocked state anyway. */
vTaskDelay( pdMS_TO_TICKS( 250 ) );
/* Note - real applications should implement a timeout here, not just
loop forever. */
}
/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket( xSocket );
}
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
static BaseType_t xTasksAlreadyCreated = pdFALSE;
uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSClientAddress;
char cBuffer[ 16 ];
/* 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.
*/
xTaskCreate(vCreateTCPClientSocket,
"clientSocket",
usUsedStackSize,
NULL,
tskIDLE_PRIORITY,
NULL);
xTasksAlreadyCreated = pdTRUE;
//xIPTaskInitialised = pdTRUE;
}
FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSClientAddress );
FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );
FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );
FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );
FreeRTOS_inet_ntoa( ulDNSClientAddress, cBuffer );
FreeRTOS_printf( ( "DNS Client Address: %s\r\n\r\n\r\n", cBuffer ) );
}
}
/* Random Number Generator function*/
BaseType_t xApplicationGetRandomNumber( uint32_t *pulValue )
{
HAL_StatusTypeDef xResult;
BaseType_t xReturn;
uint32_t ulValue;
xResult = HAL_RNG_GenerateRandomNumber( &hrng, &ulValue );
if( xResult == HAL_OK )
{
xReturn = pdPASS;
*pulValue = ulValue;
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/**
* @brief RNG Initialization Function
* @param None
* @retval None
*/
static void MX_RNG_Init(void)
{
hrng.Instance = RNG;
//hrng.Init.ClockErrorDetection = RNG_CED_ENABLE;
if (HAL_RNG_Init(&hrng) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 275;
RCC_OscInitStruct.PLL.PLLP = 1;
RCC_OscInitStruct.PLL.PLLQ = 4;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART3 Initialization Function
* @param None
* @retval None
*/
static void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USB_OTG_HS Initialization Function
* @param None
* @retval None
*/
static void MX_USB_OTG_HS_USB_Init(void)
{
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED_GREEN_Pin|LED_RED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(USB_FS_PWR_EN_GPIO_Port, USB_FS_PWR_EN_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED_YELLOW_GPIO_Port, LED_YELLOW_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LED_GREEN_Pin LED_RED_Pin */
GPIO_InitStruct.Pin = LED_GREEN_Pin|LED_RED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : USB_FS_PWR_EN_Pin */
GPIO_InitStruct.Pin = USB_FS_PWR_EN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(USB_FS_PWR_EN_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : USB_FS_OVCR_Pin */
GPIO_InitStruct.Pin = USB_FS_OVCR_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_FS_OVCR_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : USB_FS_VBUS_Pin */
GPIO_InitStruct.Pin = USB_FS_VBUS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_FS_VBUS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : USB_FS_ID_Pin */
GPIO_InitStruct.Pin = USB_FS_ID_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
HAL_GPIO_Init(USB_FS_ID_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : LED_YELLOW_Pin */
GPIO_InitStruct.Pin = LED_YELLOW_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_YELLOW_GPIO_Port, &GPIO_InitStruct);
}
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM1 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* @param htim : TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM1) {
HAL_IncTick();
}
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
int _write(int file, char *ptr, int len)
{
HAL_UART_Transmit(&huart3, ( const uint8_t * ) ptr, len, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart3, "\r", 1, HAL_MAX_DELAY);
return len;
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Thank you for reading me.
I will bring my computer home to be able to answer you.
Regards
Gaetan