Real time embedded FreeRTOS RSS feed 
Homepage FreeRTOS+ Products FreeRTOS Labs Integration Services Contact / Enquiries

FreeRTOS_sendto()

[FreeRTOS Embedded IP Stack API]

FreeRTOS_sockets.h
int32_t FreeRTOS_sendto( xSocket_t xSocket,
                         const void *pvBuffer,
                         size_t xTotalDataLength,
                         uint32_t ulFlags,
                         const struct freertos_sockaddr *pxDestinationAddress,
                         socklen_t xDestinationAddressLength );
		

Send data to a socket. The socket must have already been created by a successful call to FreeRTOS_socket().

This function can be used with standard calling semantics, or zero copy calling semantics:

  • Standard sendto() semantics

    Data is copied from the address pointed to by the pvBuffer parameter into a network buffer allocated internally by the IP stack.

    The standard sendto() semantics are used when the ulFlags parameter does not have the FREERTOS_ZERO_COPY bit set. See the example at the bottom of this page, and other application examples provided on this website.

  • Zero copy sendto() semantics

    The application writer:

    1. Obtains a buffer from the IP stack.
    2. Writes the data to be sent into the buffer obtained from the IP stack.
    3. Uses a pointer to the (already complete) buffer as the pvBuffer parameter.

    The IP stack then passes a reference to the same buffer through the IP stack to the Ethernet driver, where it is transmitted (normally by DMA where the hardware permits).

    The zero copy sendto() semantics are used when the ulFlags parameter has the FREERTOS_ZERO_COPY bit set. See the examples at the bottom of this page, and other application examples provided on this website.

FreeRTOS_sendto() has an optional timeout. The timeout defaults to zero, and is modified using FreeRTOS_setsockopt(). If the send operation cannot queue the bytes for transmission immediately then the calling task will be held in the Blocked state (so that other tasks can execute) until either the bytes can be queued for sending, or the timeout expires. A timeout will occur if:

  • The standard sendto() semantics are used, and the IP stack was not able to obtain a network buffer in time. Or,
  • No space became available on the queue used to send messages to the IP task (see the ipconfigEVENT_QUEUE_LENGTH setting in the FreeRTOSIPConfig.h header file).

If FreeRTOS_sendto() is called on a socket that is not bound to a port number, and the value of ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 in FreeRTOSIPConfig.h, then the IP stack will automatically bind the socket to a port number from the private address range.

FreeRTOS+UDP does not [currently] use all the function parameters. The parameters that are not used are retained in the function's prototype to ensure consistency with the expected standard Berkeley sockets API, and to ensure compatibility with future versions of FreeRTOS+UDP.

Parameters:

xSocket   The handle of the socket to which data is being sent. The socket must have already been created (see FreeRTOS_socket()).

pvBuffer   If the standard calling semantics are being used (the ulFlags parameter does not have the FREERTOS_ZERO_COPY bit set) then pvBuffer points to the source of the data being transmitted. FreeRTOS_sendto() will copy data from pvBuffer into a network buffer inside the IP stack.

If the zero copy calling semantics are being sued (the ulFlags parameter does have the FREERTOS_ZERO_COPY bit set) then pvBuffer points to a buffer that was previously obtained from the IP stack and already contains the data being sent. The IP stack will take control of the buffer rather than copy data out of the buffer.

See the example usage section below, and the application examples provided on this website.

xTotalDataLength   The number of bytes to send.

ulFlags   A bitwise set of options that affect the send operation.

If ulFlags has the FREERTOS_ZERO_COPY bit set, then the function will use the zero copy semantics, otherwise the function will use the standard copy mode semantics. See the description of the pvBuffer parameter above.

Future FreeRTOS+UDP versions may implement other bits.

pxDestinationAddress   A pointer to a freertos_sockaddr structure that contains the destination IP address and port number (the socket the data is being sent to). See the example below.

xDestinationAddressLength   Not currently used, but should be set to sizeof( struct freertos_sockaddr ) to ensure future compatibility.

Returns:

The number of bytes that were actually queue for sending, which will be 0 if an error or timeout occurred.

Note that, because FreeRTOS does not implement errno, the behaviour in the presence of an error is necessarily different to that of sendto() functions that are fully compliant with the expected Berkeley sockets behaviour.

Example usage:

The first example sends to a socket using the standard calling semantics (see below for another example that uses the zero copy calling semantics). The socket is passed in as the function parameter, and is assumed to have already been created using a call to FreeRTOS_socket(). If ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is not set to 1 in FreeRTOSIPConfig.h, then the socket is also assumed to have been bound to a port number using FreeRTOS_bind().


/* FreeRTOS+UDP sockets include */
#define "FreeRTOS_sockets.h"

void vStandardSendExample( xSocket_t xSocket )
{
/* Note - the task stack must be big enough to hold this array!. */
uint8_t ucBuffer[ 128 ];
struct freertos_sockaddr xDestinationAddress;
int32_t iReturned;

    /* Fill in the destination address and port number, which in this case is
    port 1024 on IP address 192.168.0.100. */
    xDestinationAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 100 );
    xDestinationAddress.sin_port = FreeRTOS_htons( 1024 );

    /* The local buffer is filled with the data to be sent, in this case it is
    just filled with 0xff. */
    memset( ucBuffer, 0xff, 128 );

    /* Send the buffer with ulFlags set to 0, so the FREERTOS_ZERO_COPY bit
    is clear. */
    iReturned = FreeRTOS_sendto(
                                    /* The socket being send to. */
                                    xSocket,
                                    /* The data being sent. */
                                    ucBuffer,
                                    /* The length of the data being sent. */
                                    128,
                                    /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */
                                    0,
                                    /* Where the data is being sent. */
                                    &xDestinationAddress,
                                    /* Not used but should be set as shown. */
                                    sizeof( xDestinationAddress )
                               );

    if( iReturned == 128 )
    {
        /* The data was successfully queued for sending.  128 bytes will have
        been copied out of ucBuffer and into a buffer inside the IP stack.
        ucBuffer can be re-used now. */
    }
}
						
Example using FreeRTOS_sendto() with the standard (as opposed to zero copy) calling semantics


This second example sends to a socket using the zero copy calling semantics (see above for an example that uses the standard calling semantics). The socket is passed in as the function parameter, and is assumed to have already been created using a call to FreeRTOS_socket(). If ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is not set to 1 in FreeRTOSIPConfig.h, then the socket is also assumed to have been bound to a port number using FreeRTOS_bind().


/* FreeRTOS+UDP sockets include */
#define "FreeRTOS_sockets.h"

void vZeroCopySendExample( xSocket_t xSocket )
{
struct freertos_sockaddr xDestinationAddress;
uint8_t *pucUDPPayloadBuffer;
int32_t iReturned;

    /* Fill in the destination address and port number, which in this case is
    port 1024 on IP address 192.168.0.100. */
    xDestinationAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 100 );
    xDestinationAddress.sin_port = FreeRTOS_htons( 1024 );

    /* Obtain a buffer from the IP stack that is large enough to hold the data
    being sent.  Although the maximum amount of time to wait for a buffer is passed
    into FreeRTOS_GetUDPPayloadBuffer() as portMAX_DELAY, the actual maximum time
    will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS (defined in
    FreeRTOSIPConfig.h) */
    pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( 128,
                                                                      portMAX_DELAY );
    if( pucUDPPayloadBuffer != NULL )
    {
        /* Write the data being sent directly into the buffer obtained from the
        IP stack.  In this case the data is just set to 0xff. */
        memset( pucUDPPayloadBuffer, 0xff, 128 );

        /* Pass the buffer (by reference) into the IP stack using the zero copy
        semantics.  Ensure to read the remaining source code comments for information
        on managing the pucUDPPayloadBuffer pointer after this call to
        FreeRTOS_sendto(). */
        iReturned = FreeRTOS_sendto(
                                        /* The socket being sent to. */
                                        xSocket,
                                        /* The buffer that already contains the
                                        data being sent. */
                                        &xBufferDescriptor,
                                        /* The length of the data being send. */
                                        128,
                                        /* ulFlags with the FREERTOS_ZERO_COPY bit
                                        set. */
                                        FREERTOS_ZERO_COPY,
                                        /* Where the data is being sent. */
                                        &xDestinationAddress,
                                        /* Not used but should be set as shown. */
                                        sizeof( xDestinationAddress )
                                    );

        if( iReturned != 0 )
        {
            /* The buffer pointed to by pucUDPPayloadBuffer was successfully
            passed (by reference) into the IP stack and is now queued for sending.
            The IP stack is responsible for returning the buffer after it has been
            sent, and pucUDPPayloadBuffer can be used safely in another call to
            FreeRTOS_GetUDPPayloadBuffer(). */
        }
        else
        {
            /* The buffer pointed to by pucUDPPayloadBuffer was not successfully
            passed (by reference) to the IP stack.  To prevent memory and network
            buffer leaks the buffer must be either reused or, as in this case,
            released back to the IP stack. */
            FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
        }
    }
}
						
Example using FreeRTOS_sendto() with the zero copy calling semantics


[ Back to the top ]    [ About FreeRTOS ]    [ FreeRTOS+ Sitemap ]    [ Main FreeRTOS Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.