POSIX code/demo initial commit.
This was the code we uploaded to freertos.org for 2018's reinvent. The todos for this version: - Take out unnecessary demos and source files. This repo should only have POSIX source files, FreeRTOS files, Windows port, and demo project.
This commit is contained in:
commit
7fc9c915eb
353
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c
Executable file
353
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c
Executable file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_TCP_server.h"
|
||||
#include "FreeRTOS_server_private.h"
|
||||
|
||||
/* Remove the entire file if TCP is not being used. */
|
||||
#if( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) )
|
||||
|
||||
#if !defined( ARRAY_SIZE )
|
||||
#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
|
||||
#endif
|
||||
|
||||
|
||||
static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket );
|
||||
static char *strnew( const char *pcString );
|
||||
/* Remove slashes at the end of a path. */
|
||||
static void prvRemoveSlash( char *pcDir );
|
||||
|
||||
TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount )
|
||||
{
|
||||
TCPServer_t *pxServer;
|
||||
SocketSet_t xSocketSet;
|
||||
|
||||
/* Create a new server.
|
||||
xPort / xPortAlt : Make the service available on 1 or 2 public port numbers. */
|
||||
xSocketSet = FreeRTOS_CreateSocketSet();
|
||||
|
||||
if( xSocketSet != NULL )
|
||||
{
|
||||
BaseType_t xSize;
|
||||
|
||||
xSize = sizeof( *pxServer ) - sizeof( pxServer->xServers ) + xCount * sizeof( pxServer->xServers[ 0 ] );
|
||||
|
||||
pxServer = ( TCPServer_t * ) pvPortMallocLarge( xSize );
|
||||
if( pxServer != NULL )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
BaseType_t xNoTimeout = 0;
|
||||
BaseType_t xIndex;
|
||||
|
||||
memset( pxServer, '\0', xSize );
|
||||
pxServer->xServerCount = xCount;
|
||||
pxServer->xSocketSet = xSocketSet;
|
||||
|
||||
for( xIndex = 0; xIndex < xCount; xIndex++ )
|
||||
{
|
||||
BaseType_t xPortNumber = pxConfigs[ xIndex ].xPortNumber;
|
||||
|
||||
if( xPortNumber > 0 )
|
||||
{
|
||||
Socket_t xSocket;
|
||||
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
FreeRTOS_printf( ( "TCP socket on port %d\n", ( int )xPortNumber ) );
|
||||
|
||||
if( xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
xAddress.sin_addr = FreeRTOS_GetIPAddress(); // Single NIC, currently not used
|
||||
xAddress.sin_port = FreeRTOS_htons( xPortNumber );
|
||||
|
||||
FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSocket, pxConfigs[ xIndex ].xBackLog );
|
||||
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
|
||||
|
||||
#if( ipconfigHTTP_RX_BUFSIZE > 0 )
|
||||
{
|
||||
if( pxConfigs[ xIndex ].eType == eSERVER_HTTP )
|
||||
{
|
||||
WinProperties_t xWinProps;
|
||||
|
||||
memset( &xWinProps, '\0', sizeof( xWinProps ) );
|
||||
/* The parent socket itself won't get connected. The properties below
|
||||
will be inherited by each new child socket. */
|
||||
xWinProps.lTxBufSize = ipconfigHTTP_TX_BUFSIZE;
|
||||
xWinProps.lTxWinSize = ipconfigHTTP_TX_WINSIZE;
|
||||
xWinProps.lRxBufSize = ipconfigHTTP_RX_BUFSIZE;
|
||||
xWinProps.lRxWinSize = ipconfigHTTP_RX_WINSIZE;
|
||||
|
||||
/* Set the window and buffer sizes. */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
FreeRTOS_FD_SET( xSocket, xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
|
||||
pxServer->xServers[ xIndex ].xSocket = xSocket;
|
||||
pxServer->xServers[ xIndex ].eType = pxConfigs[ xIndex ].eType;
|
||||
pxServer->xServers[ xIndex ].pcRootDir = strnew( pxConfigs[ xIndex ].pcRootDir );
|
||||
prvRemoveSlash( ( char * ) pxServer->xServers[ xIndex ].pcRootDir );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Could not allocate the server, delete the socket set */
|
||||
FreeRTOS_DeleteSocketSet( xSocketSet );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Could not create a socket set, return NULL */
|
||||
pxServer = NULL;
|
||||
}
|
||||
|
||||
return pxServer;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket )
|
||||
{
|
||||
TCPClient_t *pxClient = NULL;
|
||||
BaseType_t xSize = 0;
|
||||
FTCPWorkFunction fWorkFunc = NULL;
|
||||
FTCPDeleteFunction fDeleteFunc = NULL;
|
||||
const char *pcType = "Unknown";
|
||||
|
||||
/*_RB_ Can the work and delete functions be part of the xSERVER_CONFIG structure
|
||||
becomes generic, with no pre-processing required? */
|
||||
#if( ipconfigUSE_HTTP != 0 )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].eType == eSERVER_HTTP )
|
||||
{
|
||||
xSize = sizeof( HTTPClient_t );
|
||||
fWorkFunc = xHTTPClientWork;
|
||||
fDeleteFunc = vHTTPClientDelete;
|
||||
pcType = "HTTP";
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_HTTP != 0 */
|
||||
|
||||
#if( ipconfigUSE_FTP != 0 )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].eType == eSERVER_FTP )
|
||||
{
|
||||
xSize = sizeof( FTPClient_t );
|
||||
fWorkFunc = xFTPClientWork;
|
||||
fDeleteFunc = vFTPClientDelete;
|
||||
pcType = "FTP";
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_FTP != 0 */
|
||||
|
||||
/* Malloc enough space for a new HTTP-client */
|
||||
if( xSize )
|
||||
{
|
||||
pxClient = ( TCPClient_t* ) pvPortMallocLarge( xSize );
|
||||
}
|
||||
|
||||
if( pxClient != NULL )
|
||||
{
|
||||
memset( pxClient, '\0', xSize );
|
||||
|
||||
/* Put the new client in front of the list. */
|
||||
pxClient->eType = pxServer->xServers[ xIndex ].eType;
|
||||
pxClient->pcRootDir = pxServer->xServers[ xIndex ].pcRootDir;
|
||||
pxClient->pxParent = pxServer;
|
||||
pxClient->xSocket = xNexSocket;
|
||||
pxClient->pxNextClient = pxServer->pxClients;
|
||||
pxClient->fWorkFunction = fWorkFunc;
|
||||
pxClient->fDeleteFunction = fDeleteFunc;
|
||||
pxServer->pxClients = pxClient;
|
||||
|
||||
FreeRTOS_FD_SET( xNexSocket, pxServer->xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
|
||||
}
|
||||
else
|
||||
{
|
||||
pcType = "closed";
|
||||
FreeRTOS_closesocket( xNexSocket );
|
||||
}
|
||||
{
|
||||
struct freertos_sockaddr xRemoteAddress;
|
||||
FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress );
|
||||
FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, (unsigned)FreeRTOS_ntohl( xRemoteAddress.sin_addr ) ) );
|
||||
}
|
||||
|
||||
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
|
||||
( void ) pcType;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime )
|
||||
{
|
||||
TCPClient_t **ppxClient;
|
||||
BaseType_t xIndex;
|
||||
BaseType_t xRc;
|
||||
|
||||
/* Let the server do one working cycle */
|
||||
xRc = FreeRTOS_select( pxServer->xSocketSet, xBlockingTime );
|
||||
|
||||
if( xRc != 0 )
|
||||
{
|
||||
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
Socket_t xNexSocket;
|
||||
socklen_t xSocketLength;
|
||||
|
||||
if( pxServer->xServers[ xIndex ].xSocket == FREERTOS_NO_SOCKET )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
xSocketLength = sizeof( xAddress );
|
||||
xNexSocket = FreeRTOS_accept( pxServer->xServers[ xIndex ].xSocket, &xAddress, &xSocketLength);
|
||||
|
||||
if( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) )
|
||||
{
|
||||
prvReceiveNewClient( pxServer, xIndex, xNexSocket );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ppxClient = &pxServer->pxClients;
|
||||
|
||||
while( ( * ppxClient ) != NULL )
|
||||
{
|
||||
TCPClient_t *pxThis = *ppxClient;
|
||||
|
||||
/* Almost C++ */
|
||||
xRc = pxThis->fWorkFunction( pxThis );
|
||||
|
||||
if (xRc < 0 )
|
||||
{
|
||||
*ppxClient = pxThis->pxNextClient;
|
||||
/* Close handles, resources */
|
||||
pxThis->fDeleteFunction( pxThis );
|
||||
/* Free the space */
|
||||
vPortFreeLarge( pxThis );
|
||||
}
|
||||
else
|
||||
{
|
||||
ppxClient = &( pxThis->pxNextClient );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static char *strnew( const char *pcString )
|
||||
{
|
||||
BaseType_t xLength;
|
||||
char *pxBuffer;
|
||||
|
||||
xLength = strlen( pcString ) + 1;
|
||||
pxBuffer = ( char * ) pvPortMalloc( xLength );
|
||||
if( pxBuffer != NULL )
|
||||
{
|
||||
memcpy( pxBuffer, pcString, xLength );
|
||||
}
|
||||
|
||||
return pxBuffer;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvRemoveSlash( char *pcDir )
|
||||
{
|
||||
BaseType_t xLength = strlen( pcDir );
|
||||
|
||||
while( ( xLength > 0 ) && ( pcDir[ xLength - 1 ] == '/' ) )
|
||||
{
|
||||
pcDir[ --xLength ] = '\0';
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
|
||||
/* FreeRTOS_TCPServerWork() calls select().
|
||||
The two functions below provide a possibility to interrupt
|
||||
the call to select(). After the interruption, resume
|
||||
by calling FreeRTOS_TCPServerWork() again. */
|
||||
BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
BaseType_t xResult = pdFALSE;
|
||||
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
FreeRTOS_SignalSocket( pxServer->xServers[ xIndex ].xSocket );
|
||||
xResult = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
|
||||
#endif /* ipconfigSUPPORT_SIGNALS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
|
||||
/* Same as above: this function may be called from an ISR,
|
||||
for instance a GPIO interrupt. */
|
||||
BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
BaseType_t xResult = pdFALSE;
|
||||
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
|
||||
{
|
||||
if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
FreeRTOS_SignalSocketFromISR( pxServer->xServers[ xIndex ].xSocket, pxHigherPriorityTaskWoken );
|
||||
xResult = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
#endif /* ipconfigSUPPORT_SIGNALS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) */
|
74
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c
Executable file
74
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c
Executable file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_FTP_commands.h"
|
||||
|
||||
const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ] =
|
||||
{
|
||||
/* cmdLen cmdName[7] cmdType checkLogin checkNullArg */
|
||||
{ 4, "USER", ECMD_USER, pdFALSE, pdFALSE },
|
||||
{ 4, "PASS", ECMD_PASS, pdFALSE, pdFALSE },
|
||||
{ 4, "ACCT", ECMD_ACCT, pdTRUE, pdFALSE },
|
||||
{ 3, "CWD", ECMD_CWD, pdTRUE, pdTRUE },
|
||||
{ 4, "CDUP", ECMD_CDUP, pdTRUE, pdFALSE },
|
||||
{ 4, "SMNT", ECMD_SMNT, pdTRUE, pdFALSE },
|
||||
{ 4, "QUIT", ECMD_QUIT, pdTRUE, pdFALSE },
|
||||
{ 4, "REIN", ECMD_REIN, pdTRUE, pdFALSE },
|
||||
{ 4, "PORT", ECMD_PORT, pdTRUE, pdFALSE },
|
||||
{ 4, "PASV", ECMD_PASV, pdTRUE, pdFALSE },
|
||||
{ 4, "TYPE", ECMD_TYPE, pdTRUE, pdFALSE },
|
||||
{ 4, "STRU", ECMD_STRU, pdTRUE, pdFALSE },
|
||||
{ 4, "MODE", ECMD_MODE, pdTRUE, pdFALSE },
|
||||
{ 4, "RETR", ECMD_RETR, pdTRUE, pdTRUE },
|
||||
{ 4, "STOR", ECMD_STOR, pdTRUE, pdTRUE },
|
||||
{ 4, "STOU", ECMD_STOU, pdTRUE, pdFALSE },
|
||||
{ 4, "APPE", ECMD_APPE, pdTRUE, pdFALSE },
|
||||
{ 4, "ALLO", ECMD_ALLO, pdTRUE, pdFALSE },
|
||||
{ 4, "REST", ECMD_REST, pdTRUE, pdFALSE },
|
||||
{ 4, "RNFR", ECMD_RNFR, pdTRUE, pdTRUE },
|
||||
{ 4, "RNTO", ECMD_RNTO, pdTRUE, pdTRUE },
|
||||
{ 4, "ABOR", ECMD_ABOR, pdTRUE, pdFALSE },
|
||||
{ 4, "SIZE", ECMD_SIZE, pdTRUE, pdTRUE },
|
||||
{ 4, "MDTM", ECMD_MDTM, pdTRUE, pdTRUE },
|
||||
{ 4, "DELE", ECMD_DELE, pdTRUE, pdTRUE },
|
||||
{ 3, "RMD", ECMD_RMD, pdTRUE, pdTRUE },
|
||||
{ 3, "MKD", ECMD_MKD, pdTRUE, pdTRUE },
|
||||
{ 3, "PWD", ECMD_PWD, pdTRUE, pdFALSE },
|
||||
{ 4, "LIST", ECMD_LIST, pdTRUE, pdFALSE },
|
||||
{ 4, "NLST", ECMD_NLST, pdTRUE, pdFALSE },
|
||||
{ 4, "SITE", ECMD_SITE, pdTRUE, pdFALSE },
|
||||
{ 4, "SYST", ECMD_SYST, pdFALSE, pdFALSE },
|
||||
{ 4, "FEAT", ECMD_FEAT, pdFALSE, pdFALSE },
|
||||
{ 4, "STAT", ECMD_STAT, pdTRUE, pdFALSE },
|
||||
{ 4, "HELP", ECMD_HELP, pdFALSE, pdFALSE },
|
||||
{ 4, "NOOP", ECMD_NOOP, pdFALSE, pdFALSE },
|
||||
{ 4, "EMPT", ECMD_EMPTY, pdFALSE, pdFALSE },
|
||||
{ 4, "CLOS", ECMD_CLOSE, pdTRUE, pdFALSE },
|
||||
{ 4, "UNKN", ECMD_UNKNOWN, pdFALSE, pdFALSE },
|
||||
};
|
2637
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c
Executable file
2637
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c
Executable file
File diff suppressed because it is too large
Load Diff
71
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_commands.c
Executable file
71
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_commands.c
Executable file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "FreeRTOS_HTTP_commands.h"
|
||||
|
||||
const struct xWEB_COMMAND xWebCommands[ WEB_CMD_COUNT ] =
|
||||
{
|
||||
{ 3, "GET", ECMD_GET },
|
||||
{ 4, "HEAD", ECMD_HEAD },
|
||||
{ 4, "POST", ECMD_POST },
|
||||
{ 3, "PUT", ECMD_PUT },
|
||||
{ 6, "DELETE", ECMD_DELETE },
|
||||
{ 5, "TRACE", ECMD_TRACE },
|
||||
{ 7, "OPTIONS", ECMD_OPTIONS },
|
||||
{ 7, "CONNECT", ECMD_CONNECT },
|
||||
{ 5, "PATCH", ECMD_PATCH },
|
||||
{ 4, "UNKN", ECMD_UNK },
|
||||
};
|
||||
|
||||
const char *webCodename (int aCode)
|
||||
{
|
||||
switch (aCode) {
|
||||
case WEB_REPLY_OK: // = 200,
|
||||
return "OK";
|
||||
case WEB_NO_CONTENT: // 204
|
||||
return "No content";
|
||||
case WEB_BAD_REQUEST: // = 400,
|
||||
return "Bad request";
|
||||
case WEB_UNAUTHORIZED: // = 401,
|
||||
return "Authorization Required";
|
||||
case WEB_NOT_FOUND: // = 404,
|
||||
return "Not Found";
|
||||
case WEB_GONE: // = 410,
|
||||
return "Done";
|
||||
case WEB_PRECONDITION_FAILED: // = 412,
|
||||
return "Precondition Failed";
|
||||
case WEB_INTERNAL_SERVER_ERROR: // = 500,
|
||||
return "Internal Server Error";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
428
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_server.c
Executable file
428
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_server.c
Executable file
@ -0,0 +1,428 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
|
||||
/* FreeRTOS Protocol includes. */
|
||||
#include "FreeRTOS_HTTP_commands.h"
|
||||
#include "FreeRTOS_TCP_server.h"
|
||||
#include "FreeRTOS_server_private.h"
|
||||
|
||||
/* Remove the whole file if HTTP is not supported. */
|
||||
#if( ipconfigUSE_HTTP == 1 )
|
||||
|
||||
/* FreeRTOS+FAT includes. */
|
||||
#include "ff_stdio.h"
|
||||
|
||||
#ifndef HTTP_SERVER_BACKLOG
|
||||
#define HTTP_SERVER_BACKLOG ( 12 )
|
||||
#endif
|
||||
|
||||
#ifndef USE_HTML_CHUNKS
|
||||
#define USE_HTML_CHUNKS ( 0 )
|
||||
#endif
|
||||
|
||||
#if !defined( ARRAY_SIZE )
|
||||
#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
|
||||
#endif
|
||||
|
||||
/* Some defines to make the code more readbale */
|
||||
#define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer
|
||||
#define pcNEW_DIR pxClient->pxParent->pcNewDir
|
||||
#define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer
|
||||
|
||||
#ifndef ipconfigHTTP_REQUEST_CHARACTER
|
||||
#define ipconfigHTTP_REQUEST_CHARACTER '?'
|
||||
#endif
|
||||
|
||||
/*_RB_ Need comment block, although fairly self evident. */
|
||||
static void prvFileClose( HTTPClient_t *pxClient );
|
||||
static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex );
|
||||
static const char *pcGetContentsType( const char *apFname );
|
||||
static BaseType_t prvOpenURL( HTTPClient_t *pxClient );
|
||||
static BaseType_t prvSendFile( HTTPClient_t *pxClient );
|
||||
static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode );
|
||||
|
||||
static const char pcEmptyString[1] = { '\0' };
|
||||
|
||||
typedef struct xTYPE_COUPLE
|
||||
{
|
||||
const char *pcExtension;
|
||||
const char *pcType;
|
||||
} TypeCouple_t;
|
||||
|
||||
static TypeCouple_t pxTypeCouples[ ] =
|
||||
{
|
||||
{ "html", "text/html" },
|
||||
{ "css", "text/css" },
|
||||
{ "js", "text/javascript" },
|
||||
{ "png", "image/png" },
|
||||
{ "jpg", "image/jpeg" },
|
||||
{ "gif", "image/gif" },
|
||||
{ "txt", "text/plain" },
|
||||
{ "mp3", "audio/mpeg3" },
|
||||
{ "wav", "audio/wav" },
|
||||
{ "flac", "audio/ogg" },
|
||||
{ "pdf", "application/pdf" },
|
||||
{ "ttf", "application/x-font-ttf" },
|
||||
{ "ttc", "application/x-font-ttf" }
|
||||
};
|
||||
|
||||
void vHTTPClientDelete( TCPClient_t *pxTCPClient )
|
||||
{
|
||||
HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient;
|
||||
|
||||
/* This HTTP client stops, close / release all resources. */
|
||||
if( pxClient->xSocket != FREERTOS_NO_SOCKET )
|
||||
{
|
||||
FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL );
|
||||
FreeRTOS_closesocket( pxClient->xSocket );
|
||||
pxClient->xSocket = FREERTOS_NO_SOCKET;
|
||||
}
|
||||
prvFileClose( pxClient );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvFileClose( HTTPClient_t *pxClient )
|
||||
{
|
||||
if( pxClient->pxFileHandle != NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "Closing file: %s\n", pxClient->pcCurrentFilename ) );
|
||||
ff_fclose( pxClient->pxFileHandle );
|
||||
pxClient->pxFileHandle = NULL;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode )
|
||||
{
|
||||
struct xTCP_SERVER *pxParent = pxClient->pxParent;
|
||||
BaseType_t xRc;
|
||||
|
||||
/* A normal command reply on the main socket (port 21). */
|
||||
char *pcBuffer = pxParent->pcFileBuffer;
|
||||
|
||||
xRc = snprintf( pcBuffer, sizeof( pxParent->pcFileBuffer ),
|
||||
"HTTP/1.1 %d %s\r\n"
|
||||
#if USE_HTML_CHUNKS
|
||||
"Transfer-Encoding: chunked\r\n"
|
||||
#endif
|
||||
"Content-Type: %s\r\n"
|
||||
"Connection: keep-alive\r\n"
|
||||
"%s\r\n",
|
||||
( int ) xCode,
|
||||
webCodename (xCode),
|
||||
pxParent->pcContentsType[0] ? pxParent->pcContentsType : "text/html",
|
||||
pxParent->pcExtraContents );
|
||||
|
||||
pxParent->pcContentsType[0] = '\0';
|
||||
pxParent->pcExtraContents[0] = '\0';
|
||||
|
||||
xRc = FreeRTOS_send( pxClient->xSocket, ( const void * ) pcBuffer, xRc, 0 );
|
||||
pxClient->bits.bReplySent = pdTRUE_UNSIGNED;
|
||||
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvSendFile( HTTPClient_t *pxClient )
|
||||
{
|
||||
size_t uxSpace;
|
||||
size_t uxCount;
|
||||
BaseType_t xRc = 0;
|
||||
|
||||
if( pxClient->bits.bReplySent == pdFALSE_UNSIGNED )
|
||||
{
|
||||
pxClient->bits.bReplySent = pdTRUE_UNSIGNED;
|
||||
|
||||
strcpy( pxClient->pxParent->pcContentsType, pcGetContentsType( pxClient->pcCurrentFilename ) );
|
||||
snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
|
||||
"Content-Length: %d\r\n", ( int ) pxClient->uxBytesLeft );
|
||||
|
||||
/* "Requested file action OK". */
|
||||
xRc = prvSendReply( pxClient, WEB_REPLY_OK );
|
||||
}
|
||||
|
||||
if( xRc >= 0 ) do
|
||||
{
|
||||
uxSpace = FreeRTOS_tx_space( pxClient->xSocket );
|
||||
|
||||
if( pxClient->uxBytesLeft < uxSpace )
|
||||
{
|
||||
uxCount = pxClient->uxBytesLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCount = uxSpace;
|
||||
}
|
||||
|
||||
if( uxCount > 0u )
|
||||
{
|
||||
if( uxCount > sizeof( pxClient->pxParent->pcFileBuffer ) )
|
||||
{
|
||||
uxCount = sizeof( pxClient->pxParent->pcFileBuffer );
|
||||
}
|
||||
ff_fread( pxClient->pxParent->pcFileBuffer, 1, uxCount, pxClient->pxFileHandle );
|
||||
pxClient->uxBytesLeft -= uxCount;
|
||||
|
||||
xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pxParent->pcFileBuffer, uxCount, 0 );
|
||||
if( xRc < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while( uxCount > 0u );
|
||||
|
||||
if( pxClient->uxBytesLeft == 0u )
|
||||
{
|
||||
/* Writing is ready, no need for further 'eSELECT_WRITE' events. */
|
||||
FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
|
||||
prvFileClose( pxClient );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wake up the TCP task as soon as this socket may be written to. */
|
||||
FreeRTOS_FD_SET( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
|
||||
}
|
||||
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvOpenURL( HTTPClient_t *pxClient )
|
||||
{
|
||||
BaseType_t xRc;
|
||||
char pcSlash[ 2 ];
|
||||
|
||||
pxClient->bits.ulFlags = 0;
|
||||
|
||||
#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
|
||||
{
|
||||
if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL )
|
||||
{
|
||||
size_t xResult;
|
||||
|
||||
xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) );
|
||||
if( xResult > 0 )
|
||||
{
|
||||
strcpy( pxClient->pxParent->pcContentsType, "text/html" );
|
||||
snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
|
||||
"Content-Length: %d\r\n", ( int ) xResult );
|
||||
xRc = prvSendReply( pxClient, WEB_REPLY_OK ); /* "Requested file action OK" */
|
||||
if( xRc > 0 )
|
||||
{
|
||||
xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 );
|
||||
}
|
||||
/* Although against the coding standard of FreeRTOS, a return is
|
||||
done here to simplify this conditional code. */
|
||||
return xRc;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */
|
||||
|
||||
if( pxClient->pcUrlData[ 0 ] != '/' )
|
||||
{
|
||||
/* Insert a slash before the file name. */
|
||||
pcSlash[ 0 ] = '/';
|
||||
pcSlash[ 1 ] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The browser provided a starting '/' already. */
|
||||
pcSlash[ 0 ] = '\0';
|
||||
}
|
||||
snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s",
|
||||
pxClient->pcRootDir,
|
||||
pcSlash,
|
||||
pxClient->pcUrlData);
|
||||
|
||||
pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" );
|
||||
|
||||
FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename,
|
||||
pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) );
|
||||
|
||||
if( pxClient->pxFileHandle == NULL )
|
||||
{
|
||||
/* "404 File not found". */
|
||||
xRc = prvSendReply( pxClient, WEB_NOT_FOUND );
|
||||
}
|
||||
else
|
||||
{
|
||||
pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize;
|
||||
xRc = prvSendFile( pxClient );
|
||||
}
|
||||
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex )
|
||||
{
|
||||
BaseType_t xResult = 0;
|
||||
|
||||
/* A new command has been received. Process it. */
|
||||
switch( xIndex )
|
||||
{
|
||||
case ECMD_GET:
|
||||
xResult = prvOpenURL( pxClient );
|
||||
break;
|
||||
|
||||
case ECMD_HEAD:
|
||||
case ECMD_POST:
|
||||
case ECMD_PUT:
|
||||
case ECMD_DELETE:
|
||||
case ECMD_TRACE:
|
||||
case ECMD_OPTIONS:
|
||||
case ECMD_CONNECT:
|
||||
case ECMD_PATCH:
|
||||
case ECMD_UNK:
|
||||
{
|
||||
FreeRTOS_printf( ( "prvProcessCmd: Not implemented: %s\n",
|
||||
xWebCommands[xIndex].pcCommandName ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xHTTPClientWork( TCPClient_t *pxTCPClient )
|
||||
{
|
||||
BaseType_t xRc;
|
||||
HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient;
|
||||
|
||||
if( pxClient->pxFileHandle != NULL )
|
||||
{
|
||||
prvSendFile( pxClient );
|
||||
}
|
||||
|
||||
xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 );
|
||||
|
||||
if( xRc > 0 )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
const char *pcEndOfCmd;
|
||||
const struct xWEB_COMMAND *curCmd;
|
||||
char *pcBuffer = pcCOMMAND_BUFFER;
|
||||
|
||||
if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) )
|
||||
{
|
||||
pcBuffer[ xRc ] = '\0';
|
||||
}
|
||||
while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) )
|
||||
{
|
||||
pcBuffer[ --xRc ] = '\0';
|
||||
}
|
||||
pcEndOfCmd = pcBuffer + xRc;
|
||||
|
||||
curCmd = xWebCommands;
|
||||
|
||||
/* Pointing to "/index.html HTTP/1.1". */
|
||||
pxClient->pcUrlData = pcBuffer;
|
||||
|
||||
/* Pointing to "HTTP/1.1". */
|
||||
pxClient->pcRestData = pcEmptyString;
|
||||
|
||||
/* Last entry is "ECMD_UNK". */
|
||||
for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ )
|
||||
{
|
||||
BaseType_t xLength;
|
||||
|
||||
xLength = curCmd->xCommandLength;
|
||||
if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) )
|
||||
{
|
||||
char *pcLastPtr;
|
||||
|
||||
pxClient->pcUrlData += xLength + 1;
|
||||
for( pcLastPtr = (char *)pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ )
|
||||
{
|
||||
char ch = *pcLastPtr;
|
||||
if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) )
|
||||
{
|
||||
*pcLastPtr = '\0';
|
||||
pxClient->pcRestData = pcLastPtr + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( xIndex < ( WEB_CMD_COUNT - 1 ) )
|
||||
{
|
||||
xRc = prvProcessCmd( pxClient, xIndex );
|
||||
}
|
||||
}
|
||||
else if( xRc < 0 )
|
||||
{
|
||||
/* The connection will be closed and the client will be deleted. */
|
||||
FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) );
|
||||
}
|
||||
return xRc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static const char *pcGetContentsType (const char *apFname)
|
||||
{
|
||||
const char *slash = NULL;
|
||||
const char *dot = NULL;
|
||||
const char *ptr;
|
||||
const char *pcResult = "text/html";
|
||||
BaseType_t x;
|
||||
|
||||
for( ptr = apFname; *ptr; ptr++ )
|
||||
{
|
||||
if (*ptr == '.') dot = ptr;
|
||||
if (*ptr == '/') slash = ptr;
|
||||
}
|
||||
if( dot > slash )
|
||||
{
|
||||
dot++;
|
||||
for( x = 0; x < ARRAY_SIZE( pxTypeCouples ); x++ )
|
||||
{
|
||||
if( strcasecmp( dot, pxTypeCouples[ x ].pcExtension ) == 0 )
|
||||
{
|
||||
pcResult = pxTypeCouples[ x ].pcType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pcResult;
|
||||
}
|
||||
|
||||
#endif /* ipconfigUSE_HTTP */
|
||||
|
440
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c
Executable file
440
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c
Executable file
@ -0,0 +1,440 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* NTPDemo.c
|
||||
*
|
||||
* An example of how to lookup a domain using DNS
|
||||
* And also how to send and receive UDP messages to get the NTP time
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
|
||||
/* Use the date & time functions from +FAT. */
|
||||
#include "ff_time.h"
|
||||
|
||||
#include "NTPDemo.h"
|
||||
#include "ntpClient.h"
|
||||
|
||||
#include "date_and_time.h"
|
||||
|
||||
enum EStatus {
|
||||
EStatusLookup,
|
||||
EStatusAsking,
|
||||
EStatusPause,
|
||||
EStatusFailed,
|
||||
};
|
||||
|
||||
static struct SNtpPacket xNTPPacket;
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS == 0 )
|
||||
static char cRecvBuffer[ sizeof( struct SNtpPacket ) + 64 ];
|
||||
#endif
|
||||
|
||||
static enum EStatus xStatus = EStatusLookup;
|
||||
|
||||
static const char *pcTimeServers[] = {
|
||||
"0.asia.pool.ntp.org",
|
||||
"0.europe.pool.ntp.org",
|
||||
"0.id.pool.ntp.org",
|
||||
"0.south-america.pool.ntp.org",
|
||||
"0.oceania.pool.ntp.org",
|
||||
"0.north-america.pool.ntp.org"
|
||||
};
|
||||
|
||||
static SemaphoreHandle_t xNTPWakeupSem = NULL;
|
||||
static uint32_t ulIPAddressFound;
|
||||
static Socket_t xUDPSocket = NULL;
|
||||
static TaskHandle_t xNTPTaskhandle = NULL;
|
||||
static TickType_t uxSendTime;
|
||||
|
||||
static void prvNTPTask( void *pvParameters );
|
||||
|
||||
static void vSignalTask( void )
|
||||
{
|
||||
#if( ipconfigUSE_CALLBACKS == 0 )
|
||||
if( xUDPSocket != NULL )
|
||||
{
|
||||
/* Send a signal to the socket so that the
|
||||
FreeRTOS_recvfrom will get interrupted. */
|
||||
FreeRTOS_SignalSocket( xUDPSocket );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( xNTPWakeupSem != NULL )
|
||||
{
|
||||
xSemaphoreGive( xNTPWakeupSem );
|
||||
}
|
||||
}
|
||||
|
||||
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority )
|
||||
{
|
||||
/* The only public function in this module: start a task to contact
|
||||
some NTP server. */
|
||||
|
||||
if( xNTPTaskhandle != NULL )
|
||||
{
|
||||
switch( xStatus )
|
||||
{
|
||||
case EStatusPause:
|
||||
xStatus = EStatusAsking;
|
||||
vSignalTask();
|
||||
break;
|
||||
case EStatusLookup:
|
||||
FreeRTOS_printf( ( "NTP looking up server\n" ) );
|
||||
break;
|
||||
case EStatusAsking:
|
||||
FreeRTOS_printf( ( "NTP still asking\n" ) );
|
||||
break;
|
||||
case EStatusFailed:
|
||||
FreeRTOS_printf( ( "NTP failed somehow\n" ) );
|
||||
ulIPAddressFound = 0ul;
|
||||
xStatus = EStatusLookup;
|
||||
vSignalTask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
if( xUDPSocket != NULL )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 );
|
||||
#else
|
||||
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
|
||||
#endif
|
||||
|
||||
xAddress.sin_addr = 0ul;
|
||||
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
|
||||
FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
xTaskCreate( prvNTPTask, /* The function that implements the task. */
|
||||
( const char * ) "NTP client", /* Just a text name for the task to aid debugging. */
|
||||
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
|
||||
NULL, /* The task parameter, not used in this case. */
|
||||
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
|
||||
&xNTPTaskhandle ); /* The task handle. */
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_printf( ( "Creating socket failed\n" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vDNS_callback( const char *pcName, void *pvSearchID, uint32_t ulIPAddress )
|
||||
{
|
||||
char pcBuf[16];
|
||||
|
||||
/* The DNS lookup has a result, or it has reached the time-out. */
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
|
||||
FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) );
|
||||
if( ulIPAddressFound == 0ul )
|
||||
{
|
||||
ulIPAddressFound = ulIPAddress;
|
||||
}
|
||||
/* For testing: in case DNS doen't respond, still try some NTP server
|
||||
with a known IP-address. */
|
||||
if( ulIPAddressFound == 0ul )
|
||||
{
|
||||
ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 );
|
||||
/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242, 70, 4 ); */
|
||||
}
|
||||
xStatus = EStatusAsking;
|
||||
|
||||
vSignalTask();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSwapFields( struct SNtpPacket *pxPacket)
|
||||
{
|
||||
/* NTP messages are big-endian */
|
||||
pxPacket->rootDelay = FreeRTOS_htonl( pxPacket->rootDelay );
|
||||
pxPacket->rootDispersion = FreeRTOS_htonl( pxPacket->rootDispersion );
|
||||
|
||||
pxPacket->referenceTimestamp.seconds = FreeRTOS_htonl( pxPacket->referenceTimestamp.seconds );
|
||||
pxPacket->referenceTimestamp.fraction = FreeRTOS_htonl( pxPacket->referenceTimestamp.fraction );
|
||||
|
||||
pxPacket->originateTimestamp.seconds = FreeRTOS_htonl( pxPacket->originateTimestamp.seconds );
|
||||
pxPacket->originateTimestamp.fraction = FreeRTOS_htonl( pxPacket->originateTimestamp.fraction );
|
||||
|
||||
pxPacket->receiveTimestamp.seconds = FreeRTOS_htonl( pxPacket->receiveTimestamp.seconds );
|
||||
pxPacket->receiveTimestamp.fraction = FreeRTOS_htonl( pxPacket->receiveTimestamp.fraction );
|
||||
|
||||
pxPacket->transmitTimestamp.seconds = FreeRTOS_htonl( pxPacket->transmitTimestamp.seconds );
|
||||
pxPacket->transmitTimestamp.fraction = FreeRTOS_htonl( pxPacket->transmitTimestamp.fraction );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvNTPPacketInit( )
|
||||
{
|
||||
memset (&xNTPPacket, '\0', sizeof( xNTPPacket ) );
|
||||
|
||||
xNTPPacket.flags = 0xDB; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */
|
||||
xNTPPacket.poll = 10; /* 10 means 1 << 10 = 1024 seconds */
|
||||
xNTPPacket.precision = 0xFA; /* = 250 = 0.015625 seconds */
|
||||
xNTPPacket.rootDelay = 0x5D2E; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */
|
||||
xNTPPacket.rootDispersion = 0x0008CAC8; /* 0x0008CAC8 = 8.7912 seconds */
|
||||
|
||||
/* use the recorded NTP time */
|
||||
time_t uxSecs = FreeRTOS_time( NULL );/* apTime may be NULL, returns seconds */
|
||||
|
||||
xNTPPacket.referenceTimestamp.seconds = uxSecs; /* Current time */
|
||||
xNTPPacket.transmitTimestamp.seconds = uxSecs + 3;
|
||||
|
||||
/* Transform the contents of the fields from native to big endian. */
|
||||
prvSwapFields( &xNTPPacket );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvReadTime( struct SNtpPacket * pxPacket )
|
||||
{
|
||||
FF_TimeStruct_t xTimeStruct;
|
||||
time_t uxPreviousSeconds;
|
||||
time_t uxPreviousMS;
|
||||
|
||||
time_t uxCurrentSeconds;
|
||||
time_t uxCurrentMS;
|
||||
|
||||
const char *pcTimeUnit;
|
||||
int32_t ilDiff;
|
||||
TickType_t uxTravelTime;
|
||||
|
||||
uxTravelTime = xTaskGetTickCount() - uxSendTime;
|
||||
|
||||
/* Transform the contents of the fields from big to native endian. */
|
||||
prvSwapFields( pxPacket );
|
||||
|
||||
uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970;
|
||||
uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967;
|
||||
uxCurrentSeconds += uxCurrentMS / 1000;
|
||||
uxCurrentMS = uxCurrentMS % 1000;
|
||||
|
||||
// Get the last time recorded
|
||||
uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS );
|
||||
|
||||
// Set the new time with precision in msec. */
|
||||
FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS );
|
||||
|
||||
if( uxCurrentSeconds >= uxPreviousSeconds )
|
||||
{
|
||||
ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds );
|
||||
}
|
||||
else
|
||||
{
|
||||
ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds );
|
||||
}
|
||||
|
||||
if( ( ilDiff < -5 ) || ( ilDiff > 5 ) )
|
||||
{
|
||||
/* More than 5 seconds difference. */
|
||||
pcTimeUnit = "sec";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Less than or equal to 5 second difference. */
|
||||
pcTimeUnit = "ms";
|
||||
uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds;
|
||||
int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS;
|
||||
int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS;
|
||||
ilDiff = iCurMS - iPrevMS;
|
||||
}
|
||||
uxCurrentSeconds -= iTimeZone;
|
||||
|
||||
FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct );
|
||||
|
||||
/*
|
||||
378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms)
|
||||
379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms)
|
||||
*/
|
||||
|
||||
FreeRTOS_printf( ("NTP time: %d/%d/%02d %2d:%02d:%02d.%03u Diff %d %s (%lu ms)\n",
|
||||
xTimeStruct.tm_mday,
|
||||
xTimeStruct.tm_mon + 1,
|
||||
xTimeStruct.tm_year + 1900,
|
||||
xTimeStruct.tm_hour,
|
||||
xTimeStruct.tm_min,
|
||||
xTimeStruct.tm_sec,
|
||||
( unsigned )uxCurrentMS,
|
||||
( unsigned )ilDiff,
|
||||
pcTimeUnit,
|
||||
uxTravelTime ) );
|
||||
|
||||
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
|
||||
( void ) pcTimeUnit;
|
||||
( void ) uxTravelTime;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
|
||||
static BaseType_t xOnUDPReceive( Socket_t xSocket, void * pvData, size_t xLength,
|
||||
const struct freertos_sockaddr *pxFrom, const struct freertos_sockaddr *pxDest )
|
||||
{
|
||||
if( xLength >= sizeof( xNTPPacket ) )
|
||||
{
|
||||
prvReadTime( ( struct SNtpPacket *)pvData );
|
||||
if( xStatus != EStatusPause )
|
||||
{
|
||||
xStatus = EStatusPause;
|
||||
}
|
||||
}
|
||||
vSignalTask();
|
||||
/* Tell the driver not to store the RX data */
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ipconfigUSE_CALLBACKS != 0 */
|
||||
|
||||
static void prvNTPTask( void *pvParameters )
|
||||
{
|
||||
BaseType_t xServerIndex = 3;
|
||||
struct freertos_sockaddr xAddress;
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
F_TCP_UDP_Handler_t xHandler;
|
||||
#endif /* ipconfigUSE_CALLBACKS != 0 */
|
||||
|
||||
xStatus = EStatusLookup;
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
xNTPWakeupSem = xSemaphoreCreateBinary();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
memset( &xHandler, '\0', sizeof( xHandler ) );
|
||||
xHandler.pxOnUDPReceive = xOnUDPReceive;
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) );
|
||||
}
|
||||
#endif
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
|
||||
{
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) );
|
||||
}
|
||||
#endif
|
||||
for( ; ; )
|
||||
{
|
||||
switch( xStatus )
|
||||
{
|
||||
case EStatusLookup:
|
||||
if( ( ulIPAddressFound == 0ul ) || ( ulIPAddressFound == ~0ul ) )
|
||||
{
|
||||
if( ++xServerIndex == sizeof( pcTimeServers ) / sizeof( pcTimeServers[ 0 ] ) )
|
||||
{
|
||||
xServerIndex = 0;
|
||||
}
|
||||
FreeRTOS_printf( ( "Looking up server '%s'\n", pcTimeServers[ xServerIndex ] ) );
|
||||
FreeRTOS_gethostbyname_a( pcTimeServers[ xServerIndex ], vDNS_callback, (void *)NULL, 1200 );
|
||||
}
|
||||
else
|
||||
{
|
||||
xStatus = EStatusAsking;
|
||||
}
|
||||
break;
|
||||
|
||||
case EStatusAsking:
|
||||
{
|
||||
char pcBuf[16];
|
||||
|
||||
prvNTPPacketInit( );
|
||||
xAddress.sin_addr = ulIPAddressFound;
|
||||
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
|
||||
FreeRTOS_inet_ntoa( xAddress.sin_addr, pcBuf );
|
||||
FreeRTOS_printf( ( "Sending UDP message to %s:%u\n",
|
||||
pcBuf,
|
||||
FreeRTOS_ntohs( xAddress.sin_port ) ) );
|
||||
|
||||
uxSendTime = xTaskGetTickCount( );
|
||||
FreeRTOS_sendto( xUDPSocket, ( void * )&xNTPPacket, sizeof( xNTPPacket ), 0, &xAddress, sizeof( xAddress ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case EStatusPause:
|
||||
break;
|
||||
|
||||
case EStatusFailed:
|
||||
break;
|
||||
}
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
xSemaphoreTake( xNTPWakeupSem, 5000 );
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t xAddressSize;
|
||||
BaseType_t xReturned;
|
||||
|
||||
xAddressSize = sizeof( xAddress );
|
||||
xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize );
|
||||
switch( xReturned )
|
||||
{
|
||||
case 0:
|
||||
case -pdFREERTOS_ERRNO_EAGAIN:
|
||||
case -pdFREERTOS_ERRNO_EINTR:
|
||||
break;
|
||||
default:
|
||||
if( xReturned < sizeof( xNTPPacket ) )
|
||||
{
|
||||
FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
prvReadTime( ( struct SNtpPacket *)cRecvBuffer );
|
||||
if( xStatus != EStatusPause )
|
||||
{
|
||||
xStatus = EStatusPause;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
133
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h
Executable file
133
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h
Executable file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef __FTPCMD_H__
|
||||
|
||||
#define __FTPCMD_H__
|
||||
|
||||
#define REPL_110 "110 Restart marker reply.\r\n"
|
||||
#define REPL_120 "120 Try again in 2 minutes.\r\n"
|
||||
#define REPL_125 "125 Data connection already open; transfer starting.\r\n"
|
||||
#define REPL_150 "150 File status okay; about to open data connection.\r\n"
|
||||
#define REPL_200 "200 NOOP command successful.\r\n"
|
||||
#define REPL_200_PROGRESS "200 NOOP: data transfer in progress.\r\n"
|
||||
#define REPL_202 "202 Command not implemented, superfluous at this site.\r\n"
|
||||
#define REPL_211 "221 System status, or system help reply.\r\n"
|
||||
#define REPL_211_STATUS "221-status of %s.\r\n"
|
||||
#define REPL_211_END "221 End of status.\r\n"
|
||||
#define REPL_212 "212 Directory status.\r\n"
|
||||
#define REPL_213 "213 File status.\r\n"
|
||||
#define REPL_214 "214 Help message.\r\n"
|
||||
#define REPL_214_END "214 End Help message.\r\n"
|
||||
#define REPL_215 "215 %s system type.\r\n"
|
||||
#define REPL_220 "220 Service ready for new user.\r\n"
|
||||
#define REPL_221 "221 Service closing control connection.\r\n"
|
||||
#define REPL_225 "225 Data connection open; no transfer in progress.\r\n"
|
||||
#define REPL_226 "226 Closing data connection.\r\n"
|
||||
#define REPL_227 "227 Entering Passive Mode (%s,%s,%s,%s,%s,%s).\r\n"
|
||||
#define REPL_227_D "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u).\r\n"
|
||||
#define REPL_230 "230 User logged in, proceed.\r\n"
|
||||
#define REPL_250 "250 Requested file action okay, completed.\r\n"
|
||||
#define REPL_257 "257 %s created.\r\n"
|
||||
// #define REPL_257_PWD "257 \"%s\" is current working dir.\r\n"
|
||||
#define REPL_257_PWD "257 \"%s\"\r\n"
|
||||
#define REPL_331 "331 Only anonymous user is accepted.\r\n"
|
||||
#define REPL_331_ANON "331 Anonymous login okay\r\n"
|
||||
#define REPL_332 "332 Need account for login.\r\n"
|
||||
#define REPL_350 "350 Requested file action pending further information.\r\n"
|
||||
#define REPL_421 "421 Service not available, closing control connection.\r\n"
|
||||
#define REPL_425 "425 Can't open data connection.\r\n"
|
||||
#define REPL_426 "426 Connection closed; transfer aborted.\r\n"
|
||||
#define REPL_450 "450 Requested file action not taken.\r\n"
|
||||
#define REPL_451 "451 Requested action aborted. Local error in processing.\r\n"
|
||||
#define REPL_452 "452 Requested action not taken.\r\n"
|
||||
#define REPL_500 "500 Syntax error, command unrecognized.\r\n"
|
||||
#define REPL_501 "501 Syntax error in parameters or arguments.\r\n"
|
||||
#define REPL_502 "502 Command not implemented.\r\n"
|
||||
#define REPL_503 "503 Bad sequence of commands.\r\n"
|
||||
#define REPL_504 "504 Command not implemented for that parameter.\r\n"
|
||||
#define REPL_530 "530 Not logged in.\r\n"
|
||||
#define REPL_532 "532 Need account for storing files.\r\n"
|
||||
#define REPL_550 "550 Requested action not taken.\r\n"
|
||||
#define REPL_551 "551 Requested action aborted. Page type unknown.\r\n"
|
||||
#define REPL_552 "552 Requested file action aborted.\r\n"
|
||||
#define REPL_553 "553 Requested action not taken.\r\n"
|
||||
#define REPL_553_READ_ONLY "553 Read-only file-system.\r\n"
|
||||
|
||||
enum EFTPCommand {
|
||||
ECMD_USER,
|
||||
ECMD_PASS,
|
||||
ECMD_ACCT,
|
||||
ECMD_CWD,
|
||||
ECMD_CDUP,
|
||||
ECMD_SMNT,
|
||||
ECMD_QUIT,
|
||||
ECMD_REIN,
|
||||
ECMD_PORT,
|
||||
ECMD_PASV,
|
||||
ECMD_TYPE,
|
||||
ECMD_STRU,
|
||||
ECMD_MODE,
|
||||
ECMD_RETR,
|
||||
ECMD_STOR,
|
||||
ECMD_STOU,
|
||||
ECMD_APPE,
|
||||
ECMD_ALLO,
|
||||
ECMD_REST,
|
||||
ECMD_RNFR,
|
||||
ECMD_RNTO,
|
||||
ECMD_ABOR,
|
||||
ECMD_SIZE,
|
||||
ECMD_MDTM,
|
||||
ECMD_DELE,
|
||||
ECMD_RMD,
|
||||
ECMD_MKD,
|
||||
ECMD_PWD,
|
||||
ECMD_LIST,
|
||||
ECMD_NLST,
|
||||
ECMD_SITE,
|
||||
ECMD_SYST,
|
||||
ECMD_FEAT,
|
||||
ECMD_STAT,
|
||||
ECMD_HELP,
|
||||
ECMD_NOOP,
|
||||
ECMD_EMPTY,
|
||||
ECMD_CLOSE,
|
||||
ECMD_UNKNOWN,
|
||||
};
|
||||
|
||||
typedef struct xFTP_COMMAND {
|
||||
BaseType_t xCommandLength;
|
||||
const char pcCommandName[7];
|
||||
const unsigned char ucCommandType;
|
||||
const unsigned char checkLogin;
|
||||
const unsigned char checkNullArg;
|
||||
} FTPCommand_t;
|
||||
|
||||
#define FTP_CMD_COUNT (ECMD_UNKNOWN+1)
|
||||
|
||||
extern const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ];
|
||||
|
||||
#endif // __FTPCMD_H__
|
67
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h
Executable file
67
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h
Executable file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
#ifndef FREERTOS_HTTP_COMMANDS_H
|
||||
#define FREERTOS_HTTP_COMMANDS_H
|
||||
|
||||
enum {
|
||||
WEB_REPLY_OK = 200,
|
||||
WEB_NO_CONTENT = 204,
|
||||
WEB_BAD_REQUEST = 400,
|
||||
WEB_UNAUTHORIZED = 401,
|
||||
WEB_NOT_FOUND = 404,
|
||||
WEB_GONE = 410,
|
||||
WEB_PRECONDITION_FAILED = 412,
|
||||
WEB_INTERNAL_SERVER_ERROR = 500,
|
||||
};
|
||||
|
||||
enum EWebCommand {
|
||||
ECMD_GET,
|
||||
ECMD_HEAD,
|
||||
ECMD_POST,
|
||||
ECMD_PUT,
|
||||
ECMD_DELETE,
|
||||
ECMD_TRACE,
|
||||
ECMD_OPTIONS,
|
||||
ECMD_CONNECT,
|
||||
ECMD_PATCH,
|
||||
ECMD_UNK,
|
||||
};
|
||||
|
||||
struct xWEB_COMMAND
|
||||
{
|
||||
BaseType_t xCommandLength;
|
||||
const char *pcCommandName;
|
||||
const unsigned char ucCommandType;
|
||||
};
|
||||
|
||||
#define WEB_CMD_COUNT (ECMD_UNK+1)
|
||||
|
||||
extern const struct xWEB_COMMAND xWebCommands[WEB_CMD_COUNT];
|
||||
|
||||
extern const char *webCodename (int aCode);
|
||||
|
||||
#endif /* FREERTOS_HTTP_COMMANDS_H */
|
||||
|
||||
|
125
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h
Executable file
125
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h
Executable file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Some code which is common to TCP servers like HTTP en FTP
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TCP_SERVER_H
|
||||
#define FREERTOS_TCP_SERVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef FTP_SERVER_USES_RELATIVE_DIRECTORY
|
||||
#define FTP_SERVER_USES_RELATIVE_DIRECTORY 0
|
||||
#endif
|
||||
|
||||
enum eSERVER_TYPE
|
||||
{
|
||||
eSERVER_NONE,
|
||||
eSERVER_HTTP,
|
||||
eSERVER_FTP,
|
||||
};
|
||||
|
||||
struct xFTP_CLIENT;
|
||||
|
||||
#if( ipconfigFTP_HAS_RECEIVED_HOOK != 0 )
|
||||
extern void vApplicationFTPReceivedHook( const char *pcFileName, uint32_t ulSize, struct xFTP_CLIENT *pxFTPClient );
|
||||
extern void vFTPReplyMessage( struct xFTP_CLIENT *pxFTPClient, const char *pcMessage );
|
||||
#endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */
|
||||
|
||||
#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )
|
||||
/*
|
||||
* Function is called when a user name has been submitted.
|
||||
* The function may return a string such as: "331 Please enter your password"
|
||||
* or return NULL to use the default reply.
|
||||
*/
|
||||
extern const char *pcApplicationFTPUserHook( const char *pcUserName );
|
||||
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
|
||||
|
||||
#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )
|
||||
/*
|
||||
* Function is called when a password was received.
|
||||
* Return positive value to allow the user
|
||||
*/
|
||||
extern BaseType_t xApplicationFTPPasswordHook( const char *pcUserName, const char *pcPassword );
|
||||
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
|
||||
|
||||
#if( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 )
|
||||
/*
|
||||
* The FTP server is asking for user-specific properties
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t usPortNumber; /* For reference only. Host-endian. */
|
||||
const char *pcRootDir;
|
||||
BaseType_t xReadOnly;
|
||||
}
|
||||
FTPUserProperties_t;
|
||||
extern void vApplicationFTPUserPropertiesHook( const char *pcUserName, FTPUserProperties_t *pxProperties );
|
||||
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
|
||||
|
||||
#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
|
||||
/*
|
||||
* A GET request is received containing a special character,
|
||||
* usually a question mark.
|
||||
* const char *pcURLData; // A request, e.g. "/request?limit=75"
|
||||
* char *pcBuffer; // Here the answer can be written
|
||||
* size_t uxBufferLength; // Size of the buffer
|
||||
*
|
||||
*/
|
||||
extern size_t uxApplicationHTTPHandleRequestHook( const char *pcURLData, char *pcBuffer, size_t uxBufferLength );
|
||||
#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */
|
||||
|
||||
struct xSERVER_CONFIG
|
||||
{
|
||||
enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */
|
||||
BaseType_t xPortNumber; /* e.g. 80, 8080, 21 */
|
||||
BaseType_t xBackLog; /* e.g. 10, maximum number of connected TCP clients */
|
||||
const char * const pcRootDir; /* Treat this directory as the root directory */
|
||||
};
|
||||
|
||||
struct xTCP_SERVER;
|
||||
typedef struct xTCP_SERVER TCPServer_t;
|
||||
|
||||
TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount );
|
||||
void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime );
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
/* FreeRTOS_TCPServerWork() calls select().
|
||||
The two functions below provide a possibility to interrupt
|
||||
the call to select(). After the interruption, resume
|
||||
by calling FreeRTOS_TCPServerWork() again. */
|
||||
BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer );
|
||||
BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_TCP_SERVER_H */
|
185
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h
Executable file
185
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h
Executable file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.3
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Some code which is common to TCP servers like HTTP and FTP
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_SERVER_PRIVATE_H
|
||||
#define FREERTOS_SERVER_PRIVATE_H
|
||||
|
||||
#define FREERTOS_NO_SOCKET NULL
|
||||
|
||||
/* FreeRTOS+FAT */
|
||||
#include "ff_stdio.h"
|
||||
|
||||
/* Each HTTP server has 1, at most 2 sockets */
|
||||
#define HTTP_SOCKET_COUNT 2
|
||||
|
||||
/*
|
||||
* ipconfigTCP_COMMAND_BUFFER_SIZE sets the size of:
|
||||
* pcCommandBuffer': a buffer to receive and send TCP commands
|
||||
*
|
||||
* ipconfigTCP_FILE_BUFFER_SIZE sets the size of:
|
||||
* pcFileBuffer' : a buffer to access the file system: read or write data.
|
||||
*
|
||||
* The buffers are both used for FTP as well as HTTP.
|
||||
*/
|
||||
|
||||
#ifndef ipconfigTCP_COMMAND_BUFFER_SIZE
|
||||
#define ipconfigTCP_COMMAND_BUFFER_SIZE ( 2048 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_FILE_BUFFER_SIZE
|
||||
#define ipconfigTCP_FILE_BUFFER_SIZE ( 2048 )
|
||||
#endif
|
||||
|
||||
struct xTCP_CLIENT;
|
||||
|
||||
typedef BaseType_t ( * FTCPWorkFunction ) ( struct xTCP_CLIENT * /* pxClient */ );
|
||||
typedef void ( * FTCPDeleteFunction ) ( struct xTCP_CLIENT * /* pxClient */ );
|
||||
|
||||
#define TCP_CLIENT_FIELDS \
|
||||
enum eSERVER_TYPE eType; \
|
||||
struct xTCP_SERVER *pxParent; \
|
||||
Socket_t xSocket; \
|
||||
const char *pcRootDir; \
|
||||
FTCPWorkFunction fWorkFunction; \
|
||||
FTCPDeleteFunction fDeleteFunction; \
|
||||
struct xTCP_CLIENT *pxNextClient
|
||||
|
||||
typedef struct xTCP_CLIENT
|
||||
{
|
||||
/* This define contains fields which must come first within each of the client structs */
|
||||
TCP_CLIENT_FIELDS;
|
||||
/* --- Keep at the top --- */
|
||||
|
||||
} TCPClient_t;
|
||||
|
||||
struct xHTTP_CLIENT
|
||||
{
|
||||
/* This define contains fields which must come first within each of the client structs */
|
||||
TCP_CLIENT_FIELDS;
|
||||
/* --- Keep at the top --- */
|
||||
|
||||
const char *pcUrlData;
|
||||
const char *pcRestData;
|
||||
char pcCurrentFilename[ ffconfigMAX_FILENAME ];
|
||||
size_t uxBytesLeft;
|
||||
FF_FILE *pxFileHandle;
|
||||
union {
|
||||
struct {
|
||||
uint32_t
|
||||
bReplySent : 1;
|
||||
};
|
||||
uint32_t ulFlags;
|
||||
} bits;
|
||||
};
|
||||
|
||||
typedef struct xHTTP_CLIENT HTTPClient_t;
|
||||
|
||||
struct xFTP_CLIENT
|
||||
{
|
||||
/* This define contains fields which must come first within each of the client structs */
|
||||
TCP_CLIENT_FIELDS;
|
||||
/* --- Keep at the top --- */
|
||||
|
||||
uint32_t ulRestartOffset;
|
||||
uint32_t ulRecvBytes;
|
||||
size_t uxBytesLeft; /* Bytes left to send */
|
||||
uint32_t ulClientIP;
|
||||
TickType_t xStartTime;
|
||||
uint16_t usClientPort;
|
||||
Socket_t xTransferSocket;
|
||||
BaseType_t xTransType;
|
||||
BaseType_t xDirCount;
|
||||
FF_FindData_t xFindData;
|
||||
FF_FILE *pxReadHandle;
|
||||
FF_FILE *pxWriteHandle;
|
||||
char pcCurrentDir[ ffconfigMAX_FILENAME ];
|
||||
char pcFileName[ ffconfigMAX_FILENAME ];
|
||||
char pcConnectionAck[ 128 ];
|
||||
char pcClientAck[ 128 ];
|
||||
union {
|
||||
struct {
|
||||
uint32_t
|
||||
bHelloSent : 1,
|
||||
bLoggedIn : 1,
|
||||
bStatusUser : 1,
|
||||
bInRename : 1,
|
||||
bReadOnly : 1;
|
||||
};
|
||||
uint32_t ulFTPFlags;
|
||||
} bits;
|
||||
union {
|
||||
struct {
|
||||
uint32_t
|
||||
bIsListen : 1, /* pdTRUE for passive data connections (using list()). */
|
||||
bDirHasEntry : 1, /* pdTRUE if ff_findfirst() was successful. */
|
||||
bClientConnected : 1, /* pdTRUE after connect() or accept() has succeeded. */
|
||||
bEmptyFile : 1, /* pdTRUE if a connection-without-data was received. */
|
||||
bHadError : 1; /* pdTRUE if a transfer got aborted because of an error. */
|
||||
};
|
||||
uint32_t ulConnFlags;
|
||||
} bits1;
|
||||
};
|
||||
|
||||
typedef struct xFTP_CLIENT FTPClient_t;
|
||||
|
||||
BaseType_t xHTTPClientWork( TCPClient_t *pxClient );
|
||||
BaseType_t xFTPClientWork( TCPClient_t *pxClient );
|
||||
|
||||
void vHTTPClientDelete( TCPClient_t *pxClient );
|
||||
void vFTPClientDelete( TCPClient_t *pxClient );
|
||||
|
||||
BaseType_t xMakeAbsolute( struct xFTP_CLIENT *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName );
|
||||
BaseType_t xMakeRelative( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName );
|
||||
|
||||
struct xTCP_SERVER
|
||||
{
|
||||
SocketSet_t xSocketSet;
|
||||
/* A buffer to receive and send TCP commands, either HTTP of FTP. */
|
||||
char pcCommandBuffer[ ipconfigTCP_COMMAND_BUFFER_SIZE ];
|
||||
/* A buffer to access the file system: read or write data. */
|
||||
char pcFileBuffer[ ipconfigTCP_FILE_BUFFER_SIZE ];
|
||||
|
||||
#if( ipconfigUSE_FTP != 0 )
|
||||
char pcNewDir[ ffconfigMAX_FILENAME ];
|
||||
#endif
|
||||
#if( ipconfigUSE_HTTP != 0 )
|
||||
char pcContentsType[40]; /* Space for the msg: "text/javascript" */
|
||||
char pcExtraContents[40]; /* Space for the msg: "Content-Length: 346500" */
|
||||
#endif
|
||||
BaseType_t xServerCount;
|
||||
TCPClient_t *pxClients;
|
||||
struct xSERVER
|
||||
{
|
||||
enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */
|
||||
const char *pcRootDir;
|
||||
Socket_t xSocket;
|
||||
} xServers[ 1 ];
|
||||
};
|
||||
|
||||
#endif /* FREERTOS_SERVER_PRIVATE_H */
|
71
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h
Executable file
71
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h
Executable file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// ntpClient.h
|
||||
//
|
||||
|
||||
#ifndef __NTPCLIENT_H__
|
||||
|
||||
#define __NTPCLIENT_H__
|
||||
|
||||
#define NTP_PORT 123
|
||||
|
||||
typedef uint32_t quint32;
|
||||
typedef int32_t qint32;
|
||||
typedef uint8_t quint8;
|
||||
typedef int8_t qint8;
|
||||
|
||||
typedef union _SNtpFlags SNtpFlags;
|
||||
|
||||
/**
|
||||
* 64-bit NTP timestamp.
|
||||
*/
|
||||
struct __attribute__ ((__packed__)) _SNtpTimestamp {
|
||||
/** Number of seconds passed since Jan 1 1900, in big-endian format. */
|
||||
quint32 seconds;
|
||||
|
||||
/** Fractional time part, in <tt>1/0xFFFFFFFF</tt>s of a second. */
|
||||
quint32 fraction;
|
||||
};
|
||||
|
||||
typedef struct _SNtpTimestamp SNtpTimestamp;
|
||||
/**
|
||||
* Mandatory part of an NTP packet
|
||||
*/
|
||||
struct SNtpPacket {
|
||||
/** Flags. */
|
||||
unsigned char flags; // value 0xDB : mode 3 (client), version 3, leap indicator unknown 3
|
||||
|
||||
/** Stratum of the clock. */
|
||||
quint8 stratum; // value 0 : unspecified
|
||||
|
||||
/** Maximum interval between successive messages, in log2 seconds. Note that the value is signed. */
|
||||
qint8 poll; // 10 means 1 << 10 = 1024 seconds
|
||||
|
||||
/** Precision of the clock, in log2 seconds. Note that the value is signed. */
|
||||
qint8 precision; // 0xFA = 250 = 0.015625 seconds
|
||||
|
||||
/** Round trip time to the primary reference source, in NTP short format. */
|
||||
qint32 rootDelay; // 0x5D2E = 23854 or (23854/65535)= 0.3640 sec
|
||||
|
||||
/** Nominal error relative to the primary reference source. */
|
||||
qint32 rootDispersion; // 0x0008 CAC8 = 8.7912 seconds
|
||||
|
||||
/** Reference identifier (either a 4 character string or an IP address). */
|
||||
qint8 referenceID[4]; // or just 0000
|
||||
|
||||
/** The time at which the clock was last set or corrected. */
|
||||
SNtpTimestamp referenceTimestamp; // Current time
|
||||
|
||||
/** The time at which the request departed the client for the server. */
|
||||
SNtpTimestamp originateTimestamp; // Keep 0
|
||||
|
||||
/** The time at which the request arrived at the server. */
|
||||
SNtpTimestamp receiveTimestamp; // Keep 0
|
||||
|
||||
/** The time at which the reply departed the server for client. */
|
||||
SNtpTimestamp transmitTimestamp;
|
||||
};
|
||||
|
||||
/* Add this number to get secs since 1-1-1900 */
|
||||
#define TIME1970 2208988800UL
|
||||
|
||||
#endif // __NTPCLIENT_H__
|
11
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h
Executable file
11
FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h
Executable file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* A simple demo for NTP using FreeRTOS+TCP
|
||||
*/
|
||||
|
||||
#ifndef NTPDEMO_H
|
||||
|
||||
#define NTPDEMO_H
|
||||
|
||||
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority );
|
||||
|
||||
#endif
|
530
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c
Executable file
530
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c
Executable file
@ -0,0 +1,530 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* File system includes. */
|
||||
#include "fat_sl.h"
|
||||
#include "api_mdriver_ram.h"
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#define cliNEW_LINE "\r\n"
|
||||
|
||||
/*******************************************************************************
|
||||
* See the URL in the comments within main.c for the location of the online
|
||||
* documentation.
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Print out information on a single file.
|
||||
*/
|
||||
static void prvCreateFileInfoString( char *pcBuffer, F_FIND *pxFindStruct );
|
||||
|
||||
/*
|
||||
* Copies an existing file into a newly created file.
|
||||
*/
|
||||
static BaseType_t prvPerformCopy( const char *pcSourceFile,
|
||||
int32_t lSourceFileLength,
|
||||
const char *pcDestinationFile,
|
||||
char *pxWriteBuffer,
|
||||
size_t xWriteBufferLen );
|
||||
|
||||
/*
|
||||
* Implements the DIR command.
|
||||
*/
|
||||
static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the CD command.
|
||||
*/
|
||||
static BaseType_t prvCDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the DEL command.
|
||||
*/
|
||||
static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the TYPE command.
|
||||
*/
|
||||
static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the COPY command.
|
||||
*/
|
||||
static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/* Structure that defines the DIR command line command, which lists all the
|
||||
files in the current directory. */
|
||||
static const CLI_Command_Definition_t xDIR =
|
||||
{
|
||||
"dir", /* The command string to type. */
|
||||
"\r\ndir:\r\n Lists the files in the current directory\r\n",
|
||||
prvDIRCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the CD command line command, which changes the
|
||||
working directory. */
|
||||
static const CLI_Command_Definition_t xCD =
|
||||
{
|
||||
"cd", /* The command string to type. */
|
||||
"\r\ncd <dir name>:\r\n Changes the working directory\r\n",
|
||||
prvCDCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the TYPE command line command, which prints the
|
||||
contents of a file to the console. */
|
||||
static const CLI_Command_Definition_t xTYPE =
|
||||
{
|
||||
"type", /* The command string to type. */
|
||||
"\r\ntype <filename>:\r\n Prints file contents to the terminal\r\n",
|
||||
prvTYPECommand, /* The function to run. */
|
||||
1 /* One parameter is expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the DEL command line command, which deletes a file. */
|
||||
static const CLI_Command_Definition_t xDEL =
|
||||
{
|
||||
"del", /* The command string to type. */
|
||||
"\r\ndel <filename>:\r\n deletes a file or directory\r\n",
|
||||
prvDELCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the COPY command line command, which deletes a file. */
|
||||
static const CLI_Command_Definition_t xCOPY =
|
||||
{
|
||||
"copy", /* The command string to type. */
|
||||
"\r\ncopy <source file> <dest file>:\r\n Copies <source file> to <dest file>\r\n",
|
||||
prvCOPYCommand, /* The function to run. */
|
||||
2 /* Two parameters are expected. */
|
||||
};
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRegisterFileSystemCLICommands( void )
|
||||
{
|
||||
/* Register all the command line commands defined immediately above. */
|
||||
FreeRTOS_CLIRegisterCommand( &xDIR );
|
||||
FreeRTOS_CLIRegisterCommand( &xCD );
|
||||
FreeRTOS_CLIRegisterCommand( &xTYPE );
|
||||
FreeRTOS_CLIRegisterCommand( &xDEL );
|
||||
FreeRTOS_CLIRegisterCommand( &xCOPY );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength, xReturn = pdTRUE;
|
||||
static F_FILE *pxFile = NULL;
|
||||
int iChar;
|
||||
size_t xByte;
|
||||
size_t xColumns = 50U;
|
||||
|
||||
/* Ensure there is always a null terminator after each character written. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
|
||||
/* Ensure the buffer leaves space for the \r\n. */
|
||||
configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
|
||||
xWriteBufferLen -= strlen( cliNEW_LINE );
|
||||
|
||||
if( xWriteBufferLen < xColumns )
|
||||
{
|
||||
/* Ensure the loop that uses xColumns as an end condition does not
|
||||
write off the end of the buffer. */
|
||||
xColumns = xWriteBufferLen;
|
||||
}
|
||||
|
||||
if( pxFile == NULL )
|
||||
{
|
||||
/* The file has not been opened yet. Find the file name. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to open the requested file. */
|
||||
pxFile = f_open( pcParameter, "r" );
|
||||
}
|
||||
|
||||
if( pxFile != NULL )
|
||||
{
|
||||
/* Read the next chunk of data from the file. */
|
||||
for( xByte = 0; xByte < xColumns; xByte++ )
|
||||
{
|
||||
iChar = f_getc( pxFile );
|
||||
|
||||
if( iChar == -1 )
|
||||
{
|
||||
/* No more characters to return. */
|
||||
f_close( pxFile );
|
||||
pxFile = NULL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcWriteBuffer[ xByte ] = ( char ) iChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pxFile == NULL )
|
||||
{
|
||||
/* Either the file was not opened, or all the data from the file has
|
||||
been returned and the file is now closed. */
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
strcat( pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvCDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength;
|
||||
unsigned char ucReturned;
|
||||
size_t xStringLength;
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to move to the requested directory. */
|
||||
ucReturned = f_chdir( pcParameter );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "In: " );
|
||||
xStringLength = strlen( pcWriteBuffer );
|
||||
f_getcwd( &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Error" );
|
||||
}
|
||||
|
||||
strcat( pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
static F_FIND *pxFindStruct = NULL;
|
||||
unsigned char ucReturned;
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
/* This assumes pcWriteBuffer is long enough. */
|
||||
( void ) pcCommandString;
|
||||
|
||||
/* Ensure the buffer leaves space for the \r\n. */
|
||||
configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
|
||||
xWriteBufferLen -= strlen( cliNEW_LINE );
|
||||
|
||||
if( pxFindStruct == NULL )
|
||||
{
|
||||
/* This is the first time this function has been executed since the Dir
|
||||
command was run. Create the find structure. */
|
||||
pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) );
|
||||
|
||||
if( pxFindStruct != NULL )
|
||||
{
|
||||
ucReturned = f_findfirst( "*.*", pxFindStruct );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The find struct has already been created. Find the next file in
|
||||
the directory. */
|
||||
ucReturned = f_findnext( pxFindStruct );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are no more files. Free the find structure. */
|
||||
vPortFree( pxFindStruct );
|
||||
pxFindStruct = NULL;
|
||||
|
||||
/* No string to return. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
strcat( pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength;
|
||||
unsigned char ucReturned;
|
||||
|
||||
/* This function assumes xWriteBufferLen is large enough! */
|
||||
( void ) xWriteBufferLen;
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to delete the file. */
|
||||
ucReturned = f_delete( pcParameter );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "%s was deleted", pcParameter );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Error" );
|
||||
}
|
||||
|
||||
strcat( pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
char *pcSourceFile, *pcDestinationFile;
|
||||
BaseType_t xParameterStringLength;
|
||||
long lSourceLength, lDestinationLength = 0;
|
||||
|
||||
/* Obtain the name of the destination file. */
|
||||
pcDestinationFile = ( char * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
2, /* Return the second parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcDestinationFile );
|
||||
|
||||
/* Obtain the name of the source file. */
|
||||
pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcSourceFile );
|
||||
|
||||
/* Terminate the string. */
|
||||
pcSourceFile[ xParameterStringLength ] = 0x00;
|
||||
|
||||
/* See if the source file exists, obtain its length if it does. */
|
||||
lSourceLength = f_filelength( pcSourceFile );
|
||||
|
||||
if( lSourceLength == 0 )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Source file does not exist" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* See if the destination file exists. */
|
||||
lDestinationLength = f_filelength( pcDestinationFile );
|
||||
|
||||
if( lDestinationLength != 0 )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Error: Destination file already exists" );
|
||||
}
|
||||
}
|
||||
|
||||
/* Continue only if the source file exists and the destination file does
|
||||
not exist. */
|
||||
if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) )
|
||||
{
|
||||
if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Copy made" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Error during copy" );
|
||||
}
|
||||
}
|
||||
|
||||
strcat( pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvPerformCopy( const char *pcSourceFile,
|
||||
int32_t lSourceFileLength,
|
||||
const char *pcDestinationFile,
|
||||
char *pxWriteBuffer,
|
||||
size_t xWriteBufferLen )
|
||||
{
|
||||
int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining;
|
||||
F_FILE *pxFile;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
|
||||
/* NOTE: Error handling has been omitted for clarity. */
|
||||
|
||||
while( lBytesRead < lSourceFileLength )
|
||||
{
|
||||
/* How many bytes are left? */
|
||||
lBytesRemaining = lSourceFileLength - lBytesRead;
|
||||
|
||||
/* How many bytes should be read this time around the loop. Can't
|
||||
read more bytes than will fit into the buffer. */
|
||||
if( lBytesRemaining > ( long ) xWriteBufferLen )
|
||||
{
|
||||
lBytesToRead = ( long ) xWriteBufferLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
lBytesToRead = lBytesRemaining;
|
||||
}
|
||||
|
||||
/* Open the source file, seek past the data that has already been
|
||||
read from the file, read the next block of data, then close the
|
||||
file again so the destination file can be opened. */
|
||||
pxFile = f_open( pcSourceFile, "r" );
|
||||
if( pxFile != NULL )
|
||||
{
|
||||
f_seek( pxFile, lBytesRead, F_SEEK_SET );
|
||||
f_read( pxWriteBuffer, lBytesToRead, 1, pxFile );
|
||||
f_close( pxFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Open the destination file and write the block of data to the end of
|
||||
the file. */
|
||||
pxFile = f_open( pcDestinationFile, "a" );
|
||||
if( pxFile != NULL )
|
||||
{
|
||||
f_write( pxWriteBuffer, lBytesToRead, 1, pxFile );
|
||||
f_close( pxFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
lBytesRead += lBytesToRead;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreateFileInfoString( char *pcBuffer, F_FIND *pxFindStruct )
|
||||
{
|
||||
const char *pcWritableFile = "writable file", *pcReadOnlyFile = "read only file", *pcDirectory = "directory";
|
||||
const char * pcAttrib;
|
||||
|
||||
/* Point pcAttrib to a string that describes the file. */
|
||||
if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 )
|
||||
{
|
||||
pcAttrib = pcDirectory;
|
||||
}
|
||||
else if( pxFindStruct->attr & F_ATTR_READONLY )
|
||||
{
|
||||
pcAttrib = pcReadOnlyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcAttrib = pcWritableFile;
|
||||
}
|
||||
|
||||
/* Create a string that includes the file name, the file size and the
|
||||
attributes string. */
|
||||
sprintf( pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, ( int ) pxFindStruct->filesize );
|
||||
}
|
480
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
Executable file
480
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
Executable file
@ -0,0 +1,480 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* http://www.FreeRTOS.org/cli
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
|
||||
#define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0
|
||||
#endif
|
||||
|
||||
#ifndef configINCLUDE_QUERY_HEAP_COMMAND
|
||||
#define configINCLUDE_QUERY_HEAP_COMMAND 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The function that registers the commands that are defined within this file.
|
||||
*/
|
||||
void vRegisterSampleCLICommands( void );
|
||||
|
||||
/*
|
||||
* Implements the task-stats command.
|
||||
*/
|
||||
static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the run-time-stats command.
|
||||
*/
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
#endif /* configGENERATE_RUN_TIME_STATS */
|
||||
|
||||
/*
|
||||
* Implements the echo-three-parameters command.
|
||||
*/
|
||||
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the echo-parameters command.
|
||||
*/
|
||||
static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the "query heap" command.
|
||||
*/
|
||||
#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )
|
||||
static BaseType_t prvQueryHeapCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Implements the "trace start" and "trace stop" commands;
|
||||
*/
|
||||
#if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )
|
||||
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
#endif
|
||||
|
||||
/* Structure that defines the "task-stats" command line command. This generates
|
||||
a table that gives information on each task in the system. */
|
||||
static const CLI_Command_Definition_t xTaskStats =
|
||||
{
|
||||
"task-stats", /* The command string to type. */
|
||||
"\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",
|
||||
prvTaskStatsCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "echo_3_parameters" command line command. This
|
||||
takes exactly three parameters that the command simply echos back one at a
|
||||
time. */
|
||||
static const CLI_Command_Definition_t xThreeParameterEcho =
|
||||
{
|
||||
"echo-3-parameters",
|
||||
"\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",
|
||||
prvThreeParameterEchoCommand, /* The function to run. */
|
||||
3 /* Three parameters are expected, which can take any value. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "echo_parameters" command line command. This
|
||||
takes a variable number of parameters that the command simply echos back one at
|
||||
a time. */
|
||||
static const CLI_Command_Definition_t xParameterEcho =
|
||||
{
|
||||
"echo-parameters",
|
||||
"\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",
|
||||
prvParameterEchoCommand, /* The function to run. */
|
||||
-1 /* The user can enter any number of commands. */
|
||||
};
|
||||
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
/* Structure that defines the "run-time-stats" command line command. This
|
||||
generates a table that shows how much run time each task has */
|
||||
static const CLI_Command_Definition_t xRunTimeStats =
|
||||
{
|
||||
"run-time-stats", /* The command string to type. */
|
||||
"\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",
|
||||
prvRunTimeStatsCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
#endif /* configGENERATE_RUN_TIME_STATS */
|
||||
|
||||
#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )
|
||||
/* Structure that defines the "query_heap" command line command. */
|
||||
static const CLI_Command_Definition_t xQueryHeap =
|
||||
{
|
||||
"query-heap",
|
||||
"\r\nquery-heap:\r\n Displays the free heap space, and minimum ever free heap space.\r\n",
|
||||
prvQueryHeapCommand, /* The function to run. */
|
||||
0 /* The user can enter any number of commands. */
|
||||
};
|
||||
#endif /* configQUERY_HEAP_COMMAND */
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
/* Structure that defines the "trace" command line command. This takes a single
|
||||
parameter, which can be either "start" or "stop". */
|
||||
static const CLI_Command_Definition_t xStartStopTrace =
|
||||
{
|
||||
"trace",
|
||||
"\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",
|
||||
prvStartStopTraceCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. Valid values are "start" and "stop". */
|
||||
};
|
||||
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRegisterSampleCLICommands( void )
|
||||
{
|
||||
/* Register all the command line commands defined immediately above. */
|
||||
FreeRTOS_CLIRegisterCommand( &xTaskStats );
|
||||
FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );
|
||||
FreeRTOS_CLIRegisterCommand( &xParameterEcho );
|
||||
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( &xRunTimeStats );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( &xQueryHeap );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( &xStartStopTrace );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *const pcHeader = " State Priority Stack #\r\n************************************************\r\n";
|
||||
BaseType_t xSpacePadding;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Generate a table of task stats. */
|
||||
strcpy( pcWriteBuffer, "Task" );
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
|
||||
/* Minus three for the null terminator and half the number of characters in
|
||||
"Task" so the column lines up with the centre of the heading. */
|
||||
configASSERT( configMAX_TASK_NAME_LEN > 3 );
|
||||
for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
|
||||
{
|
||||
/* Add a space to align columns after the task's name. */
|
||||
*pcWriteBuffer = ' ';
|
||||
pcWriteBuffer++;
|
||||
|
||||
/* Ensure always terminated. */
|
||||
*pcWriteBuffer = 0x00;
|
||||
}
|
||||
strcpy( pcWriteBuffer, pcHeader );
|
||||
vTaskList( pcWriteBuffer + strlen( pcHeader ) );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )
|
||||
|
||||
static BaseType_t prvQueryHeapCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
sprintf( pcWriteBuffer, "Current free heap %d bytes, minimum ever free heap %d bytes\r\n", ( int ) xPortGetFreeHeapSize(), ( int ) xPortGetMinimumEverFreeHeapSize() );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* configINCLUDE_QUERY_HEAP */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
|
||||
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n";
|
||||
BaseType_t xSpacePadding;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Generate a table of task stats. */
|
||||
strcpy( pcWriteBuffer, "Task" );
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
|
||||
/* Pad the string "task" with however many bytes necessary to make it the
|
||||
length of a task name. Minus three for the null terminator and half the
|
||||
number of characters in "Task" so the column lines up with the centre of
|
||||
the heading. */
|
||||
for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
|
||||
{
|
||||
/* Add a space to align columns after the task's name. */
|
||||
*pcWriteBuffer = ' ';
|
||||
pcWriteBuffer++;
|
||||
|
||||
/* Ensure always terminated. */
|
||||
*pcWriteBuffer = 0x00;
|
||||
}
|
||||
|
||||
strcpy( pcWriteBuffer, pcHeader );
|
||||
vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* configGENERATE_RUN_TIME_STATS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength, xReturn;
|
||||
static UBaseType_t uxParameterNumber = 0;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
if( uxParameterNumber == 0 )
|
||||
{
|
||||
/* The first time the function is called after the command has been
|
||||
entered just a header string is returned. */
|
||||
sprintf( pcWriteBuffer, "The three parameters were:\r\n" );
|
||||
|
||||
/* Next time the function is called the first parameter will be echoed
|
||||
back. */
|
||||
uxParameterNumber = 1U;
|
||||
|
||||
/* There is more data to be returned as no parameters have been echoed
|
||||
back yet. */
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
uxParameterNumber, /* Return the next parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Return the parameter string. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber );
|
||||
strncat( pcWriteBuffer, pcParameter, ( size_t ) xParameterStringLength );
|
||||
strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
|
||||
|
||||
/* If this is the last of the three parameters then there are no more
|
||||
strings to return after this one. */
|
||||
if( uxParameterNumber == 3U )
|
||||
{
|
||||
/* If this is the last of the three parameters then there are no more
|
||||
strings to return after this one. */
|
||||
xReturn = pdFALSE;
|
||||
uxParameterNumber = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are more parameters to return after this one. */
|
||||
xReturn = pdTRUE;
|
||||
uxParameterNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength, xReturn;
|
||||
static UBaseType_t uxParameterNumber = 0;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
if( uxParameterNumber == 0 )
|
||||
{
|
||||
/* The first time the function is called after the command has been
|
||||
entered just a header string is returned. */
|
||||
sprintf( pcWriteBuffer, "The parameters were:\r\n" );
|
||||
|
||||
/* Next time the function is called the first parameter will be echoed
|
||||
back. */
|
||||
uxParameterNumber = 1U;
|
||||
|
||||
/* There is more data to be returned as no parameters have been echoed
|
||||
back yet. */
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
uxParameterNumber, /* Return the next parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
if( pcParameter != NULL )
|
||||
{
|
||||
/* Return the parameter string. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber );
|
||||
strncat( pcWriteBuffer, ( char * ) pcParameter, ( size_t ) xParameterStringLength );
|
||||
strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
|
||||
|
||||
/* There might be more parameters to return after this one. */
|
||||
xReturn = pdTRUE;
|
||||
uxParameterNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more parameters were found. Make sure the write buffer does
|
||||
not contain a valid string. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
|
||||
/* No more data to return. */
|
||||
xReturn = pdFALSE;
|
||||
|
||||
/* Start over the next time this command is executed. */
|
||||
uxParameterNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
|
||||
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t lParameterStringLength;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* There are only two valid parameter values. */
|
||||
if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )
|
||||
{
|
||||
/* Start or restart the trace. */
|
||||
vTraceStop();
|
||||
vTraceClear();
|
||||
vTraceStart();
|
||||
|
||||
sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );
|
||||
}
|
||||
else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )
|
||||
{
|
||||
/* End the trace, if one is running. */
|
||||
vTraceStop();
|
||||
sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );
|
||||
}
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
|
226
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c
Executable file
226
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c
Executable file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This file uses a third party USB CDC driver.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Example includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* Demo application includes. */
|
||||
#include "serial.h"
|
||||
|
||||
/* Dimensions the buffer into which input characters are placed. */
|
||||
#define cmdMAX_INPUT_SIZE 50
|
||||
|
||||
/* Dimentions a buffer to be used by the UART driver, if the UART driver uses a
|
||||
buffer at all. */
|
||||
#define cmdQUEUE_LENGTH 25
|
||||
|
||||
/* DEL acts as a backspace. */
|
||||
#define cmdASCII_DEL ( 0x7F )
|
||||
|
||||
/* The maximum time to wait for the mutex that guards the UART to become
|
||||
available. */
|
||||
#define cmdMAX_MUTEX_WAIT pdMS_TO_TICKS( 300 )
|
||||
|
||||
#ifndef configCLI_BAUD_RATE
|
||||
#define configCLI_BAUD_RATE 115200
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The task that implements the command console processing.
|
||||
*/
|
||||
static void prvUARTCommandConsoleTask( void *pvParameters );
|
||||
void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Const messages output by the command console. */
|
||||
static const char * const pcWelcomeMessage = "FreeRTOS command server.\r\nType Help to view a list of registered commands.\r\n\r\n>";
|
||||
static const char * const pcEndOfOutputMessage = "\r\n[Press ENTER to execute the previous command again]\r\n>";
|
||||
static const char * const pcNewLine = "\r\n";
|
||||
|
||||
/* Used to guard access to the UART in case messages are sent to the UART from
|
||||
more than one task. */
|
||||
static SemaphoreHandle_t xTxMutex = NULL;
|
||||
|
||||
/* The handle to the UART port, which is not used by all ports. */
|
||||
static xComPortHandle xPort = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority )
|
||||
{
|
||||
/* Create the semaphore used to access the UART Tx. */
|
||||
xTxMutex = xSemaphoreCreateMutex();
|
||||
configASSERT( xTxMutex );
|
||||
|
||||
/* Create that task that handles the console itself. */
|
||||
xTaskCreate( prvUARTCommandConsoleTask, /* The task that implements the command console. */
|
||||
"CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */
|
||||
usStackSize, /* The size of the stack allocated to the task. */
|
||||
NULL, /* The parameter is not used, so NULL is passed. */
|
||||
uxPriority, /* The priority allocated to the task. */
|
||||
NULL ); /* A handle is not required, so just pass NULL. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvUARTCommandConsoleTask( void *pvParameters )
|
||||
{
|
||||
signed char cRxedChar;
|
||||
uint8_t ucInputIndex = 0;
|
||||
char *pcOutputString;
|
||||
static char cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ];
|
||||
BaseType_t xReturned;
|
||||
xComPortHandle xPort;
|
||||
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Obtain the address of the output buffer. Note there is no mutual
|
||||
exclusion on this buffer as it is assumed only one command console interface
|
||||
will be used at any one time. */
|
||||
pcOutputString = FreeRTOS_CLIGetOutputBuffer();
|
||||
|
||||
/* Initialise the UART. */
|
||||
xPort = xSerialPortInitMinimal( configCLI_BAUD_RATE, cmdQUEUE_LENGTH );
|
||||
|
||||
/* Send the welcome message. */
|
||||
vSerialPutString( xPort, ( signed char * ) pcWelcomeMessage, ( unsigned short ) strlen( pcWelcomeMessage ) );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait for the next character. The while loop is used in case
|
||||
INCLUDE_vTaskSuspend is not set to 1 - in which case portMAX_DELAY will
|
||||
be a genuine block time rather than an infinite block time. */
|
||||
while( xSerialGetChar( xPort, &cRxedChar, portMAX_DELAY ) != pdPASS );
|
||||
|
||||
/* Ensure exclusive access to the UART Tx. */
|
||||
if( xSemaphoreTake( xTxMutex, cmdMAX_MUTEX_WAIT ) == pdPASS )
|
||||
{
|
||||
/* Echo the character back. */
|
||||
xSerialPutChar( xPort, cRxedChar, portMAX_DELAY );
|
||||
|
||||
/* Was it the end of the line? */
|
||||
if( cRxedChar == '\n' || cRxedChar == '\r' )
|
||||
{
|
||||
/* Just to space the output from the input. */
|
||||
vSerialPutString( xPort, ( signed char * ) pcNewLine, ( unsigned short ) strlen( pcNewLine ) );
|
||||
|
||||
/* See if the command is empty, indicating that the last command
|
||||
is to be executed again. */
|
||||
if( ucInputIndex == 0 )
|
||||
{
|
||||
/* Copy the last command back into the input string. */
|
||||
strcpy( cInputString, cLastInputString );
|
||||
}
|
||||
|
||||
/* Pass the received command to the command interpreter. The
|
||||
command interpreter is called repeatedly until it returns
|
||||
pdFALSE (indicating there is no more output) as it might
|
||||
generate more than one string. */
|
||||
do
|
||||
{
|
||||
/* Get the next output string from the command interpreter. */
|
||||
xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
|
||||
|
||||
/* Write the generated string to the UART. */
|
||||
vSerialPutString( xPort, ( signed char * ) pcOutputString, ( unsigned short ) strlen( pcOutputString ) );
|
||||
|
||||
} while( xReturned != pdFALSE );
|
||||
|
||||
/* All the strings generated by the input command have been
|
||||
sent. Clear the input string ready to receive the next command.
|
||||
Remember the command that was just processed first in case it is
|
||||
to be processed again. */
|
||||
strcpy( cLastInputString, cInputString );
|
||||
ucInputIndex = 0;
|
||||
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
||||
|
||||
vSerialPutString( xPort, ( signed char * ) pcEndOfOutputMessage, ( unsigned short ) strlen( pcEndOfOutputMessage ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cRxedChar == '\r' )
|
||||
{
|
||||
/* Ignore the character. */
|
||||
}
|
||||
else if( ( cRxedChar == '\b' ) || ( cRxedChar == cmdASCII_DEL ) )
|
||||
{
|
||||
/* Backspace was pressed. Erase the last character in the
|
||||
string - if any. */
|
||||
if( ucInputIndex > 0 )
|
||||
{
|
||||
ucInputIndex--;
|
||||
cInputString[ ucInputIndex ] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A character was entered. Add it to the string entered so
|
||||
far. When a \n is entered the complete string will be
|
||||
passed to the command interpreter. */
|
||||
if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) )
|
||||
{
|
||||
if( ucInputIndex < cmdMAX_INPUT_SIZE )
|
||||
{
|
||||
cInputString[ ucInputIndex ] = cRxedChar;
|
||||
ucInputIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Must ensure to give the mutex back. */
|
||||
xSemaphoreGive( xTxMutex );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vOutputString( const char * const pcMessage )
|
||||
{
|
||||
if( xSemaphoreTake( xTxMutex, cmdMAX_MUTEX_WAIT ) == pdPASS )
|
||||
{
|
||||
vSerialPutString( xPort, ( signed char * ) pcMessage, ( unsigned short ) strlen( pcMessage ) );
|
||||
xSemaphoreGive( xTxMutex );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
313
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c
Executable file
313
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c
Executable file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* See the following URL for information on the commands defined in this file:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* FreeRTOS+UDP includes, just to make the stats available to the CLI
|
||||
commands. */
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
|
||||
/*
|
||||
* Defines a command that prints out IP address information.
|
||||
*/
|
||||
static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Defines a command that prints out the gathered demo debug stats.
|
||||
*/
|
||||
static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Defines a command that sends an ICMP ping request to an IP address.
|
||||
*/
|
||||
static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/* Structure that defines the "ip-config" command line command. */
|
||||
static const CLI_Command_Definition_t xIPConfig =
|
||||
{
|
||||
"ip-config",
|
||||
"ip-config:\r\n Displays IP address configuration\r\n\r\n",
|
||||
prvDisplayIPConfig,
|
||||
0
|
||||
};
|
||||
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS != 0
|
||||
/* Structure that defines the "ip-debug-stats" command line command. */
|
||||
static const CLI_Command_Definition_t xIPDebugStats =
|
||||
{
|
||||
"ip-debug-stats", /* The command string to type. */
|
||||
"ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n",
|
||||
prvDisplayIPDebugStats, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS */
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
|
||||
/* Structure that defines the "ping" command line command. This takes an IP
|
||||
address or host name and (optionally) the number of bytes to ping as
|
||||
parameters. */
|
||||
static const CLI_Command_Definition_t xPing =
|
||||
{
|
||||
"ping",
|
||||
"ping <ipaddress> <optional:bytes to send>:\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n",
|
||||
prvPingCommand, /* The function to run. */
|
||||
-1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */
|
||||
};
|
||||
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRegisterUDPCLICommands( void )
|
||||
{
|
||||
/* Register all the command line commands defined immediately above. */
|
||||
FreeRTOS_CLIRegisterCommand( &xIPConfig );
|
||||
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS == 1
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( &xIPDebugStats );
|
||||
}
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS */
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( &xPing );
|
||||
}
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
|
||||
static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
char * pcParameter;
|
||||
BaseType_t lParameterStringLength, xReturn;
|
||||
uint32_t ulIPAddress, ulBytesToPing;
|
||||
const uint32_t ulDefaultBytesToPing = 8UL;
|
||||
char cBuffer[ 16 ];
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Start with an empty string. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
|
||||
/* Obtain the number of bytes to ping. */
|
||||
pcParameter = ( char * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
2, /* Return the second parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
if( pcParameter == NULL )
|
||||
{
|
||||
/* The number of bytes was not specified, so default it. */
|
||||
ulBytesToPing = ulDefaultBytesToPing;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulBytesToPing = atol( pcParameter );
|
||||
}
|
||||
|
||||
/* Obtain the IP address string. */
|
||||
pcParameter = ( char * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to obtain the IP address. If the first character is not a
|
||||
digit, assume the host name has been passed in. */
|
||||
if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) )
|
||||
{
|
||||
ulIPAddress = FreeRTOS_inet_addr( pcParameter );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Terminate the host name. */
|
||||
pcParameter[ lParameterStringLength ] = 0x00;
|
||||
|
||||
/* Attempt to resolve host. */
|
||||
ulIPAddress = FreeRTOS_gethostbyname( pcParameter );
|
||||
}
|
||||
|
||||
/* Convert IP address, which may have come from a DNS lookup, to string. */
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
|
||||
|
||||
if( ulIPAddress != 0 )
|
||||
{
|
||||
xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
if( xReturn == pdFALSE )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "%s", "Could not send ping request\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, ( int ) xReturn );
|
||||
}
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS != 0
|
||||
|
||||
static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
static BaseType_t xIndex = -1;
|
||||
extern xExampleDebugStatEntry_t xIPTraceValues[];
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
xIndex++;
|
||||
|
||||
if( xIndex < xExampleDebugStatEntries() )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "%s %d\r\n", ( char * ) xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the index for the next time it is called. */
|
||||
xIndex = -1;
|
||||
|
||||
/* Ensure nothing remains in the write buffer. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS */
|
||||
|
||||
static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
static BaseType_t xIndex = 0;
|
||||
BaseType_t xReturn;
|
||||
uint32_t ulAddress;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
switch( xIndex )
|
||||
{
|
||||
case 0 :
|
||||
FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL );
|
||||
sprintf( pcWriteBuffer, "\r\nIP address " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
case 1 :
|
||||
FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL );
|
||||
sprintf( pcWriteBuffer, "\r\nNet mask " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL );
|
||||
sprintf( pcWriteBuffer, "\r\nGateway address " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
case 3 :
|
||||
FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress );
|
||||
sprintf( pcWriteBuffer, "\r\nDNS server address " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
default :
|
||||
ulAddress = 0;
|
||||
sprintf( pcWriteBuffer, "\r\n\r\n" );
|
||||
xReturn = pdFALSE;
|
||||
xIndex = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if( ulAddress != 0 )
|
||||
{
|
||||
FreeRTOS_inet_ntoa( ulAddress, ( &( pcWriteBuffer[ strlen( pcWriteBuffer ) ] ) ) );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* See the URL in the comments within main.c for the location of the online
|
||||
* documentation.
|
||||
******************************************************************************/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* File system includes. */
|
||||
#include "fat_sl.h"
|
||||
#include "api_mdriver_ram.h"
|
||||
|
||||
/* 8.3 format, plus null terminator. */
|
||||
#define fsMAX_FILE_NAME_LEN 13
|
||||
|
||||
/* The number of bytes read/written to the example files at a time. */
|
||||
#define fsRAM_BUFFER_SIZE 200
|
||||
|
||||
/* The number of bytes written to the file that uses f_putc() and f_getc(). */
|
||||
#define fsPUTC_FILE_SIZE 100
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Creates and verifies different files on the volume, demonstrating the use of
|
||||
* various different API functions.
|
||||
*/
|
||||
void vCreateAndVerifySampleFiles( void );
|
||||
|
||||
/*
|
||||
* Create a set of example files in the root directory of the volume using
|
||||
* f_write().
|
||||
*/
|
||||
static void prvCreateDemoFilesUsing_f_write( void );
|
||||
|
||||
/*
|
||||
* Use f_read() to read back and verify the files that were created by
|
||||
* prvCreateDemoFilesUsing_f_write().
|
||||
*/
|
||||
static void prvVerifyDemoFileUsing_f_read( void );
|
||||
|
||||
/*
|
||||
* Create an example file in a sub-directory using f_putc().
|
||||
*/
|
||||
static void prvCreateDemoFileUsing_f_putc( void );
|
||||
|
||||
/*
|
||||
* Use f_getc() to read back and verify the file that was created by
|
||||
* prvCreateDemoFileUsing_f_putc().
|
||||
*/
|
||||
static void prvVerifyDemoFileUsing_f_getc( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A buffer used to both create content to write to disk, and read content back
|
||||
from a disk. Note there is no mutual exclusion on this buffer. */
|
||||
static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];
|
||||
|
||||
/* Names of directories that are created. */
|
||||
static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2";
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vCreateAndVerifySampleFiles( void )
|
||||
{
|
||||
unsigned char ucStatus;
|
||||
|
||||
/* First create the volume. */
|
||||
ucStatus = f_initvolume( ram_initfunc );
|
||||
|
||||
/* It is expected that the volume is not formatted. */
|
||||
if( ucStatus == F_ERR_NOTFORMATTED )
|
||||
{
|
||||
/* Format the created volume. */
|
||||
ucStatus = f_format( F_FAT12_MEDIA );
|
||||
}
|
||||
|
||||
if( ucStatus == F_NO_ERROR )
|
||||
{
|
||||
/* Create a set of files using f_write(). */
|
||||
prvCreateDemoFilesUsing_f_write();
|
||||
|
||||
/* Read back and verify the files that were created using f_write(). */
|
||||
prvVerifyDemoFileUsing_f_read();
|
||||
|
||||
/* Create sub directories two deep then create a file using putc. */
|
||||
prvCreateDemoFileUsing_f_putc();
|
||||
|
||||
/* Read back and verify the file created by
|
||||
prvCreateDemoFileUsing_f_putc(). */
|
||||
prvVerifyDemoFileUsing_f_getc();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreateDemoFilesUsing_f_write( void )
|
||||
{
|
||||
BaseType_t xFileNumber, xWriteNumber;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
const BaseType_t xMaxFiles = 5;
|
||||
long lItemsWritten;
|
||||
F_FILE *pxFile;
|
||||
|
||||
/* Create xMaxFiles files. Each created file will be
|
||||
( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled
|
||||
with a different repeating character. */
|
||||
for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )
|
||||
{
|
||||
/* Generate a file name. */
|
||||
sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber );
|
||||
|
||||
/* Obtain the current working directory and print out the file name and
|
||||
the directory into which the file is being written. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
|
||||
/* Open the file, creating the file if it does not already exist. */
|
||||
pxFile = f_open( cFileName, "w" );
|
||||
configASSERT( pxFile );
|
||||
|
||||
/* Fill the RAM buffer with data that will be written to the file. This
|
||||
is just a repeating ascii character that indicates the file number. */
|
||||
memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );
|
||||
|
||||
/* Write the RAM buffer to the opened file a number of times. The
|
||||
number of times the RAM buffer is written to the file depends on the
|
||||
file number, so the length of each created file will be different. */
|
||||
for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )
|
||||
{
|
||||
lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );
|
||||
configASSERT( lItemsWritten == 1 );
|
||||
}
|
||||
|
||||
/* Close the file so another file can be created. */
|
||||
f_close( pxFile );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvVerifyDemoFileUsing_f_read( void )
|
||||
{
|
||||
BaseType_t xFileNumber, xReadNumber;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
const BaseType_t xMaxFiles = 5;
|
||||
long lItemsRead, lChar;
|
||||
F_FILE *pxFile;
|
||||
|
||||
/* Read back the files that were created by
|
||||
prvCreateDemoFilesUsing_f_write(). */
|
||||
for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )
|
||||
{
|
||||
/* Generate the file name. */
|
||||
sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber );
|
||||
|
||||
/* Obtain the current working directory and print out the file name and
|
||||
the directory from which the file is being read. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
|
||||
/* Open the file for reading. */
|
||||
pxFile = f_open( cFileName, "r" );
|
||||
configASSERT( pxFile );
|
||||
|
||||
/* Read the file into the RAM buffer, checking the file contents are as
|
||||
expected. The size of the file depends on the file number. */
|
||||
for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )
|
||||
{
|
||||
/* Start with the RAM buffer clear. */
|
||||
memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );
|
||||
|
||||
lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );
|
||||
configASSERT( lItemsRead == 1 );
|
||||
|
||||
/* Check the RAM buffer is filled with the expected data. Each
|
||||
file contains a different repeating ascii character that indicates
|
||||
the number of the file. */
|
||||
for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )
|
||||
{
|
||||
configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the file. */
|
||||
f_close( pxFile );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreateDemoFileUsing_f_putc( void )
|
||||
{
|
||||
unsigned char ucReturn;
|
||||
int iByte, iReturned;
|
||||
F_FILE *pxFile;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
|
||||
/* Create a sub directory. */
|
||||
ucReturn = f_mkdir( pcDirectory1 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Move into the created sub-directory. */
|
||||
ucReturn = f_chdir( pcDirectory1 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
|
||||
/* Create a subdirectory in the new directory. */
|
||||
ucReturn = f_mkdir( pcDirectory2 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Move into the directory just created - now two directories down from
|
||||
the root. */
|
||||
ucReturn = f_chdir( pcDirectory2 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 );
|
||||
|
||||
/* Generate the file name. */
|
||||
sprintf( cFileName, "%s.txt", pcDirectory2 );
|
||||
|
||||
/* Print out the file name and the directory into which the file is being
|
||||
written. */
|
||||
pxFile = f_open( cFileName, "w" );
|
||||
|
||||
/* Create a file 1 byte at a time. The file is filled with incrementing
|
||||
ascii characters starting from '0'. */
|
||||
for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
|
||||
{
|
||||
iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile );
|
||||
configASSERT( iReturned == ( ( int ) '0' + iByte ) );
|
||||
}
|
||||
|
||||
/* Finished so close the file. */
|
||||
f_close( pxFile );
|
||||
|
||||
/* Move back to the root directory. */
|
||||
ucReturn = f_chdir( "../.." );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
configASSERT( strcmp( cRAMBuffer, pcRoot ) == 0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvVerifyDemoFileUsing_f_getc( void )
|
||||
{
|
||||
unsigned char ucReturn;
|
||||
int iByte, iReturned;
|
||||
F_FILE *pxFile;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
|
||||
/* Move into the directory in which the file was created. */
|
||||
ucReturn = f_chdir( pcFullPath );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 );
|
||||
|
||||
/* Generate the file name. */
|
||||
sprintf( cFileName, "%s.txt", pcDirectory2 );
|
||||
|
||||
/* This time the file is opened for reading. */
|
||||
pxFile = f_open( cFileName, "r" );
|
||||
|
||||
/* Read the file 1 byte at a time. */
|
||||
for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
|
||||
{
|
||||
iReturned = f_getc( pxFile );
|
||||
configASSERT( iReturned == ( ( int ) '0' + iByte ) );
|
||||
}
|
||||
|
||||
/* Finished so close the file. */
|
||||
f_close( pxFile );
|
||||
|
||||
/* Move back to the root directory. */
|
||||
ucReturn = f_chdir( "../.." );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
664
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c
Executable file
664
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c
Executable file
@ -0,0 +1,664 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* See the following URL for information on the commands defined in this file:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* FreeRTOS+UDP includes, just to make the stats available to the CLI
|
||||
commands. */
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
|
||||
#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
|
||||
#define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Implements the run-time-stats command.
|
||||
*/
|
||||
static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the task-stats command.
|
||||
*/
|
||||
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the echo-three-parameters command.
|
||||
*/
|
||||
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the echo-parameters command.
|
||||
*/
|
||||
static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Defines a command that prints out IP address information.
|
||||
*/
|
||||
static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Defines a command that prints out the gathered demo debug stats.
|
||||
*/
|
||||
static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Defines a command that sends an ICMP ping request to an IP address.
|
||||
*/
|
||||
static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the "trace start" and "trace stop" commands;
|
||||
*/
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
#endif
|
||||
|
||||
/* Structure that defines the "ip-config" command line command. */
|
||||
static const CLI_Command_Definition_t xIPConfig =
|
||||
{
|
||||
"ip-config",
|
||||
"ip-config:\r\n Displays IP address configuration\r\n\r\n",
|
||||
prvDisplayIPConfig,
|
||||
0
|
||||
};
|
||||
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS != 0
|
||||
/* Structure that defines the "ip-debug-stats" command line command. */
|
||||
static const CLI_Command_Definition_t xIPDebugStats =
|
||||
{
|
||||
"ip-debug-stats", /* The command string to type. */
|
||||
"ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n",
|
||||
prvDisplayIPDebugStats, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS */
|
||||
|
||||
/* Structure that defines the "run-time-stats" command line command. This
|
||||
generates a table that shows how much run time each task has */
|
||||
static const CLI_Command_Definition_t xRunTimeStats =
|
||||
{
|
||||
"run-time-stats", /* The command string to type. */
|
||||
"run-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n",
|
||||
prvRunTimeStatsCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "task-stats" command line command. This generates
|
||||
a table that gives information on each task in the system. */
|
||||
static const CLI_Command_Definition_t xTaskStats =
|
||||
{
|
||||
"task-stats", /* The command string to type. */
|
||||
"task-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n",
|
||||
prvTaskStatsCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "echo_3_parameters" command line command. This
|
||||
takes exactly three parameters that the command simply echos back one at a
|
||||
time. */
|
||||
static const CLI_Command_Definition_t xThreeParameterEcho =
|
||||
{
|
||||
"echo-3-parameters",
|
||||
"echo-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n\r\n",
|
||||
prvThreeParameterEchoCommand, /* The function to run. */
|
||||
3 /* Three parameters are expected, which can take any value. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "echo_parameters" command line command. This
|
||||
takes a variable number of parameters that the command simply echos back one at
|
||||
a time. */
|
||||
static const CLI_Command_Definition_t xParameterEcho =
|
||||
{
|
||||
"echo-parameters",
|
||||
"echo-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n",
|
||||
prvParameterEchoCommand, /* The function to run. */
|
||||
-1 /* The user can enter any number of commands. */
|
||||
};
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
|
||||
/* Structure that defines the "ping" command line command. This takes an IP
|
||||
address or host name and (optionally) the number of bytes to ping as
|
||||
parameters. */
|
||||
static const CLI_Command_Definition_t xPing =
|
||||
{
|
||||
"ping",
|
||||
"ping <ipaddress> <optional:bytes to send>:\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n",
|
||||
prvPingCommand, /* The function to run. */
|
||||
-1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */
|
||||
};
|
||||
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
/* Structure that defines the "trace" command line command. This takes a single
|
||||
parameter, which can be either "start" or "stop". */
|
||||
static const CLI_Command_Definition_t xStartStopTrace =
|
||||
{
|
||||
"trace",
|
||||
"trace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n",
|
||||
prvStartStopTraceCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. Valid values are "start" and "stop". */
|
||||
};
|
||||
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRegisterCLICommands( void )
|
||||
{
|
||||
/* Register all the command line commands defined immediately above. */
|
||||
FreeRTOS_CLIRegisterCommand( &xTaskStats );
|
||||
FreeRTOS_CLIRegisterCommand( &xRunTimeStats );
|
||||
FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );
|
||||
FreeRTOS_CLIRegisterCommand( &xParameterEcho );
|
||||
FreeRTOS_CLIRegisterCommand( &xIPDebugStats );
|
||||
FreeRTOS_CLIRegisterCommand( &xIPConfig );
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( &xPing );
|
||||
}
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
FreeRTOS_CLIRegisterCommand( & xStartStopTrace );
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *const pcHeader = " State\tPriority\tStack\t#\r\n************************************************\r\n";
|
||||
BaseType_t xSpacePadding;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Generate a table of task stats. */
|
||||
strcpy( pcWriteBuffer, "Task" );
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
|
||||
/* Pad the string "task" with however many bytes necessary to make it the
|
||||
length of a task name. Minus three for the null terminator and half the
|
||||
number of characters in "Task" so the column lines up with the centre of
|
||||
the heading. */
|
||||
for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
|
||||
{
|
||||
/* Add a space to align columns after the task's name. */
|
||||
*pcWriteBuffer = ' ';
|
||||
pcWriteBuffer++;
|
||||
|
||||
/* Ensure always terminated. */
|
||||
*pcWriteBuffer = 0x00;
|
||||
}
|
||||
strcpy( pcWriteBuffer, pcHeader );
|
||||
vTaskList( pcWriteBuffer + strlen( pcHeader ) );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n";
|
||||
BaseType_t xSpacePadding;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Generate a table of task stats. */
|
||||
strcpy( pcWriteBuffer, "Task" );
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
|
||||
/* Pad the string "task" with however many bytes necessary to make it the
|
||||
length of a task name. Minus three for the null terminator and half the
|
||||
number of characters in "Task" so the column lines up with the centre of
|
||||
the heading. */
|
||||
for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
|
||||
{
|
||||
/* Add a space to align columns after the task's name. */
|
||||
*pcWriteBuffer = ' ';
|
||||
pcWriteBuffer++;
|
||||
|
||||
/* Ensure always terminated. */
|
||||
*pcWriteBuffer = 0x00;
|
||||
}
|
||||
|
||||
strcpy( pcWriteBuffer, pcHeader );
|
||||
vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength, xReturn;
|
||||
static BaseType_t lParameterNumber = 0;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
if( lParameterNumber == 0 )
|
||||
{
|
||||
/* The first time the function is called after the command has been
|
||||
entered just a header string is returned. */
|
||||
sprintf( pcWriteBuffer, "The three parameters were:\r\n" );
|
||||
|
||||
/* Next time the function is called the first parameter will be echoed
|
||||
back. */
|
||||
lParameterNumber = 1L;
|
||||
|
||||
/* There is more data to be returned as no parameters have been echoed
|
||||
back yet. */
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
lParameterNumber, /* Return the next parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Return the parameter string. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber );
|
||||
strncat( pcWriteBuffer, pcParameter, xParameterStringLength );
|
||||
strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
|
||||
|
||||
/* If this is the last of the three parameters then there are no more
|
||||
strings to return after this one. */
|
||||
if( lParameterNumber == 3L )
|
||||
{
|
||||
/* If this is the last of the three parameters then there are no more
|
||||
strings to return after this one. */
|
||||
xReturn = pdFALSE;
|
||||
lParameterNumber = 0L;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are more parameters to return after this one. */
|
||||
xReturn = pdTRUE;
|
||||
lParameterNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t xParameterStringLength, xReturn;
|
||||
static BaseType_t lParameterNumber = 0;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
if( lParameterNumber == 0 )
|
||||
{
|
||||
/* The first time the function is called after the command has been
|
||||
entered just a header string is returned. */
|
||||
sprintf( pcWriteBuffer, "The parameters were:\r\n" );
|
||||
|
||||
/* Next time the function is called the first parameter will be echoed
|
||||
back. */
|
||||
lParameterNumber = 1L;
|
||||
|
||||
/* There is more data to be returned as no parameters have been echoed
|
||||
back yet. */
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
lParameterNumber, /* Return the next parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
if( pcParameter != NULL )
|
||||
{
|
||||
/* Return the parameter string. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber );
|
||||
strncat( pcWriteBuffer, pcParameter, xParameterStringLength );
|
||||
strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
|
||||
|
||||
/* There might be more parameters to return after this one. */
|
||||
xReturn = pdTRUE;
|
||||
lParameterNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more parameters were found. Make sure the write buffer does
|
||||
not contain a valid string. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
|
||||
/* No more data to return. */
|
||||
xReturn = pdFALSE;
|
||||
|
||||
/* Start over the next time this command is executed. */
|
||||
lParameterNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
|
||||
static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
char * pcParameter;
|
||||
BaseType_t lParameterStringLength, xReturn;
|
||||
uint32_t ulIPAddress, ulBytesToPing;
|
||||
const uint32_t ulDefaultBytesToPing = 8UL;
|
||||
char cBuffer[ 16 ];
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Start with an empty string. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
|
||||
/* Obtain the number of bytes to ping. */
|
||||
pcParameter = ( char * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
2, /* Return the second parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
if( pcParameter == NULL )
|
||||
{
|
||||
/* The number of bytes was not specified, so default it. */
|
||||
ulBytesToPing = ulDefaultBytesToPing;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulBytesToPing = atol( pcParameter );
|
||||
}
|
||||
|
||||
/* Obtain the IP address string. */
|
||||
pcParameter = ( char * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to obtain the IP address. If the first character is not a
|
||||
digit, assume the host name has been passed in. */
|
||||
if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) )
|
||||
{
|
||||
ulIPAddress = FreeRTOS_inet_addr( pcParameter );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Terminate the host name. */
|
||||
pcParameter[ lParameterStringLength ] = 0x00;
|
||||
|
||||
/* Attempt to resolve host. */
|
||||
ulIPAddress = FreeRTOS_gethostbyname( pcParameter );
|
||||
}
|
||||
|
||||
/* Convert IP address, which may have come from a DNS lookup, to string. */
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
|
||||
|
||||
if( ulIPAddress != 0 )
|
||||
{
|
||||
xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
if( xReturn == pdFALSE )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "%s", "Could not send ping request\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, xReturn );
|
||||
}
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS != 0
|
||||
|
||||
static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
static BaseType_t xIndex = -1;
|
||||
extern xExampleDebugStatEntry_t xIPTraceValues[];
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
xIndex++;
|
||||
|
||||
if( xIndex < xExampleDebugStatEntries() )
|
||||
{
|
||||
sprintf( pcWriteBuffer, "%s %d\r\n", xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the index for the next time it is called. */
|
||||
xIndex = -1;
|
||||
|
||||
/* Ensure nothing remains in the write buffer. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS */
|
||||
|
||||
static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
static BaseType_t xIndex = 0;
|
||||
BaseType_t xReturn;
|
||||
uint32_t ulAddress;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
switch( xIndex )
|
||||
{
|
||||
case 0 :
|
||||
FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL );
|
||||
sprintf( pcWriteBuffer, "\r\nIP address " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
case 1 :
|
||||
FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL );
|
||||
sprintf( pcWriteBuffer, "\r\nNet mask " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL );
|
||||
sprintf( pcWriteBuffer, "\r\nGateway address " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
case 3 :
|
||||
FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress );
|
||||
sprintf( pcWriteBuffer, "\r\nDNS server address " );
|
||||
xReturn = pdTRUE;
|
||||
xIndex++;
|
||||
break;
|
||||
|
||||
default :
|
||||
ulAddress = 0;
|
||||
sprintf( pcWriteBuffer, "\r\n\r\n" );
|
||||
xReturn = pdFALSE;
|
||||
xIndex = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if( ulAddress != 0 )
|
||||
{
|
||||
FreeRTOS_inet_ntoa( ulAddress, &( pcWriteBuffer[ strlen( pcWriteBuffer ) ] ) );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
|
||||
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
const char *pcParameter;
|
||||
BaseType_t lParameterStringLength;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* There are only two valid parameter values. */
|
||||
if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )
|
||||
{
|
||||
/* Start or restart the trace. */
|
||||
vTraceStop();
|
||||
vTraceClear();
|
||||
vTraceStart();
|
||||
|
||||
sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );
|
||||
}
|
||||
else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )
|
||||
{
|
||||
/* End the trace, if one is running. */
|
||||
vTraceStop();
|
||||
sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );
|
||||
}
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef UDP_COMMAND_INTERPRETER_H
|
||||
#define UDP_COMMAND_INTERPRETER_H
|
||||
|
||||
void vStartUDPCommandInterpreterTask( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority );
|
||||
|
||||
#endif /* UDP_COMMAND_INTERPRETER_H */
|
206
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
Executable file
206
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
Executable file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* FreeRTOS+UDP includes. */
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
|
||||
/* Demo app includes. */
|
||||
#include "UDPCommandInterpreter.h"
|
||||
|
||||
/* Dimensions the buffer into which input characters are placed. */
|
||||
#define cmdMAX_INPUT_SIZE 60
|
||||
|
||||
/* Dimensions the buffer into which string outputs can be placed. */
|
||||
#define cmdMAX_OUTPUT_SIZE 1250
|
||||
|
||||
/* Dimensions the buffer passed to the recvfrom() call. */
|
||||
#define cmdSOCKET_INPUT_BUFFER_SIZE 60
|
||||
|
||||
/*
|
||||
* The task that runs FreeRTOS+CLI.
|
||||
*/
|
||||
void vUDPCommandInterpreterTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Open and configure the UDP socket.
|
||||
*/
|
||||
static xSocket_t prvOpenUDPServerSocket( uint16_t usPort );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartUDPCommandInterpreterTask( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority )
|
||||
{
|
||||
xTaskCreate( vUDPCommandInterpreterTask, "CLI", usStackSize, ( void * ) ulPort, uxPriority, NULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Task that provides the input and output for the FreeRTOS+CLI command
|
||||
* interpreter. In this case a UDP port is used. See the URL in the comments
|
||||
* within main.c for the location of the online documentation.
|
||||
*/
|
||||
void vUDPCommandInterpreterTask( void *pvParameters )
|
||||
{
|
||||
long lBytes, lByte;
|
||||
signed char cInChar, cInputIndex = 0;
|
||||
static char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];
|
||||
BaseType_t xMoreDataToFollow;
|
||||
struct freertos_sockaddr xClient;
|
||||
socklen_t xClientAddressLength = 0; /* This is required as a parameter to maintain the sendto() Berkeley sockets API - but it is not actually used so can take any value. */
|
||||
xSocket_t xSocket;
|
||||
|
||||
/* Just to prevent compiler warnings. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Attempt to open the socket. The port number is passed in the task
|
||||
parameter. The strange casting is to remove compiler warnings on 32-bit
|
||||
machines. */
|
||||
xSocket = prvOpenUDPServerSocket( ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL );
|
||||
|
||||
if( xSocket != FREERTOS_INVALID_SOCKET )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait for incoming data on the opened socket. */
|
||||
lBytes = FreeRTOS_recvfrom( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ), 0, &xClient, &xClientAddressLength );
|
||||
|
||||
if( lBytes != FREERTOS_SOCKET_ERROR )
|
||||
{
|
||||
/* Process each received byte in turn. */
|
||||
lByte = 0;
|
||||
while( lByte < lBytes )
|
||||
{
|
||||
/* The next character in the input buffer. */
|
||||
cInChar = cLocalBuffer[ lByte ];
|
||||
lByte++;
|
||||
|
||||
/* Newline characters are taken as the end of the command
|
||||
string. */
|
||||
if( cInChar == '\n' )
|
||||
{
|
||||
/* Process the input string received prior to the
|
||||
newline. */
|
||||
do
|
||||
{
|
||||
/* Pass the string to FreeRTOS+CLI. */
|
||||
xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE );
|
||||
|
||||
/* Send the output generated by the command's
|
||||
implementation. */
|
||||
FreeRTOS_sendto( xSocket, cOutputString, strlen( cOutputString ), 0, &xClient, xClientAddressLength );
|
||||
|
||||
} while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */
|
||||
|
||||
/* All the strings generated by the command processing
|
||||
have been sent. Clear the input string ready to receive
|
||||
the next command. */
|
||||
cInputIndex = 0;
|
||||
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
||||
|
||||
/* Transmit a spacer, just to make the command console
|
||||
easier to read. */
|
||||
FreeRTOS_sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, &xClient, xClientAddressLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cInChar == '\r' )
|
||||
{
|
||||
/* Ignore the character. Newlines are used to
|
||||
detect the end of the input string. */
|
||||
}
|
||||
else if( cInChar == '\b' )
|
||||
{
|
||||
/* Backspace was pressed. Erase the last character
|
||||
in the string - if any. */
|
||||
if( cInputIndex > 0 )
|
||||
{
|
||||
cInputIndex--;
|
||||
cInputString[ cInputIndex ] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A character was entered. Add it to the string
|
||||
entered so far. When a \n is entered the complete
|
||||
string will be passed to the command interpreter. */
|
||||
if( cInputIndex < cmdMAX_INPUT_SIZE )
|
||||
{
|
||||
cInputString[ cInputIndex ] = cInChar;
|
||||
cInputIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The socket could not be opened. */
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static xSocket_t prvOpenUDPServerSocket( uint16_t usPort )
|
||||
{
|
||||
struct freertos_sockaddr xServer;
|
||||
xSocket_t xSocket = FREERTOS_INVALID_SOCKET;
|
||||
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
if( xSocket != FREERTOS_INVALID_SOCKET)
|
||||
{
|
||||
/* Zero out the server structure. */
|
||||
memset( ( void * ) &xServer, 0x00, sizeof( xServer ) );
|
||||
|
||||
/* Set family and port. */
|
||||
xServer.sin_port = FreeRTOS_htons( usPort );
|
||||
|
||||
/* Bind the address to the socket. */
|
||||
if( FreeRTOS_bind( xSocket, &xServer, sizeof( xServer ) ) == -1 )
|
||||
{
|
||||
FreeRTOS_closesocket( xSocket );
|
||||
xSocket = FREERTOS_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
return xSocket;
|
||||
}
|
||||
|
||||
|
359
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c
Executable file
359
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c
Executable file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* See the following web page for essential TwoEchoClient.c usage and
|
||||
* configuration details:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+UDP includes. */
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
|
||||
/* Small delay used between attempts to obtain a zero copy buffer. */
|
||||
#define echoTINY_DELAY ( ( TickType_t ) 2 )
|
||||
|
||||
/* The echo tasks create a socket, send out a number of echo requests
|
||||
(listening for each echo reply), then close the socket again before
|
||||
starting over. This delay is used between each iteration to ensure the
|
||||
network does not get too congested. */
|
||||
#define echoLOOP_DELAY ( ( TickType_t ) 250 / portTICK_RATE_MS )
|
||||
|
||||
#if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1
|
||||
/* When the trace recorder code is included user events are generated to
|
||||
mark the sending and receiving of the echoed data (only in the zero copy
|
||||
task. */
|
||||
#define echoMARK_SEND_IN_TRACE_BUFFER( x ) vTraceUserEvent( x )
|
||||
traceLabel xZeroCopySendEvent, xZeroCopyReceiveEvent;
|
||||
|
||||
#else
|
||||
/* When the trace recorder code is not included just #define away the call
|
||||
to post the user event. */
|
||||
#define echoMARK_SEND_IN_TRACE_BUFFER( x )
|
||||
#define xZeroCopySendEvent 0
|
||||
#define xZeroCopyReceiveEvent 0
|
||||
#endif
|
||||
|
||||
/* The echo server is assumed to be on port 7, which is the standard echo
|
||||
protocol port. */
|
||||
#define echoECHO_PORT ( 7 )
|
||||
|
||||
/*
|
||||
* Uses a socket to send data to, then receive data from, the standard echo
|
||||
* port number 7. prvEchoClientTask() uses the standard interface.
|
||||
* prvZeroCopyEchoClientTask() uses the zero copy interface.
|
||||
*/
|
||||
static void prvEchoClientTask( void *pvParameters );
|
||||
static void prvZeroCopyEchoClientTask( void *pvParameters );
|
||||
|
||||
/* The receive timeout is set shorter when the windows simulator is used
|
||||
because simulated time is slower than real time. */
|
||||
#ifdef _WINDOWS_
|
||||
const TickType_t xReceiveTimeOut = 50 / portTICK_RATE_MS;
|
||||
#else
|
||||
const TickType_t xReceiveTimeOut = 500 / portTICK_RATE_MS;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartEchoClientTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority )
|
||||
{
|
||||
/* Create the echo client task that does not use the zero copy interface. */
|
||||
xTaskCreate( prvEchoClientTask, /* The function that implements the task. */
|
||||
"Echo0", /* Just a text name for the task to aid debugging. */
|
||||
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
|
||||
NULL, /* The task parameter, not used in this case. */
|
||||
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
|
||||
NULL ); /* The task handle is not used. */
|
||||
|
||||
/* Create the echo client task that does use the zero copy interface. */
|
||||
xTaskCreate( prvZeroCopyEchoClientTask, /* The function that implements the task. */
|
||||
"Echo1", /* Just a text name for the task to aid debugging. */
|
||||
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
|
||||
NULL, /* The task parameter, not used in this case. */
|
||||
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
|
||||
NULL ); /* The task handle is not used. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvEchoClientTask( void *pvParameters )
|
||||
{
|
||||
xSocket_t xSocket;
|
||||
struct freertos_sockaddr xEchoServerAddress;
|
||||
char cTxString[ 25 ], cRxString[ 25 ]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */
|
||||
int32_t lLoopCount = 0UL;
|
||||
const int32_t lMaxLoopCount = 50;
|
||||
volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL;
|
||||
uint32_t xAddressLength = sizeof( xEchoServerAddress );
|
||||
|
||||
/* Remove compiler warning about unused parameters. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Echo requests are sent to the echo server. The address of the echo
|
||||
server is configured by the constants configECHO_SERVER_ADDR0 to
|
||||
configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */
|
||||
xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
|
||||
xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,
|
||||
configECHO_SERVER_ADDR1,
|
||||
configECHO_SERVER_ADDR2,
|
||||
configECHO_SERVER_ADDR3 );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Create a socket. */
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
|
||||
|
||||
/* Set a time out so a missing reply does not cause the task to block
|
||||
indefinitely. */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
|
||||
/* Send a number of echo requests. */
|
||||
for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ )
|
||||
{
|
||||
/* Create the string that is sent to the echo server. */
|
||||
sprintf( cTxString, "Message number %u\r\n", ( unsigned int ) ulTxCount );
|
||||
|
||||
/* Send the string to the socket. ulFlags is set to 0, so the zero
|
||||
copy interface is not used. That means the data from cTxString is
|
||||
copied into a network buffer inside FreeRTOS_sendto(), and cTxString
|
||||
can be reused as soon as FreeRTOS_sendto() has returned. 1 is added
|
||||
to ensure the NULL string terminator is sent as part of the message. */
|
||||
FreeRTOS_sendto( xSocket, /* The socket being sent to. */
|
||||
( void * ) cTxString, /* The data being sent. */
|
||||
strlen( cTxString ) + 1,/* The length of the data being sent. */
|
||||
0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */
|
||||
&xEchoServerAddress, /* The destination address. */
|
||||
sizeof( xEchoServerAddress ) );
|
||||
|
||||
/* Keep a count of how many echo requests have been transmitted so
|
||||
it can be compared to the number of echo replies received. It would
|
||||
be expected to loose at least one to an ARP message the first time
|
||||
the connection is created. */
|
||||
ulTxCount++;
|
||||
|
||||
/* Receive data echoed back to the socket. ulFlags is zero, so the
|
||||
zero copy option is not being used and the received data will be
|
||||
copied into the buffer pointed to by cRxString. xAddressLength is
|
||||
not actually used (at the time of writing this comment, anyway) by
|
||||
FreeRTOS_recvfrom(), but is set appropriately in case future
|
||||
versions do use it. */
|
||||
memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) );
|
||||
FreeRTOS_recvfrom( xSocket, /* The socket being received from. */
|
||||
cRxString, /* The buffer into which the received data will be written. */
|
||||
sizeof( cRxString ), /* The size of the buffer provided to receive the data. */
|
||||
0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */
|
||||
&xEchoServerAddress, /* The address from where the data was sent (the source address). */
|
||||
&xAddressLength );
|
||||
|
||||
/* Compare the transmitted string to the received string. */
|
||||
if( strcmp( cRxString, cTxString ) == 0 )
|
||||
{
|
||||
/* The echo reply was received without error. */
|
||||
ulRxCount++;
|
||||
}
|
||||
};
|
||||
|
||||
/* Pause for a short while to ensure the network is not too
|
||||
congested. */
|
||||
vTaskDelay( echoLOOP_DELAY );
|
||||
|
||||
/* Close this socket before looping back to create another. */
|
||||
FreeRTOS_closesocket( xSocket );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvZeroCopyEchoClientTask( void *pvParameters )
|
||||
{
|
||||
xSocket_t xSocket;
|
||||
struct freertos_sockaddr xEchoServerAddress;
|
||||
static char cTxString[ 40 ];
|
||||
int32_t lLoopCount = 0UL;
|
||||
volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL;
|
||||
uint32_t xAddressLength = sizeof( xEchoServerAddress );
|
||||
int32_t lReturned;
|
||||
uint8_t *pucUDPPayloadBuffer;
|
||||
|
||||
const int32_t lMaxLoopCount = 50;
|
||||
const char * const pcStringToSend = "Zero copy message number";
|
||||
/* The buffer is large enough to hold the string, a number, and the string terminator. */
|
||||
const size_t xBufferLength = strlen( pcStringToSend ) + 15;
|
||||
|
||||
#if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1
|
||||
{
|
||||
/* When the trace recorder code is included user events are generated to
|
||||
mark the sending and receiving of the echoed data (only in the zero copy
|
||||
task). */
|
||||
xZeroCopySendEvent = xTraceOpenLabel( "ZeroCopyTx" );
|
||||
xZeroCopyReceiveEvent = xTraceOpenLabel( "ZeroCopyRx" );
|
||||
}
|
||||
#endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS */
|
||||
|
||||
/* Remove compiler warning about unused parameters. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Delay for a little while to ensure the task is out of synch with the
|
||||
other echo task implemented above. */
|
||||
vTaskDelay( echoLOOP_DELAY >> 1 );
|
||||
|
||||
/* Echo requests are sent to the echo server. The address of the echo
|
||||
server is configured by the constants configECHO_SERVER_ADDR0 to
|
||||
configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */
|
||||
xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
|
||||
xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,
|
||||
configECHO_SERVER_ADDR1,
|
||||
configECHO_SERVER_ADDR2,
|
||||
configECHO_SERVER_ADDR3 );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Create a socket. */
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
|
||||
|
||||
/* Set a time out so a missing reply does not cause the task to block
|
||||
indefinitely. */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
|
||||
/* Send a number of echo requests. */
|
||||
for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ )
|
||||
{
|
||||
/* This task is going to send using the zero copy interface. The
|
||||
data being sent is therefore written directly into a buffer that is
|
||||
passed by reference into the FreeRTOS_sendto() function. First
|
||||
obtain a buffer of adequate size from the IP stack. Although a max
|
||||
delay is used, the actual delay will be capped to
|
||||
ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence the test to ensure a buffer
|
||||
was actually obtained. */
|
||||
pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xBufferLength, portMAX_DELAY );
|
||||
|
||||
if( pucUDPPayloadBuffer != NULL )
|
||||
{
|
||||
/* A buffer was successfully obtained. Create the string that is
|
||||
sent to the echo server. Note the string is written directly
|
||||
into the buffer obtained from the IP stack. */
|
||||
sprintf( ( char * ) pucUDPPayloadBuffer, "%s %u\r\n", "Zero copy message number", ( unsigned int ) ulTxCount );
|
||||
|
||||
/* Also copy the string into a local buffer so it can be compared
|
||||
with the string that is later received back from the echo server. */
|
||||
strcpy( cTxString, ( char * ) pucUDPPayloadBuffer );
|
||||
|
||||
/* Pass the buffer into the send function. ulFlags has the
|
||||
FREERTOS_ZERO_COPY bit set so the IP stack will take control of
|
||||
the buffer, rather than copy data out of the buffer. */
|
||||
echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopySendEvent );
|
||||
lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */
|
||||
( void * ) pucUDPPayloadBuffer, /* The buffer being passed into the IP stack. */
|
||||
strlen( cTxString ) + 1, /* The length of the data being sent. Plus 1 to ensure the null terminator is part of the data. */
|
||||
FREERTOS_ZERO_COPY, /* ulFlags with the zero copy bit is set. */
|
||||
&xEchoServerAddress, /* Where the data is being sent. */
|
||||
sizeof( xEchoServerAddress ) );
|
||||
|
||||
if( lReturned == 0 )
|
||||
{
|
||||
/* The send operation failed, so this task is still
|
||||
responsible for the buffer obtained from the IP stack. To
|
||||
ensure the buffer is not lost it must either be used again,
|
||||
or, as in this case, returned to the IP stack using
|
||||
FreeRTOS_ReleaseUDPPayloadBuffer(). pucUDPPayloadBuffer can
|
||||
be safely re-used to receive from the socket below once the
|
||||
buffer has been returned to the stack. */
|
||||
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The send was successful so the IP stack is now managing
|
||||
the buffer pointed to by pucUDPPayloadBuffer, and the IP
|
||||
stack will return the buffer once it has been sent.
|
||||
pucUDPPayloadBuffer can be safely re-used to receive from
|
||||
the socket below. */
|
||||
}
|
||||
|
||||
/* Keep a count of how many echo requests have been transmitted
|
||||
so it can be compared to the number of echo replies received.
|
||||
It would be expected to loose at least one to an ARP message the
|
||||
first time the connection is created. */
|
||||
ulTxCount++;
|
||||
|
||||
/* Receive data on the socket. ulFlags has the zero copy bit set
|
||||
(FREERTOS_ZERO_COPY) indicating to the stack that a reference to
|
||||
the received data should be passed out to this task using the
|
||||
second parameter to the FreeRTOS_recvfrom() call. When this is
|
||||
done the IP stack is no longer responsible for releasing the
|
||||
buffer, and the task *must* return the buffer to the stack when
|
||||
it is no longer needed. By default the receive block time is
|
||||
portMAX_DELAY. */
|
||||
echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopyReceiveEvent );
|
||||
lReturned = FreeRTOS_recvfrom( xSocket, /* The socket to receive from. */
|
||||
( void * ) &pucUDPPayloadBuffer, /* pucUDPPayloadBuffer will be set to point to the buffer that already contains the received data. */
|
||||
0, /* Ignored because the zero copy interface is being used. */
|
||||
FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */
|
||||
&xEchoServerAddress, /* The address from which the data was sent. */
|
||||
&xAddressLength );
|
||||
|
||||
if( lReturned > 0 )
|
||||
{
|
||||
/* Compare the string sent to the echo server with the string
|
||||
received back from the echo server. */
|
||||
if( strcmp( ( char * ) pucUDPPayloadBuffer, cTxString ) == 0 )
|
||||
{
|
||||
/* The strings matched. */
|
||||
ulRxCount++;
|
||||
}
|
||||
|
||||
/* The buffer that contains the data passed out of the stack
|
||||
*must* be returned to the stack. */
|
||||
FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pause for a short while to ensure the network is not too
|
||||
congested. */
|
||||
vTaskDelay( echoLOOP_DELAY );
|
||||
|
||||
/* Close this socket before looping back to create another. */
|
||||
FreeRTOS_closesocket( xSocket );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef TWO_ECHO_CLIENTS_H
|
||||
#define TWO_ECHO_CLIENTS_H
|
||||
|
||||
/*
|
||||
* Create the two UDP echo client tasks. One task uses the standard interface
|
||||
* to send to and receive from an echo server. The other task uses the zero
|
||||
* copy interface to send to and receive from an echo server.
|
||||
*/
|
||||
void vStartEchoClientTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority );
|
||||
|
||||
#endif /* TWO_ECHO_CLIENTS_H */
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file, along with DemoIPTrace.h, provides a basic example use of the
|
||||
* FreeRTOS+UDP trace macros. The statistics gathered here can be viewed in
|
||||
* the command line interface.
|
||||
* See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/UDP_IP_Trace.shtml
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+UDP includes. */
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "DemoIPTrace.h"
|
||||
|
||||
/* It is possible to remove the trace macros using the
|
||||
configINCLUDE_DEMO_DEBUG_STATS setting in FreeRTOSIPConfig.h. */
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS == 1
|
||||
|
||||
/*
|
||||
* Each row in the xIPTraceValues[] table contains a pointer to a function that
|
||||
* updates the value for that row. Rows that latch the lowest value point to
|
||||
* this function (for example, this function can be used to latch the lowest
|
||||
* number of network buffers that were available during the execution of the
|
||||
* stack).
|
||||
*/
|
||||
static void prvStoreLowest( uint32_t *pulCurrentValue, uint32_t ulCount );
|
||||
|
||||
/*
|
||||
* Each row in the xIPTraceValues[] table contains a pointer to a function that
|
||||
* updates the value for that row. Rows that simply increment an event count
|
||||
* point to this function.
|
||||
*/
|
||||
static void prvIncrementEventCount( uint32_t *pulCurrentValue, uint32_t ulCount );
|
||||
|
||||
|
||||
xExampleDebugStatEntry_t xIPTraceValues[] =
|
||||
{
|
||||
/* Comment out array entries to remove individual trace items. */
|
||||
|
||||
{ iptraceID_NETWORK_INTERFACE_RECEIVE, ( const uint8_t * const ) "Packets received by the network interface", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_NETWORK_INTERFACE_TRANSMIT, ( const uint8_t * const ) "Count of transmitted packets", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_PACKET_DROPPED_TO_GENERATE_ARP, ( const uint8_t * const ) "Count of packets dropped to generate ARP", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_NETWORK_BUFFER_OBTAINED, ( const uint8_t * const ) "Lowest ever available network buffers", prvStoreLowest, 0xffffUL },
|
||||
{ iptraceID_NETWORK_EVENT_RECEIVED, ( const uint8_t * const ) "Lowest ever free space in network event queue", prvStoreLowest, 0xffffUL },
|
||||
{ iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER, ( const uint8_t * const ) "Count of failed attempts to obtain a network buffer",prvIncrementEventCount, 0 },
|
||||
{ iptraceID_ARP_TABLE_ENTRY_EXPIRED, ( const uint8_t * const ) "Count of expired ARP entries", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_FAILED_TO_CREATE_SOCKET, ( const uint8_t * const ) "Count of failures to create a socket", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_RECVFROM_DISCARDING_BYTES, ( const uint8_t * const ) "Count of times recvfrom() has discarding bytes", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_ETHERNET_RX_EVENT_LOST, ( const uint8_t * const ) "Count of lost Ethenret Rx events (event queue full?)",prvIncrementEventCount, 0 },
|
||||
{ iptraceID_STACK_TX_EVENT_LOST, ( const uint8_t * const ) "Count of lost IP stack events (event queue full?)", prvIncrementEventCount, 0 },
|
||||
{ ipconfigID_BIND_FAILED, ( const uint8_t * const ) "Count of failed calls to bind()", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_RECVFROM_TIMEOUT, ( const uint8_t * const ) "Count of receive timeouts", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_SENDTO_DATA_TOO_LONG, ( const uint8_t * const ) "Count of failed sends due to oversized payload", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_SENDTO_SOCKET_NOT_BOUND, ( const uint8_t * const ) "Count of failed sends due to unbound socket", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_NO_BUFFER_FOR_SENDTO, ( const uint8_t * const ) "Count of failed transmits due to timeout", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR, ( const uint8_t * const ) "Number of times task had to wait to obtain a DMA Tx descriptor", prvIncrementEventCount, 0 },
|
||||
{ iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP, ( const uint8_t * const ) "Failed to notify select group", prvIncrementEventCount, 0 }
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xExampleDebugStatEntries( void )
|
||||
{
|
||||
/* Return the number of entries in the xIPTraceValues[] table. */
|
||||
return ( BaseType_t ) ( sizeof( xIPTraceValues ) / sizeof( xExampleDebugStatEntry_t ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vExampleDebugStatUpdate( uint8_t ucIdentifier, uint32_t ulValue )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
const BaseType_t xEntries = sizeof( xIPTraceValues ) / sizeof( xExampleDebugStatEntry_t );
|
||||
|
||||
/* Update an entry in the xIPTraceValues[] table. Each row in the table
|
||||
includes a pointer to a function that performs the actual update. This
|
||||
function just executes the update function from that table row. */
|
||||
for( xIndex = 0; xIndex < xEntries; xIndex++ )
|
||||
{
|
||||
if( xIPTraceValues[ xIndex ].ucIdentifier == ucIdentifier )
|
||||
{
|
||||
xIPTraceValues[ xIndex ].vPerformAction( &( xIPTraceValues[ xIndex ].ulData ), ulValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
configASSERT( xIndex != xEntries );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvIncrementEventCount( uint32_t *pulCurrentValue, uint32_t ulCount )
|
||||
{
|
||||
/* Each row in the xIPTraceValues[] table contains a pointer to a function
|
||||
that updates the value for that row. Rows that simply increment an event
|
||||
count point to this function. */
|
||||
( void ) ulCount;
|
||||
( *pulCurrentValue )++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvStoreLowest( uint32_t *pulCurrentValue, uint32_t ulCount )
|
||||
{
|
||||
/* Each row in the xIPTraceValues[] table contains a pointer to a function
|
||||
that updates the value for that row. Rows that latch the lowest value
|
||||
point to this function (for example, this function can be used to latch
|
||||
the lowest number of network buffers that were available during the
|
||||
execution of the stack). */
|
||||
if( ulCount < *pulCurrentValue )
|
||||
{
|
||||
*pulCurrentValue = ulCount;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS == 1 */
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file, along with DemoIPTrace.h, provides a basic example use of the
|
||||
* FreeRTOS+UDP trace macros. The statistics gathered here can be viewed in
|
||||
* the command line interface.
|
||||
* See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/UDP_IP_Trace.shtml
|
||||
*/
|
||||
|
||||
#ifndef DEMO_IP_TRACE_MACROS_H
|
||||
#define DEMO_IP_TRACE_MACROS_H
|
||||
|
||||
typedef void ( *vTraceAction_t )( uint32_t *, uint32_t );
|
||||
|
||||
/* Type that defines each statistic being gathered. */
|
||||
typedef struct ExampleDebugStatEntry
|
||||
{
|
||||
uint8_t ucIdentifier; /* Unique identifier for statistic. */
|
||||
const uint8_t * const pucDescription; /* Text description for the statistic. */
|
||||
vTraceAction_t vPerformAction; /* Action to perform when the statistic is updated (increment counter, store minimum value, store maximum value, etc. */
|
||||
uint32_t ulData; /* The meaning of this data is dependent on the trace macro ID. */
|
||||
} xExampleDebugStatEntry_t;
|
||||
|
||||
/* Unique identifiers used to locate the entry for each trace macro in the
|
||||
xIPTraceValues[] table defined in DemoIPTrace.c. */
|
||||
#define iptraceID_NETWORK_INTERFACE_RECEIVE 0
|
||||
#define iptraceID_NETWORK_INTERFACE_TRANSMIT 1
|
||||
#define iptraceID_PACKET_DROPPED_TO_GENERATE_ARP 2
|
||||
/* Do not change IDs above this line as the ID is shared with a FreeRTOS+Nabto
|
||||
demo. */
|
||||
#define iptraceID_NETWORK_BUFFER_OBTAINED 3
|
||||
#define iptraceID_NETWORK_BUFFER_OBTAINED_FROM_ISR 4
|
||||
#define iptraceID_NETWORK_EVENT_RECEIVED 5
|
||||
#define iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER 6
|
||||
#define iptraceID_ARP_TABLE_ENTRY_EXPIRED 7
|
||||
#define iptraceID_FAILED_TO_CREATE_SOCKET 8
|
||||
#define iptraceID_RECVFROM_DISCARDING_BYTES 9
|
||||
#define iptraceID_ETHERNET_RX_EVENT_LOST 10
|
||||
#define iptraceID_STACK_TX_EVENT_LOST 11
|
||||
#define ipconfigID_BIND_FAILED 12
|
||||
#define iptraceID_RECVFROM_TIMEOUT 13
|
||||
#define iptraceID_SENDTO_DATA_TOO_LONG 14
|
||||
#define iptraceID_SENDTO_SOCKET_NOT_BOUND 15
|
||||
#define iptraceID_NO_BUFFER_FOR_SENDTO 16
|
||||
#define iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR 17
|
||||
#define iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP 18
|
||||
|
||||
/* It is possible to remove the trace macros using the
|
||||
configINCLUDE_DEMO_DEBUG_STATS setting in FreeRTOSIPConfig.h. */
|
||||
#if configINCLUDE_DEMO_DEBUG_STATS == 1
|
||||
|
||||
/* The trace macro definitions themselves. Any trace macros left undefined
|
||||
will default to be empty macros. */
|
||||
#define iptraceNETWORK_BUFFER_OBTAINED( pxBufferAddress ) vExampleDebugStatUpdate( iptraceID_NETWORK_BUFFER_OBTAINED, uxQueueMessagesWaiting( ( xQueueHandle ) xNetworkBufferSemaphore ) )
|
||||
#define iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxBufferAddress ) vExampleDebugStatUpdate( iptraceID_NETWORK_BUFFER_OBTAINED, uxQueueMessagesWaiting( ( xQueueHandle ) xNetworkBufferSemaphore ) )
|
||||
|
||||
#define iptraceNETWORK_EVENT_RECEIVED( eEvent ) { \
|
||||
uint16_t usSpace; \
|
||||
usSpace = ( uint16_t ) uxQueueMessagesWaiting( xNetworkEventQueue ); \
|
||||
/* Minus one as an event was removed before the space was queried. */ \
|
||||
usSpace = ( ipconfigEVENT_QUEUE_LENGTH - usSpace ) - 1; \
|
||||
vExampleDebugStatUpdate( iptraceID_NETWORK_EVENT_RECEIVED, usSpace ); \
|
||||
}
|
||||
|
||||
#define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER() vExampleDebugStatUpdate( iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER, 0 )
|
||||
#define iptraceARP_TABLE_ENTRY_EXPIRED( ulIPAddress ) vExampleDebugStatUpdate( iptraceID_ARP_TABLE_ENTRY_EXPIRED, 0 )
|
||||
#define iptracePACKET_DROPPED_TO_GENERATE_ARP( ulIPAddress ) vExampleDebugStatUpdate( iptraceID_PACKET_DROPPED_TO_GENERATE_ARP, 0 )
|
||||
#define iptraceFAILED_TO_CREATE_SOCKET() vExampleDebugStatUpdate( iptraceID_FAILED_TO_CREATE_SOCKET, 0 )
|
||||
#define iptraceRECVFROM_DISCARDING_BYTES( xNumberOfBytesDiscarded ) vExampleDebugStatUpdate( iptraceID_RECVFROM_DISCARDING_BYTES, 0 )
|
||||
#define iptraceETHERNET_RX_EVENT_LOST() vExampleDebugStatUpdate( iptraceID_ETHERNET_RX_EVENT_LOST, 0 )
|
||||
#define iptraceSTACK_TX_EVENT_LOST( xEvent ) vExampleDebugStatUpdate( iptraceID_STACK_TX_EVENT_LOST, 0 )
|
||||
#define iptraceBIND_FAILED( xSocket, usPort ) vExampleDebugStatUpdate( ipconfigID_BIND_FAILED, 0 )
|
||||
#define iptraceNETWORK_INTERFACE_TRANSMIT() vExampleDebugStatUpdate( iptraceID_NETWORK_INTERFACE_TRANSMIT, 0 )
|
||||
#define iptraceRECVFROM_TIMEOUT() vExampleDebugStatUpdate( iptraceID_RECVFROM_TIMEOUT, 0 )
|
||||
#define iptraceSENDTO_DATA_TOO_LONG() vExampleDebugStatUpdate( iptraceID_SENDTO_DATA_TOO_LONG, 0 )
|
||||
#define iptraceSENDTO_SOCKET_NOT_BOUND() vExampleDebugStatUpdate( iptraceID_SENDTO_SOCKET_NOT_BOUND, 0 )
|
||||
#define iptraceNO_BUFFER_FOR_SENDTO() vExampleDebugStatUpdate( iptraceID_NO_BUFFER_FOR_SENDTO, 0 )
|
||||
#define iptraceWAITING_FOR_TX_DMA_DESCRIPTOR() vExampleDebugStatUpdate( iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR, 0 )
|
||||
#define iptraceFAILED_TO_NOTIFY_SELECT_GROUP( xSocket ) vExampleDebugStatUpdate( iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP, 0 )
|
||||
#define iptraceNETWORK_INTERFACE_RECEIVE() vExampleDebugStatUpdate( iptraceID_NETWORK_INTERFACE_RECEIVE, 0 )
|
||||
|
||||
/*
|
||||
* The function that updates a line in the xIPTraceValues table.
|
||||
*/
|
||||
void vExampleDebugStatUpdate( uint8_t ucIdentifier, uint32_t ulValue );
|
||||
|
||||
/*
|
||||
* Returns the number of entries in the xIPTraceValues table.
|
||||
*/
|
||||
BaseType_t xExampleDebugStatEntries( void );
|
||||
|
||||
#endif /* configINCLUDE_DEMO_DEBUG_STATS == 1 */
|
||||
|
||||
|
||||
#endif /* DEMO_IP_TRACE_MACROS_H */
|
||||
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
* http://www.freertos.org/a00110.html
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */
|
||||
#define configMAX_TASK_NAME_LEN ( 7 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 0
|
||||
#define configUSE_APPLICATION_TASK_TAG 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY 2
|
||||
#define configTIMER_QUEUE_LENGTH 20
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
#define configMAX_PRIORITIES ( 7 )
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Hook functions */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTimerGetTimerTaskHandle 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xQueueGetMutexHolder 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xEventGroupSetBitsFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
|
||||
/* heap_4.c, */
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) )
|
||||
|
||||
/* Allow RTOS objects to be created using RAM provided by the application writer. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
|
||||
/* Create RTOS objects using dynamically allocated RAM */
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
|
||||
/* This demo makes use of one or more example stats formatting functions. These
|
||||
format the raw data provided by the uxTaskGetSystemState() function in to human
|
||||
readable ASCII form. See the notes in the implementation of vTaskList() within
|
||||
FreeRTOS/Source/tasks.c for limitations. */
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
|
||||
/* Run time stats gathering definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
|
||||
/* Assert call defined for debug builds. */
|
||||
extern void vAssertCalled(const char * pcFile, uint32_t ulLine);
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>
|
||||
<ProjectName>RTOS_POSIX_Demo</ProjectName>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Midl>
|
||||
<TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>
|
||||
<HeaderFileName>
|
||||
</HeaderFileName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\FreeRTOS-Plus-POSIX\include\portable\pc\windows;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\FreeRTOS-Plus-POSIX\include\portable;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\FreeRTOS-Plus-POSIX\include;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\FreeRTOS-Plus-POSIX\source;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\include\private;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\third_party\win_pcap;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator\lib\include;..\..\..\FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator;..\..\..\FreeRTOS\Demo\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0c09</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<OutputFile>.\Debug/RTOS_POSIX_demo.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Debug/WIN32.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Midl>
|
||||
<TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>
|
||||
<HeaderFileName>
|
||||
</HeaderFileName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0c09</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<OutputFile>.\Release/RTOSDemo.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release/WIN32.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\croutine.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\event_groups.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\list.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\queue.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\stream_buffer.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c" />
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\timers.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_clock.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_mqueue.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread_barrier.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread_mutex.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread_cond.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_sched.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_semaphore.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_timer.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_unistd.c" />
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_utils.c" />
|
||||
<ClCompile Include="main.c">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="posix_demo.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\portmacro.h" />
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\FreeRTOS_POSIX.h" />
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\FreeRTOS_POSIX_internal.h" />
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\portable\FreeRTOS_POSIX_portable_default.h" />
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\portable\pc\windows\FreeRTOS_POSIX_portable.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\errno.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\fcntl.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\mqueue.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\pthread.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\sched.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\semaphore.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\signal.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\sys\types.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\time.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\unistd.h" />
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\utils.h" />
|
||||
<ClInclude Include=".\lib\include\private\aws_doubly_linked_list.h" />
|
||||
<ClInclude Include="FreeRTOSConfig.h" />
|
||||
<ClInclude Include="posix_demo.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="application_code">
|
||||
<UniqueIdentifier>{34567deb-d5ab-4a56-8640-0aaec609521a}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="lib">
|
||||
<UniqueIdentifier>{e3396fdf-de1f-4cb9-975c-673cb9315287}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\include">
|
||||
<UniqueIdentifier>{02f5b936-2f92-411d-89d3-985520c10e9d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\include\FreeRTOS_POSIX">
|
||||
<UniqueIdentifier>{1f6970f5-2901-4d3b-a119-86195fed3601}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\include\FreeRTOS_POSIX\sys">
|
||||
<UniqueIdentifier>{63611657-d97d-479c-af87-69d6817b564d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS-Plus-POSIX">
|
||||
<UniqueIdentifier>{7c2a7031-ca15-4d3e-838e-efe7b508f899}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS-Plus-POSIX\include">
|
||||
<UniqueIdentifier>{dddb94ad-d701-41db-ab34-8fd5b9b4d2db}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS-Plus-POSIX\source">
|
||||
<UniqueIdentifier>{db0fccd4-1177-4630-8a6d-b1ea48d0b0fa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS">
|
||||
<UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\include\private">
|
||||
<UniqueIdentifier>{26ccdf01-559e-4934-9311-bd1a25bdd658}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="configuration_files">
|
||||
<UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>
|
||||
<Extensions>
|
||||
</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS\Portable">
|
||||
<UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS\Portable\MemMang">
|
||||
<UniqueIdentifier>{a4b373f5-dc97-40ff-9b67-118253049621}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="lib\FreeRTOS\Portable\MSVC-W">
|
||||
<UniqueIdentifier>{0447c18c-e805-43d8-8b36-744f7c7fb88f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>application_code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_clock.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_mqueue.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread_barrier.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread_cond.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_pthread_mutex.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_sched.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_semaphore.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_timer.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_unistd.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\lib\FreeRTOS-Plus-POSIX\source\FreeRTOS_POSIX_utils.c">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">
|
||||
<Filter>lib\FreeRTOS\Portable\MemMang</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">
|
||||
<Filter>lib\FreeRTOS\Portable\MSVC-W</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\croutine.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\event_groups.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\list.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\queue.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\stream_buffer.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\FreeRTOS\Source\timers.c">
|
||||
<Filter>lib\FreeRTOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="posix_demo.c">
|
||||
<Filter>application_code</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="FreeRTOSConfig.h">
|
||||
<Filter>configuration_files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\FreeRTOS_POSIX.h">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\FreeRTOS_POSIX_internal.h">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\portable\pc\windows\FreeRTOS_POSIX_portable.h">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\FreeRTOS-Plus-POSIX\include\portable\FreeRTOS_POSIX_portable_default.h">
|
||||
<Filter>lib\FreeRTOS-Plus-POSIX\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\private\aws_doubly_linked_list.h">
|
||||
<Filter>lib\include\private</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\errno.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\fcntl.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\mqueue.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\pthread.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\sched.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\semaphore.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\signal.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\time.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\unistd.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\utils.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\lib\include\FreeRTOS_POSIX\sys\types.h">
|
||||
<Filter>lib\include\FreeRTOS_POSIX\sys</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\portmacro.h">
|
||||
<Filter>lib\FreeRTOS\Portable\MSVC-W</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="posix_demo.h">
|
||||
<Filter>application_code</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX.h
|
||||
* @brief FreeRTOS+POSIX header.
|
||||
*
|
||||
* This file must be included before all other FreeRTOS+POSIX includes.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_H_
|
||||
#define _FREERTOS_POSIX_H_
|
||||
|
||||
/* FreeRTOS+POSIX platform-specific configuration headers. */
|
||||
#include "FreeRTOS_POSIX_portable.h"
|
||||
#include "portable/FreeRTOS_POSIX_portable_default.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "event_groups.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+POSIX data types and internal structs. */
|
||||
#include "FreeRTOS_POSIX/sys/types.h"
|
||||
#include "FreeRTOS_POSIX_internal.h"
|
||||
|
||||
#endif /* _FREERTOS_POSIX_H_ */
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_INTERNAL_H_
|
||||
#define _FREERTOS_POSIX_INTERNAL_H_
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_internal.h
|
||||
* @brief Internal structs and initializers for FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
/* Amazon FreeRTOS includes. */
|
||||
#include "aws_doubly_linked_list.h"
|
||||
|
||||
/**
|
||||
* @brief Mutex attribute object.
|
||||
*/
|
||||
typedef struct pthread_mutexattr_internal
|
||||
{
|
||||
int iType; /**< Mutex type. */
|
||||
} pthread_mutexattr_internal_t;
|
||||
|
||||
/**
|
||||
* @brief Mutex.
|
||||
*/
|
||||
typedef struct pthread_mutex_internal
|
||||
{
|
||||
BaseType_t xIsInitialized; /**< Set to pdTRUE if this mutex is initialized, pdFALSE otherwise. */
|
||||
StaticSemaphore_t xMutex; /**< FreeRTOS mutex. */
|
||||
TaskHandle_t xTaskOwner; /**< Owner; used for deadlock detection and permission checks. */
|
||||
pthread_mutexattr_internal_t xAttr; /**< Mutex attributes. */
|
||||
} pthread_mutex_internal_t;
|
||||
|
||||
/**
|
||||
* @brief Compile-time initializer of pthread_mutex_internal_t.
|
||||
*/
|
||||
#define FREERTOS_POSIX_MUTEX_INITIALIZER \
|
||||
( &( ( pthread_mutex_internal_t ) \
|
||||
{ \
|
||||
.xIsInitialized = pdFALSE, \
|
||||
.xMutex = { { 0 } }, \
|
||||
.xTaskOwner = NULL, \
|
||||
.xAttr = { .iType = 0 } \
|
||||
} \
|
||||
) \
|
||||
)
|
||||
|
||||
/**
|
||||
* @brief Condition variable.
|
||||
*/
|
||||
typedef struct pthread_cond_internal
|
||||
{
|
||||
BaseType_t xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */
|
||||
StaticSemaphore_t xCondMutex; /**< Prevents concurrent accesses to iWaitingThreads. */
|
||||
StaticSemaphore_t xCondWaitSemaphore; /**< Threads block on this semaphore in pthread_cond_wait. */
|
||||
int iWaitingThreads; /**< The number of threads currently waiting on this condition variable. */
|
||||
} pthread_cond_internal_t;
|
||||
|
||||
/**
|
||||
* @brief Compile-time initializer of pthread_cond_internal_t.
|
||||
*/
|
||||
#define FREERTOS_POSIX_COND_INITIALIZER \
|
||||
( &( ( pthread_cond_internal_t ) \
|
||||
{ \
|
||||
.xIsInitialized = pdFALSE, \
|
||||
.xCondMutex = { { 0 } }, \
|
||||
.xCondWaitSemaphore = { { 0 } },\
|
||||
.iWaitingThreads = 0 \
|
||||
} \
|
||||
) \
|
||||
)
|
||||
|
||||
#endif /* _FREERTOS_POSIX_INTERNAL_H_ */
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable_default.h
|
||||
* @brief Defaults for port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_DEFAULT_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_DEFAULT_H_
|
||||
|
||||
/**
|
||||
* @brief The FreeRTOS task name given to pthreads.
|
||||
*/
|
||||
#ifndef posixconfigPTHREAD_TASK_NAME
|
||||
#define posixconfigPTHREAD_TASK_NAME "pthread"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief the FreeRTOS timer name given to POSIX timers.
|
||||
*/
|
||||
#ifndef posixconfigTIMER_NAME
|
||||
#define posixconfigTIMER_NAME "timer"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup Defaults for POSIX message queue implementation.
|
||||
*/
|
||||
/**@{ */
|
||||
#ifndef posixconfigMQ_MAX_MESSAGES
|
||||
#define posixconfigMQ_MAX_MESSAGES 10 /**< Maximum number of messages in an mq at one time. */
|
||||
#endif
|
||||
|
||||
#ifndef posixconfigMQ_MAX_SIZE
|
||||
#define posixconfigMQ_MAX_SIZE 128 /**< Maximum size (in bytes) of each message. */
|
||||
#endif
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @defgroup POSIX implementation-dependent constants usually defined in limits.h.
|
||||
*
|
||||
* They are defined here to provide portability between platforms.
|
||||
*/
|
||||
/**@{ */
|
||||
#ifndef PTHREAD_STACK_MIN
|
||||
#define PTHREAD_STACK_MIN configMINIMAL_STACK_SIZE * sizeof( StackType_t ) /**< Minimum size in bytes of thread stack storage. */
|
||||
#endif
|
||||
#ifndef NAME_MAX
|
||||
#define NAME_MAX 64 /**< Maximum number of bytes in a filename (not including terminating null). */
|
||||
#endif
|
||||
#ifndef SEM_VALUE_MAX
|
||||
#define SEM_VALUE_MAX 0xFFFFU /**< Maximum value of a sem_t. */
|
||||
#endif
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @defgroup Enable typedefs of POSIX types.
|
||||
*
|
||||
* Set these values to 1 or 0 to enable or disable the typedefs, respectively.
|
||||
* These typedefs should only be disabled if they conflict with system typedefs.
|
||||
*/
|
||||
/**@{ */
|
||||
#ifndef posixconfigENABLE_CLOCK_T
|
||||
#define posixconfigENABLE_CLOCK_T 1 /**< clock_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_CLOCKID_T
|
||||
#define posixconfigENABLE_CLOCKID_T 1 /**< clockid_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_MODE_T
|
||||
#define posixconfigENABLE_MODE_T 1 /**< mode_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PID_T
|
||||
#define posixconfigENABLE_PID_T 1 /**< pid_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PTHREAD_ATTR_T
|
||||
#define posixconfigENABLE_PTHREAD_ATTR_T 1 /**< pthread_attr_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PTHREAD_COND_T
|
||||
#define posixconfigENABLE_PTHREAD_COND_T 1 /**< pthread_cond_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PTHREAD_CONDATTR_T
|
||||
#define posixconfigENABLE_PTHREAD_CONDATTR_T 1 /**< pthread_condattr_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PTHREAD_MUTEX_T
|
||||
#define posixconfigENABLE_PTHREAD_MUTEX_T 1 /**< pthread_mutex_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PTHREAD_MUTEXATTR_T
|
||||
#define posixconfigENABLE_PTHREAD_MUTEXATTR_T 1 /**< pthread_mutexattr_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_PTHREAD_T
|
||||
#define posixconfigENABLE_PTHREAD_T 1 /**< pthread_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_SSIZE_T
|
||||
#define posixconfigENABLE_SSIZE_T 1 /**< ssize_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_TIME_T
|
||||
#define posixconfigENABLE_TIME_T 1 /**< time_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_TIMER_T
|
||||
#define posixconfigENABLE_TIMER_T 1 /**< timer_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_USECONDS_T
|
||||
#define posixconfigENABLE_USECONDS_T 1 /**< useconds_t in sys/types.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_TIMESPEC
|
||||
#define posixconfigENABLE_TIMESPEC 1 /**< struct timespec in time.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_ITIMERSPEC
|
||||
#define posixconfigENABLE_ITIMERSPEC 1 /**< struct itimerspec in time.h */
|
||||
#endif
|
||||
#ifndef posixconfigENABLE_TM
|
||||
#define posixconfigENABLE_TM 1 /**< struct tm in time.h */
|
||||
#endif
|
||||
/**@} */
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_PORTABLE_DEFAULT_H_ */
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable.h
|
||||
* @brief Port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_H_
|
||||
|
||||
/* ESP-IDF already defines the following types. */
|
||||
#define posixconfigENABLE_CLOCK_T 0
|
||||
#define posixconfigENABLE_CLOCKID_T 0
|
||||
#define posixconfigENABLE_MODE_T 0
|
||||
#define posixconfigENABLE_PTHREAD_ATTR_T 0
|
||||
#define posixconfigENABLE_PTHREAD_COND_T 0
|
||||
#define posixconfigENABLE_PTHREAD_CONDATTR_T 0
|
||||
#define posixconfigENABLE_PTHREAD_MUTEX_T 0
|
||||
#define posixconfigENABLE_PTHREAD_MUTEXATTR_T 0
|
||||
#define posixconfigENABLE_PTHREAD_T 0
|
||||
#define posixconfigENABLE_TIME_T 0
|
||||
#define posixconfigENABLE_TIMER_T 0
|
||||
#define posixconfigENABLE_TIMESPEC 0
|
||||
#define posixconfigENABLE_ITIMERSPEC 0
|
||||
|
||||
/* ESP-IDF already provides the header sched.h. Exclude them by
|
||||
* activating the double inclusion guards. */
|
||||
#define _FREERTOS_POSIX_SCHED_H_
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.1
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable.h
|
||||
* @brief Port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_H_
|
||||
|
||||
/* Microchip includes. */
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Microchip already typedefs the following types. */
|
||||
#define posixconfigENABLE_MODE_T 0
|
||||
#define posixconfigENABLE_PID_T 0
|
||||
#define posixconfigENABLE_SSIZE_T 0
|
||||
#define posixconfigENABLE_USECONDS_T 0
|
||||
/* Microchip -mnewlib compiler option supports these types. */
|
||||
#define posixconfigENABLE_TIMESPEC 0
|
||||
#define posixconfigENABLE_ITIMERSPEC 0
|
||||
#define posixconfigENABLE_CLOCKID_T 0
|
||||
#define posixconfigENABLE_TIME_T 0
|
||||
#define posixconfigENABLE_TIMER_T 0
|
||||
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable.h
|
||||
* @brief Port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_H_
|
||||
|
||||
/* This port uses the defaults in FreeRTOS_POSIX_portable_default.h, so this
|
||||
* file is empty. */
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable.h
|
||||
* @brief Port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_H_
|
||||
|
||||
/* This port uses the defaults in FreeRTOS_POSIX_portable_default.h, so this
|
||||
* file is empty. */
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable.h
|
||||
* @brief Port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_H_
|
||||
|
||||
/* This port uses the defaults in FreeRTOS_POSIX_portable_default.h, so this
|
||||
* file is empty. */
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_portable.h
|
||||
* @brief Port-specific configuration of FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PORTABLE_H_
|
||||
#define _FREERTOS_POSIX_PORTABLE_H_
|
||||
|
||||
/* This port uses the defaults in FreeRTOS_POSIX_portable_default.h, so this
|
||||
* file is empty. */
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */
|
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_clock.c
|
||||
* @brief Implementation of clock functions in time.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
clock_t clock( void )
|
||||
{
|
||||
/* Return the amount of time since the scheduler started that wasn't spent
|
||||
* in the idle task. */
|
||||
return ( clock_t ) ( xTaskGetTickCount() - xTaskGetIdleTickCount() );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int clock_getcpuclockid( pid_t pid,
|
||||
clockid_t * clock_id )
|
||||
{
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) pid;
|
||||
( void ) clock_id;
|
||||
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int clock_getres( clockid_t clock_id,
|
||||
struct timespec * res )
|
||||
{
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) clock_id;
|
||||
|
||||
/* Convert FreeRTOS tick resolution as timespec. */
|
||||
if( res != NULL )
|
||||
{
|
||||
res->tv_sec = 0;
|
||||
res->tv_nsec = NANOSECONDS_PER_TICK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int clock_gettime( clockid_t clock_id,
|
||||
struct timespec * tp )
|
||||
{
|
||||
TimeOut_t xCurrentTime = { 0 };
|
||||
int iStatus = 0;
|
||||
|
||||
/* Intermediate variable used to convert TimeOut_t to struct timespec.
|
||||
* Also used to detect overflow issues. It must be unsigned because the
|
||||
* behavior of signed integer overflow is undefined. */
|
||||
uint64_t ullTickCount = 0ULL;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) clock_id;
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Get the current tick count and overflow count. vTaskSetTimeOutState()
|
||||
* is used to get these values because they are both static in tasks.c. */
|
||||
vTaskSetTimeOutState( &xCurrentTime );
|
||||
|
||||
/* Adjust the tick count for the number of times a TickType_t has overflowed.
|
||||
* portMAX_DELAY should be the maximum value of a TickType_t. */
|
||||
ullTickCount = ( uint64_t ) ( xCurrentTime.xOverflowCount ) << ( sizeof( TickType_t ) * 8 );
|
||||
|
||||
/* Add the current tick count. */
|
||||
ullTickCount += xCurrentTime.xTimeOnEntering;
|
||||
|
||||
/* Convert ullTickCount to timespec. */
|
||||
UTILS_NanosecondsToTimespec( ( int64_t ) ullTickCount * NANOSECONDS_PER_TICK, tp );
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int clock_nanosleep( clockid_t clock_id,
|
||||
int flags,
|
||||
const struct timespec * rqtp,
|
||||
struct timespec * rmtp )
|
||||
{
|
||||
int iStatus = 0;
|
||||
TickType_t xSleepTime = 0;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) clock_id;
|
||||
( void ) rmtp;
|
||||
( void ) flags; /* This is only ignored if INCLUDE_vTaskDelayUntil is 0. */
|
||||
|
||||
/* Check rqtp. */
|
||||
if( UTILS_ValidateTimespec( rqtp ) == false )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Check for absolute time sleep. */
|
||||
if( ( flags & TIMER_ABSTIME ) == TIMER_ABSTIME )
|
||||
{
|
||||
/* Get number of ticks until absolute time. */
|
||||
if( UTILS_AbsoluteTimespecToTicks( rqtp, &xSleepTime ) == 0 )
|
||||
{
|
||||
/* Delay until absolute time if vTaskDelayUntil is available. */
|
||||
#if ( INCLUDE_vTaskDelayUntil == 1 )
|
||||
|
||||
/* Get the current tick count. This variable isn't declared
|
||||
* at the top of the function because it's only used and needed
|
||||
* if vTaskDelayUntil is available. */
|
||||
TickType_t xCurrentTicks = xTaskGetTickCount();
|
||||
|
||||
/* Delay until absolute time. */
|
||||
vTaskDelayUntil( &xCurrentTicks, xSleepTime );
|
||||
#else
|
||||
|
||||
/* If vTaskDelayUntil isn't available, ignore the TIMER_ABSTIME flag
|
||||
* and sleep for a relative time. */
|
||||
vTaskDelay( xSleepTime );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If TIMER_ABSTIME isn't specified, convert rqtp to ticks and
|
||||
* sleep for a relative time. */
|
||||
if( UTILS_TimespecToTicks( rqtp, &xSleepTime ) == 0 )
|
||||
{
|
||||
vTaskDelay( xSleepTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int clock_settime( clockid_t clock_id,
|
||||
const struct timespec * tp )
|
||||
{
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) clock_id;
|
||||
( void ) tp;
|
||||
|
||||
/* This function is currently unsupported. It will always return -1 and
|
||||
* set errno to EPERM. */
|
||||
errno = EPERM;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
struct tm * localtime_r( const time_t * timer,
|
||||
struct tm * result )
|
||||
{
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) timer;
|
||||
( void ) result;
|
||||
|
||||
/* This function is only supported if the "custom" FreeRTOS+POSIX tm struct
|
||||
* is used. */
|
||||
#if ( posixconfigENABLE_TM == 0 )
|
||||
errno = ENOTSUP;
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
|
||||
/* Zero the tm, then store the FreeRTOS tick count. The input parameter
|
||||
* timer isn't used. */
|
||||
( void ) memset( result, 0x00, sizeof( struct tm ) );
|
||||
result->tm_tick = ( time_t ) xTaskGetTickCount();
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int nanosleep( const struct timespec * rqtp,
|
||||
struct timespec * rmtp )
|
||||
{
|
||||
int iStatus = 0;
|
||||
TickType_t xSleepTime = 0;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) rmtp;
|
||||
|
||||
/* Check rqtp. */
|
||||
if( UTILS_ValidateTimespec( rqtp ) == false )
|
||||
{
|
||||
errno = EINVAL;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Convert rqtp to ticks and delay. */
|
||||
if( UTILS_TimespecToTicks( rqtp, &xSleepTime ) == 0 )
|
||||
{
|
||||
vTaskDelay( xSleepTime );
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t strftime( char * s,
|
||||
size_t maxsize,
|
||||
const char * format,
|
||||
const struct tm * timeptr )
|
||||
{
|
||||
int iStatus = 0;
|
||||
size_t bytesPrinted = 0;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) format;
|
||||
|
||||
/* Print the time in the buffer. */
|
||||
iStatus = snprintf( s, maxsize, "%ld", ( long int ) timeptr->tm_tick );
|
||||
|
||||
/* Check for encoding and size errors. */
|
||||
if( ( iStatus > 0 ) && ( ( size_t ) iStatus < maxsize ) )
|
||||
{
|
||||
bytesPrinted = ( size_t ) iStatus;
|
||||
}
|
||||
|
||||
return bytesPrinted;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
time_t time( time_t * tloc )
|
||||
{
|
||||
/* Read the current FreeRTOS tick count and convert it to seconds. */
|
||||
time_t xCurrentTime = ( time_t ) ( xTaskGetTickCount() / configTICK_RATE_HZ );
|
||||
|
||||
/* Set the output parameter if provided. */
|
||||
if( tloc != NULL )
|
||||
{
|
||||
*tloc = xCurrentTime;
|
||||
}
|
||||
|
||||
return xCurrentTime;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,885 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_mqueue.c
|
||||
* @brief Implementation of message queue functions in mqueue.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/fcntl.h"
|
||||
#include "FreeRTOS_POSIX/mqueue.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/**
|
||||
* @brief Element of the FreeRTOS queues that store mq data.
|
||||
*/
|
||||
typedef struct QueueElement
|
||||
{
|
||||
char * pcData; /**< Data in queue. Type char* to match msg_ptr. */
|
||||
size_t xDataSize; /**< Size of data pointed by pcData. */
|
||||
} QueueElement_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure of an mq.
|
||||
*
|
||||
* FreeRTOS isn't guaranteed to have a file-like abstraction, so message
|
||||
* queues in this implementation are stored as a linked list (in RAM).
|
||||
*/
|
||||
typedef struct QueueListElement
|
||||
{
|
||||
Link_t xLink; /**< Pointer to the next element in the list. */
|
||||
QueueHandle_t xQueue; /**< FreeRTOS queue handle. */
|
||||
size_t xOpenDescriptors; /**< Number of threads that have opened this queue. */
|
||||
char * pcName; /**< Null-terminated queue name. */
|
||||
struct mq_attr xAttr; /**< Queue attibutes. */
|
||||
BaseType_t xPendingUnlink; /**< If pdTRUE, this queue will be unlinked once all descriptors close. */
|
||||
} QueueListElement_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Convert an absolute timespec into a tick timeout, taking into account
|
||||
* queue flags.
|
||||
*
|
||||
* @param[in] lMessageQueueFlags Message queue flags to consider.
|
||||
* @param[in] pxAbsoluteTimeout The absolute timespec to convert.
|
||||
* @param[out] pxTimeoutTicks Output parameter of the timeout in ticks.
|
||||
*
|
||||
* @return 0 if successful; EINVAL if pxAbsoluteTimeout is invalid, or ETIMEDOUT
|
||||
* if pxAbsoluteTimeout is in the past.
|
||||
*/
|
||||
static int prvCalculateTickTimeout( long lMessageQueueFlags,
|
||||
const struct timespec * const pxAbsoluteTimeout,
|
||||
TickType_t * pxTimeoutTicks );
|
||||
|
||||
/**
|
||||
* @brief Add a new queue to the queue list.
|
||||
*
|
||||
* @param[out] ppxMessageQueue Pointer to new queue.
|
||||
* @param[in] pxAttr mq_attr of the new queue.
|
||||
* @param[in] pcName Name of new queue.
|
||||
* @param[in] xNameLength Length of pcName.
|
||||
*
|
||||
* @return pdTRUE if the queue is found; pdFALSE otherwise.
|
||||
*/
|
||||
static BaseType_t prvCreateNewMessageQueue( QueueListElement_t ** ppxMessageQueue,
|
||||
const struct mq_attr * const pxAttr,
|
||||
const char * const pcName,
|
||||
size_t xNameLength );
|
||||
|
||||
/**
|
||||
* @brief Free all the resources used by a message queue.
|
||||
*
|
||||
* @param[out] pxMessageQueue Pointer to queue to free.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
static void prvDeleteMessageQueue( const QueueListElement_t * const pxMessageQueue );
|
||||
|
||||
/**
|
||||
* @brief Attempt to find the queue identified by pcName or xMqId in the queue list.
|
||||
*
|
||||
* Matches queues by pcName first; if pcName is NULL, matches by xMqId.
|
||||
* @param[out] ppxQueueListElement Output parameter set when queue is found.
|
||||
* @param[in] pcName A queue name to match.
|
||||
* @param[in] xMessageQueueDescriptor A queue descriptor to match.
|
||||
*
|
||||
* @return pdTRUE if the queue is found; pdFALSE otherwise.
|
||||
*/
|
||||
static BaseType_t prvFindQueueInList( QueueListElement_t ** const ppxQueueListElement,
|
||||
const char * const pcName,
|
||||
mqd_t xMessageQueueDescriptor );
|
||||
|
||||
/**
|
||||
* @brief Initialize the queue list.
|
||||
*
|
||||
* Performs initialization of the queue list mutex and queue list head.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
static void prvInitializeQueueList( void );
|
||||
|
||||
/**
|
||||
* @brief Checks that pcName is a valid name for a message queue.
|
||||
*
|
||||
* Also outputs the length of pcName.
|
||||
* @param[in] pcName The name to check.
|
||||
* @param[out] pxNameLength Output parameter for name length.
|
||||
*
|
||||
* @return pdTRUE if the name is valid; pdFALSE otherwise.
|
||||
*/
|
||||
static BaseType_t prvValidateQueueName( const char * const pcName,
|
||||
size_t * pxNameLength );
|
||||
|
||||
/**
|
||||
* @brief Guards access to the list of message queues.
|
||||
*/
|
||||
static StaticSemaphore_t xQueueListMutex = { { 0 } };
|
||||
|
||||
/**
|
||||
* @brief Head of the linked list of queues.
|
||||
*/
|
||||
static Link_t xQueueListHead = { 0 };
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int prvCalculateTickTimeout( long lMessageQueueFlags,
|
||||
const struct timespec * const pxAbsoluteTimeout,
|
||||
TickType_t * pxTimeoutTicks )
|
||||
{
|
||||
int iStatus = 0;
|
||||
|
||||
/* Check for nonblocking queue. */
|
||||
if( lMessageQueueFlags & O_NONBLOCK )
|
||||
{
|
||||
/* No additional checks are done for nonblocking queues. Timeout is 0. */
|
||||
*pxTimeoutTicks = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No absolute timeout given. Block forever. */
|
||||
if( pxAbsoluteTimeout == NULL )
|
||||
{
|
||||
*pxTimeoutTicks = portMAX_DELAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check that the given timespec is valid. */
|
||||
if( UTILS_ValidateTimespec( pxAbsoluteTimeout ) == false )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
|
||||
/* Convert absolute timespec to ticks. */
|
||||
if( ( iStatus == 0 ) &&
|
||||
( UTILS_AbsoluteTimespecToTicks( pxAbsoluteTimeout, pxTimeoutTicks ) != 0 ) )
|
||||
{
|
||||
iStatus = ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvCreateNewMessageQueue( QueueListElement_t ** ppxMessageQueue,
|
||||
const struct mq_attr * const pxAttr,
|
||||
const char * const pcName,
|
||||
size_t xNameLength )
|
||||
{
|
||||
BaseType_t xStatus = pdTRUE;
|
||||
|
||||
/* Allocate space for a new queue element. */
|
||||
*ppxMessageQueue = pvPortMalloc( sizeof( QueueListElement_t ) );
|
||||
|
||||
/* Check that memory allocation succeeded. */
|
||||
if( *ppxMessageQueue == NULL )
|
||||
{
|
||||
xStatus = pdFALSE;
|
||||
}
|
||||
|
||||
/* Create the FreeRTOS queue. */
|
||||
if( xStatus == pdTRUE )
|
||||
{
|
||||
( *ppxMessageQueue )->xQueue =
|
||||
xQueueCreate( pxAttr->mq_maxmsg, sizeof( QueueElement_t ) );
|
||||
|
||||
/* Check that queue creation succeeded. */
|
||||
if( ( *ppxMessageQueue )->xQueue == NULL )
|
||||
{
|
||||
vPortFree( *ppxMessageQueue );
|
||||
xStatus = pdFALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if( xStatus == pdTRUE )
|
||||
{
|
||||
/* Allocate space for the queue name plus null-terminator. */
|
||||
( *ppxMessageQueue )->pcName = pvPortMalloc( xNameLength + 1 );
|
||||
|
||||
/* Check that memory was successfully allocated for queue name. */
|
||||
if( ( *ppxMessageQueue )->pcName == NULL )
|
||||
{
|
||||
vQueueDelete( ( *ppxMessageQueue )->xQueue );
|
||||
vPortFree( *ppxMessageQueue );
|
||||
xStatus = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy queue name. Copying xNameLength+1 will cause strncpy to add
|
||||
* the null-terminator. */
|
||||
( void ) strncpy( ( *ppxMessageQueue )->pcName, pcName, xNameLength + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( xStatus == pdTRUE )
|
||||
{
|
||||
/* Copy attributes. */
|
||||
( *ppxMessageQueue )->xAttr = *pxAttr;
|
||||
|
||||
/* A newly-created queue will have 1 open descriptor for it. */
|
||||
( *ppxMessageQueue )->xOpenDescriptors = 1;
|
||||
|
||||
/* A newly-created queue will not be pending unlink. */
|
||||
( *ppxMessageQueue )->xPendingUnlink = pdFALSE;
|
||||
|
||||
/* Add the new queue to the list. */
|
||||
listADD( &xQueueListHead, &( *ppxMessageQueue )->xLink );
|
||||
}
|
||||
|
||||
return xStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvDeleteMessageQueue( const QueueListElement_t * const pxMessageQueue )
|
||||
{
|
||||
QueueElement_t xQueueElement = { 0 };
|
||||
|
||||
/* Free all data in the queue. It's assumed that no more data will be added
|
||||
* to the queue, so xQueueReceive does not block. */
|
||||
while( xQueueReceive( pxMessageQueue->xQueue,
|
||||
( void * ) &xQueueElement,
|
||||
0 ) == pdTRUE )
|
||||
{
|
||||
vPortFree( xQueueElement.pcData );
|
||||
}
|
||||
|
||||
/* Free memory used by this message queue. */
|
||||
vQueueDelete( pxMessageQueue->xQueue );
|
||||
vPortFree( ( void * ) pxMessageQueue->pcName );
|
||||
vPortFree( ( void * ) pxMessageQueue );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvFindQueueInList( QueueListElement_t ** const ppxQueueListElement,
|
||||
const char * const pcName,
|
||||
mqd_t xMessageQueueDescriptor )
|
||||
{
|
||||
Link_t * pxQueueListLink = NULL;
|
||||
QueueListElement_t * pxMessageQueue = NULL;
|
||||
BaseType_t xQueueFound = pdFALSE;
|
||||
|
||||
/* Iterate through the list of queues. */
|
||||
listFOR_EACH( pxQueueListLink, &xQueueListHead )
|
||||
{
|
||||
pxMessageQueue = listCONTAINER( pxQueueListLink, QueueListElement_t, xLink );
|
||||
|
||||
/* Match by name first if provided. */
|
||||
if( ( pcName != NULL ) && ( strcmp( pxMessageQueue->pcName, pcName ) == 0 ) )
|
||||
{
|
||||
xQueueFound = pdTRUE;
|
||||
break;
|
||||
}
|
||||
/* If name doesn't match, match by descriptor. */
|
||||
else
|
||||
{
|
||||
if( ( mqd_t ) pxMessageQueue == xMessageQueueDescriptor )
|
||||
{
|
||||
xQueueFound = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the queue was found, set the output parameter. */
|
||||
if( ( xQueueFound == pdTRUE ) && ( ppxQueueListElement != NULL ) )
|
||||
{
|
||||
*ppxQueueListElement = pxMessageQueue;
|
||||
}
|
||||
|
||||
return xQueueFound;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitializeQueueList( void )
|
||||
{
|
||||
/* Keep track of whether the queue list has been initialized. */
|
||||
static BaseType_t xQueueListInitialized = pdFALSE;
|
||||
|
||||
/* Check if queue list needs to be initialized. */
|
||||
if( xQueueListInitialized == pdFALSE )
|
||||
{
|
||||
/* Initialization must be in a critical section to prevent two threads
|
||||
* from initializing at the same time. */
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* Check again that queue list is still uninitialized, i.e. it wasn't
|
||||
* initialized while this function was waiting to enter the critical
|
||||
* section. */
|
||||
if( xQueueListInitialized == pdFALSE )
|
||||
{
|
||||
/* Initialize the queue list mutex and list head. */
|
||||
( void ) xSemaphoreCreateMutexStatic( &xQueueListMutex );
|
||||
listINIT_HEAD( &xQueueListHead );
|
||||
xQueueListInitialized = pdTRUE;
|
||||
}
|
||||
|
||||
/* Exit the critical section. */
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvValidateQueueName( const char * const pcName,
|
||||
size_t * pxNameLength )
|
||||
{
|
||||
BaseType_t xStatus = pdTRUE;
|
||||
size_t xNameLength = 0;
|
||||
|
||||
/* All message queue names must start with '/'. */
|
||||
if( pcName[ 0 ] != '/' )
|
||||
{
|
||||
xStatus = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the length of pcName, excluding the first '/' and null-terminator. */
|
||||
xNameLength = UTILS_strnlen( pcName, NAME_MAX + 2 );
|
||||
|
||||
if( xNameLength == NAME_MAX + 2 )
|
||||
{
|
||||
/* Name too long. */
|
||||
xStatus = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Name length passes, set output parameter. */
|
||||
*pxNameLength = xNameLength;
|
||||
}
|
||||
}
|
||||
|
||||
return xStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int mq_close( mqd_t mqdes )
|
||||
{
|
||||
int iStatus = 0;
|
||||
QueueListElement_t * pxMessageQueue = ( QueueListElement_t * ) mqdes;
|
||||
BaseType_t xQueueRemoved = pdFALSE;
|
||||
|
||||
/* Initialize the queue list, if needed. */
|
||||
prvInitializeQueueList();
|
||||
|
||||
/* Lock the mutex that guards access to the queue list. This call will
|
||||
* never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
|
||||
|
||||
/* Attempt to find the message queue based on the given descriptor. */
|
||||
if( prvFindQueueInList( NULL, NULL, mqdes ) == pdTRUE )
|
||||
{
|
||||
/* Decrement the number of open descriptors. */
|
||||
if(pxMessageQueue->xOpenDescriptors > 0)
|
||||
{
|
||||
pxMessageQueue->xOpenDescriptors--;
|
||||
}
|
||||
|
||||
/* Check if the queue has any more open descriptors. */
|
||||
if( pxMessageQueue->xOpenDescriptors == 0 )
|
||||
{
|
||||
/* If no open descriptors remain and mq_unlink has already been called,
|
||||
* remove the queue. */
|
||||
if( pxMessageQueue->xPendingUnlink == pdTRUE )
|
||||
{
|
||||
listREMOVE( &pxMessageQueue->xLink );
|
||||
|
||||
/* Set the flag to delete the queue. Deleting the queue is deferred
|
||||
* until xQueueListMutex is released. */
|
||||
xQueueRemoved = pdTRUE;
|
||||
}
|
||||
/* Otherwise, wait for the call to mq_unlink. */
|
||||
else
|
||||
{
|
||||
pxMessageQueue->xPendingUnlink = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Queue not found; bad descriptor. */
|
||||
errno = EBADF;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
/* Release the mutex protecting the queue list. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
|
||||
|
||||
/* Delete all resources used by the queue if needed. */
|
||||
if( xQueueRemoved == pdTRUE )
|
||||
{
|
||||
prvDeleteMessageQueue( pxMessageQueue );
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int mq_getattr( mqd_t mqdes,
|
||||
struct mq_attr * mqstat )
|
||||
{
|
||||
int iStatus = 0;
|
||||
QueueListElement_t * pxMessageQueue = ( QueueListElement_t * ) mqdes;
|
||||
|
||||
/* Lock the mutex that guards access to the queue list. This call will
|
||||
* never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
|
||||
|
||||
/* Find the mq referenced by mqdes. */
|
||||
if( prvFindQueueInList( NULL, NULL, mqdes ) == pdTRUE )
|
||||
{
|
||||
/* Update the number of messages in the queue and copy the attributes
|
||||
* into mqstat. */
|
||||
pxMessageQueue->xAttr.mq_curmsgs = ( long ) uxQueueMessagesWaiting( pxMessageQueue->xQueue );
|
||||
*mqstat = pxMessageQueue->xAttr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Queue not found; bad descriptor. */
|
||||
errno = EBADF;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
/* Release the mutex protecting the queue list. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
mqd_t mq_open( const char * name,
|
||||
int oflag,
|
||||
mode_t mode,
|
||||
struct mq_attr * attr )
|
||||
{
|
||||
mqd_t xMessageQueue = NULL;
|
||||
size_t xNameLength = 0;
|
||||
|
||||
/* Default mq_attr. */
|
||||
struct mq_attr xQueueCreationAttr =
|
||||
{
|
||||
.mq_flags = 0,
|
||||
.mq_maxmsg = posixconfigMQ_MAX_MESSAGES,
|
||||
.mq_msgsize = posixconfigMQ_MAX_SIZE,
|
||||
.mq_curmsgs = 0
|
||||
};
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) mode;
|
||||
|
||||
/* Initialize the queue list, if needed. */
|
||||
prvInitializeQueueList();
|
||||
|
||||
/* Check queue name. */
|
||||
if( prvValidateQueueName( name, &xNameLength ) == pdFALSE )
|
||||
{
|
||||
/* Invalid name. */
|
||||
errno = EINVAL;
|
||||
xMessageQueue = ( mqd_t ) -1;
|
||||
}
|
||||
|
||||
/* Check attributes, if O_CREATE is specified and attr is given. */
|
||||
if( xMessageQueue == NULL )
|
||||
{
|
||||
if( ( oflag & O_CREAT ) && ( attr != NULL ) && ( ( attr->mq_maxmsg <= 0 ) || ( attr->mq_msgsize <= 0 ) ) )
|
||||
{
|
||||
/* Invalid mq_attr.mq_maxmsg or mq_attr.mq_msgsize. */
|
||||
errno = EINVAL;
|
||||
xMessageQueue = ( mqd_t ) -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( xMessageQueue == NULL )
|
||||
{
|
||||
/* Lock the mutex that guards access to the queue list. This call will
|
||||
* never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
|
||||
|
||||
/* Search the queue list to check if the queue exists. */
|
||||
if( prvFindQueueInList( ( QueueListElement_t ** ) &xMessageQueue,
|
||||
name,
|
||||
( mqd_t ) NULL ) == pdTRUE )
|
||||
{
|
||||
/* If the mq exists, check that this function wasn't called with
|
||||
* O_CREAT and O_EXCL. */
|
||||
if( ( oflag & O_EXCL ) && ( oflag & O_CREAT ) )
|
||||
{
|
||||
errno = EEXIST;
|
||||
xMessageQueue = ( mqd_t ) -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the mq has been unlinked and is pending removal. */
|
||||
if( ( ( QueueListElement_t * ) xMessageQueue )->xPendingUnlink == pdTRUE )
|
||||
{
|
||||
/* Queue pending deletion. Don't allow it to be re-opened. */
|
||||
errno = EINVAL;
|
||||
xMessageQueue = ( mqd_t ) -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase count of open file descriptors for queue. */
|
||||
( ( QueueListElement_t * ) xMessageQueue )->xOpenDescriptors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Queue does not exist. */
|
||||
else
|
||||
{
|
||||
/* Only create the new queue if O_CREAT was specified. */
|
||||
if( oflag & O_CREAT )
|
||||
{
|
||||
/* Copy attributes if provided. */
|
||||
if( attr != NULL )
|
||||
{
|
||||
xQueueCreationAttr = *attr;
|
||||
}
|
||||
|
||||
/* Copy oflags. */
|
||||
xQueueCreationAttr.mq_flags = ( long ) oflag;
|
||||
|
||||
/* Create the new message queue. */
|
||||
if( prvCreateNewMessageQueue( ( QueueListElement_t ** ) &xMessageQueue,
|
||||
&xQueueCreationAttr,
|
||||
name,
|
||||
xNameLength ) == pdFALSE )
|
||||
{
|
||||
errno = ENOSPC;
|
||||
xMessageQueue = ( mqd_t ) -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = ENOENT;
|
||||
xMessageQueue = ( mqd_t ) -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the mutex protecting the queue list. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
|
||||
}
|
||||
|
||||
return xMessageQueue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ssize_t mq_receive( mqd_t mqdes,
|
||||
char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned int * msg_prio )
|
||||
{
|
||||
return mq_timedreceive( mqdes, msg_ptr, msg_len, msg_prio, NULL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int mq_send( mqd_t mqdes,
|
||||
const char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned msg_prio )
|
||||
{
|
||||
return mq_timedsend( mqdes, msg_ptr, msg_len, msg_prio, NULL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ssize_t mq_timedreceive( mqd_t mqdes,
|
||||
char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned * msg_prio,
|
||||
const struct timespec * abstime )
|
||||
{
|
||||
ssize_t xStatus = 0;
|
||||
int iCalculateTimeoutReturn = 0;
|
||||
TickType_t xTimeoutTicks = 0;
|
||||
QueueListElement_t * pxMessageQueue = ( QueueListElement_t * ) mqdes;
|
||||
QueueElement_t xReceiveData = { 0 };
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) msg_prio;
|
||||
|
||||
/* Lock the mutex that guards access to the queue list. This call will
|
||||
* never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
|
||||
|
||||
/* Find the mq referenced by mqdes. */
|
||||
if( prvFindQueueInList( NULL, NULL, mqdes ) == pdFALSE )
|
||||
{
|
||||
/* Queue not found; bad descriptor. */
|
||||
errno = EBADF;
|
||||
xStatus = -1;
|
||||
}
|
||||
|
||||
/* Verify that msg_len is large enough. */
|
||||
if( xStatus == 0 )
|
||||
{
|
||||
if( msg_len < ( size_t ) pxMessageQueue->xAttr.mq_msgsize )
|
||||
{
|
||||
/* msg_len too small. */
|
||||
errno = EMSGSIZE;
|
||||
xStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( xStatus == 0 )
|
||||
{
|
||||
/* Convert abstime to a tick timeout. */
|
||||
iCalculateTimeoutReturn = prvCalculateTickTimeout( pxMessageQueue->xAttr.mq_flags,
|
||||
abstime,
|
||||
&xTimeoutTicks );
|
||||
|
||||
if( iCalculateTimeoutReturn != 0 )
|
||||
{
|
||||
errno = iCalculateTimeoutReturn;
|
||||
xStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the mutex protecting the queue list. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
|
||||
|
||||
if( xStatus == 0 )
|
||||
{
|
||||
/* Receive data from the FreeRTOS queue. */
|
||||
if( xQueueReceive( pxMessageQueue->xQueue,
|
||||
&xReceiveData,
|
||||
xTimeoutTicks ) == pdFALSE )
|
||||
{
|
||||
/* If queue receive fails, set the appropriate errno. */
|
||||
if( pxMessageQueue->xAttr.mq_flags & O_NONBLOCK )
|
||||
{
|
||||
/* Set errno to EAGAIN for nonblocking mq. */
|
||||
errno = EAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, set errno to ETIMEDOUT. */
|
||||
errno = ETIMEDOUT;
|
||||
}
|
||||
|
||||
xStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( xStatus == 0 )
|
||||
{
|
||||
/* Get the length of data for return value. */
|
||||
xStatus = ( ssize_t ) xReceiveData.xDataSize;
|
||||
|
||||
/* Copy received data into given buffer, then free it. */
|
||||
( void ) memcpy( msg_ptr, xReceiveData.pcData, xReceiveData.xDataSize );
|
||||
vPortFree( xReceiveData.pcData );
|
||||
}
|
||||
|
||||
return xStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int mq_timedsend( mqd_t mqdes,
|
||||
const char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned int msg_prio,
|
||||
const struct timespec * abstime )
|
||||
{
|
||||
int iStatus = 0, iCalculateTimeoutReturn = 0;
|
||||
TickType_t xTimeoutTicks = 0;
|
||||
QueueListElement_t * pxMessageQueue = ( QueueListElement_t * ) mqdes;
|
||||
QueueElement_t xSendData = { 0 };
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) msg_prio;
|
||||
|
||||
/* Lock the mutex that guards access to the queue list. This call will
|
||||
* never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
|
||||
|
||||
/* Find the mq referenced by mqdes. */
|
||||
if( prvFindQueueInList( NULL, NULL, mqdes ) == pdFALSE )
|
||||
{
|
||||
/* Queue not found; bad descriptor. */
|
||||
errno = EBADF;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
/* Verify that mq_msgsize is large enough. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( msg_len > ( size_t ) pxMessageQueue->xAttr.mq_msgsize )
|
||||
{
|
||||
/* msg_len too large. */
|
||||
errno = EMSGSIZE;
|
||||
iStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Convert abstime to a tick timeout. */
|
||||
iCalculateTimeoutReturn = prvCalculateTickTimeout( pxMessageQueue->xAttr.mq_flags,
|
||||
abstime,
|
||||
&xTimeoutTicks );
|
||||
|
||||
if( iCalculateTimeoutReturn != 0 )
|
||||
{
|
||||
errno = iCalculateTimeoutReturn;
|
||||
iStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the mutex protecting the queue list. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
|
||||
|
||||
/* Allocate memory for the message. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
xSendData.xDataSize = msg_len;
|
||||
xSendData.pcData = pvPortMalloc( msg_len );
|
||||
|
||||
/* Check that memory allocation succeeded. */
|
||||
if( xSendData.pcData == NULL )
|
||||
{
|
||||
/* msg_len too large. */
|
||||
errno = EMSGSIZE;
|
||||
iStatus = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the data to send. */
|
||||
( void ) memcpy( xSendData.pcData, msg_ptr, msg_len );
|
||||
}
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Send data to the FreeRTOS queue. */
|
||||
if( xQueueSend( pxMessageQueue->xQueue,
|
||||
&xSendData,
|
||||
xTimeoutTicks ) == pdFALSE )
|
||||
{
|
||||
/* If queue send fails, set the appropriate errno. */
|
||||
if( pxMessageQueue->xAttr.mq_flags & O_NONBLOCK )
|
||||
{
|
||||
/* Set errno to EAGAIN for nonblocking mq. */
|
||||
errno = EAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, set errno to ETIMEDOUT. */
|
||||
errno = ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Free the allocated queue data. */
|
||||
vPortFree( xSendData.pcData );
|
||||
|
||||
iStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int mq_unlink( const char * name )
|
||||
{
|
||||
int iStatus = 0;
|
||||
size_t xNameSize = 0;
|
||||
BaseType_t xQueueRemoved = pdFALSE;
|
||||
QueueListElement_t * pxMessageQueue = NULL;
|
||||
|
||||
/* Initialize the queue list, if needed. */
|
||||
prvInitializeQueueList();
|
||||
|
||||
/* Check queue name. */
|
||||
if( prvValidateQueueName( name, &xNameSize ) == pdFALSE )
|
||||
{
|
||||
/* Error with mq name. */
|
||||
errno = EINVAL;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Lock the mutex that guards access to the queue list. This call will
|
||||
* never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
|
||||
|
||||
/* Check if the named queue exists. */
|
||||
if( prvFindQueueInList( &pxMessageQueue, name, ( mqd_t ) NULL ) == pdTRUE )
|
||||
{
|
||||
/* If the queue exists and there are no open descriptors to it,
|
||||
* remove it from the list. */
|
||||
if( pxMessageQueue->xOpenDescriptors == 0 )
|
||||
{
|
||||
listREMOVE( &pxMessageQueue->xLink );
|
||||
|
||||
/* Set the flag to delete the queue. Deleting the queue is deferred
|
||||
* until xQueueListMutex is released. */
|
||||
xQueueRemoved = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the queue has open descriptors, set the pending unlink flag
|
||||
* so that mq_close will free its resources. */
|
||||
pxMessageQueue->xPendingUnlink = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The named message queue doesn't exist. */
|
||||
errno = ENOENT;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
/* Release the mutex protecting the queue list. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
|
||||
}
|
||||
|
||||
/* Delete all resources used by the queue if needed. */
|
||||
if( xQueueRemoved == pdTRUE )
|
||||
{
|
||||
prvDeleteMessageQueue( pxMessageQueue );
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_pthread.c
|
||||
* @brief Implementation of thread functions in pthread.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
|
||||
/**
|
||||
* @brief Thread attribute object.
|
||||
*/
|
||||
typedef struct pthread_attr_internal
|
||||
{
|
||||
size_t xStackSize; /**< Stack size. */
|
||||
int iDetachState; /**< Detach state: joinable or detached. */
|
||||
struct sched_param xSchedParam; /**< Scheduler parameters. */
|
||||
} pthread_attr_internal_t;
|
||||
|
||||
/**
|
||||
* @brief Thread object.
|
||||
*/
|
||||
typedef struct pthread_internal
|
||||
{
|
||||
pthread_attr_internal_t xAttr; /**< Thread attributes. */
|
||||
void * ( *pvStartRoutine )( void * ); /**< Application thread function. */
|
||||
void * xTaskArg; /**< Arguments for application thread function. */
|
||||
TaskHandle_t xTaskHandle; /**< FreeRTOS task handle. */
|
||||
StaticSemaphore_t xJoinBarrier; /**< Synchronizes the two callers of pthread_join. */
|
||||
StaticSemaphore_t xJoinMutex; /**< Ensures that only one other thread may join this thread. */
|
||||
void * xReturn; /**< Return value of pvStartRoutine. */
|
||||
} pthread_internal_t;
|
||||
|
||||
/**
|
||||
* @brief Terminates the calling thread.
|
||||
*
|
||||
* For joinable threads, this function waits for pthread_join. Otherwise,
|
||||
* it deletes the thread and frees up resources used by the thread.
|
||||
*
|
||||
* @return This function does not return.
|
||||
*/
|
||||
static void prvExitThread( void );
|
||||
|
||||
/**
|
||||
* @brief Wrapper function for the user's thread routine.
|
||||
*
|
||||
* This function is executed as a FreeRTOS task function.
|
||||
* @param[in] pxArg A pointer to a pthread_internal_t.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
static void prvRunThread( void * pxArg );
|
||||
|
||||
/**
|
||||
* @brief Default pthread_attr_t.
|
||||
*/
|
||||
static const pthread_attr_internal_t xDefaultThreadAttributes =
|
||||
{
|
||||
.xStackSize = PTHREAD_STACK_MIN,
|
||||
.iDetachState = PTHREAD_CREATE_JOINABLE,
|
||||
.xSchedParam = { .sched_priority = tskIDLE_PRIORITY }
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvExitThread( void )
|
||||
{
|
||||
pthread_internal_t * pxThread = ( pthread_internal_t * ) pthread_self();
|
||||
|
||||
/* If this thread is joinable, wait for a call to pthread_join. */
|
||||
if( pxThread->xAttr.iDetachState == PTHREAD_CREATE_JOINABLE )
|
||||
{
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );
|
||||
|
||||
/* Suspend until the call to pthread_join. The caller of pthread_join
|
||||
* will perform cleanup. */
|
||||
vTaskSuspend( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For a detached thread, perform cleanup of thread object. */
|
||||
vPortFree( pxThread );
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvRunThread( void * pxArg )
|
||||
{
|
||||
pthread_internal_t * pxThread = ( pthread_internal_t * ) pxArg;
|
||||
|
||||
/* Run the thread routine. */
|
||||
pxThread->xReturn = pxThread->pvStartRoutine( ( void * ) pxThread->xTaskArg );
|
||||
|
||||
/* Exit once finished. This function does not return. */
|
||||
prvExitThread();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_destroy( pthread_attr_t * attr )
|
||||
{
|
||||
int iStatus = 0;
|
||||
vPortFree( *attr );
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_getdetachstate( const pthread_attr_t * attr,
|
||||
int * detachstate )
|
||||
{
|
||||
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
|
||||
|
||||
*detachstate = pxAttr->iDetachState;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_getschedparam( const pthread_attr_t * attr,
|
||||
struct sched_param * param )
|
||||
{
|
||||
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
|
||||
|
||||
*param = pxAttr->xSchedParam;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_getstacksize( const pthread_attr_t * attr,
|
||||
size_t * stacksize )
|
||||
{
|
||||
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
|
||||
|
||||
*stacksize = pxAttr->xStackSize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_init( pthread_attr_t * attr )
|
||||
{
|
||||
int iStatus = 0;
|
||||
|
||||
/* Allocate memory for a new thread attributes object. */
|
||||
*attr = pvPortMalloc( sizeof( pthread_attr_internal_t ) );
|
||||
|
||||
/* Check that thread attributes object was successfully allocated. */
|
||||
if( *attr == NULL )
|
||||
{
|
||||
iStatus = ENOMEM;
|
||||
}
|
||||
|
||||
/* Copy the default values into the new thread attributes object. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
*( ( pthread_attr_internal_t * ) ( *attr ) ) = xDefaultThreadAttributes;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_setdetachstate( pthread_attr_t * attr,
|
||||
int detachstate )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
|
||||
|
||||
if( ( detachstate != PTHREAD_CREATE_DETACHED ) && ( detachstate != PTHREAD_CREATE_JOINABLE ) )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxAttr->iDetachState = detachstate;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_setschedparam( pthread_attr_t * attr,
|
||||
const struct sched_param * param )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
|
||||
|
||||
/* Check for NULL param. */
|
||||
if( param == NULL )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure that param.sched_priority is valid. */
|
||||
if( ( iStatus == 0 ) &&
|
||||
( ( param->sched_priority > sched_get_priority_max( SCHED_OTHER ) ) ||
|
||||
( param->sched_priority < 0 ) ) )
|
||||
{
|
||||
iStatus = ENOTSUP;
|
||||
}
|
||||
|
||||
/* Set the sched_param. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
pxAttr->xSchedParam = *param;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_attr_setstacksize( pthread_attr_t * attr,
|
||||
size_t stacksize )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
|
||||
|
||||
if( stacksize < PTHREAD_STACK_MIN )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxAttr->xStackSize = stacksize;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_create( pthread_t * thread,
|
||||
const pthread_attr_t * attr,
|
||||
void *( *startroutine )( void * ),
|
||||
void * arg )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_internal_t * pxThread = NULL;
|
||||
|
||||
/* Allocate memory for new thread object. */
|
||||
pxThread = ( pthread_internal_t * ) pvPortMalloc( sizeof( pthread_internal_t ) );
|
||||
|
||||
if( pxThread == NULL )
|
||||
{
|
||||
/* No memory. */
|
||||
iStatus = EAGAIN;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* No attributes given, use default attributes. */
|
||||
if( attr == NULL )
|
||||
{
|
||||
pxThread->xAttr = xDefaultThreadAttributes;
|
||||
}
|
||||
/* Otherwise, use provided attributes. */
|
||||
else
|
||||
{
|
||||
pxThread->xAttr = *( ( pthread_attr_internal_t * ) ( *attr ) );
|
||||
}
|
||||
|
||||
/* Set argument and start routine. */
|
||||
pxThread->xTaskArg = arg;
|
||||
pxThread->pvStartRoutine = startroutine;
|
||||
|
||||
/* If this thread is joinable, create the synchronization mechanisms for
|
||||
* pthread_join. */
|
||||
if( pxThread->xAttr.iDetachState == PTHREAD_CREATE_JOINABLE )
|
||||
{
|
||||
/* These calls will not fail when their arguments aren't NULL. */
|
||||
( void ) xSemaphoreCreateMutexStatic( &pxThread->xJoinMutex );
|
||||
( void ) xSemaphoreCreateBinaryStatic( &pxThread->xJoinBarrier );
|
||||
}
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Suspend all tasks to create a critical section. This ensures that
|
||||
* the new thread doesn't exit before a tag is assigned. */
|
||||
vTaskSuspendAll();
|
||||
|
||||
/* Create the FreeRTOS task that will run the pthread. */
|
||||
if( xTaskCreate( prvRunThread,
|
||||
posixconfigPTHREAD_TASK_NAME,
|
||||
( uint16_t ) ( pxThread->xAttr.xStackSize / sizeof( StackType_t ) ),
|
||||
( void * ) pxThread,
|
||||
pxThread->xAttr.xSchedParam.sched_priority,
|
||||
&pxThread->xTaskHandle ) != pdPASS )
|
||||
{
|
||||
/* Task creation failed, no memory. */
|
||||
vPortFree( pxThread );
|
||||
iStatus = EAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store the pointer to the thread object in the task tag. */
|
||||
vTaskSetApplicationTaskTag( pxThread->xTaskHandle, ( TaskHookFunction_t ) pxThread );
|
||||
|
||||
/* Set the thread object for the user. */
|
||||
*thread = ( pthread_t ) pxThread;
|
||||
}
|
||||
|
||||
/* End the critical section. */
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_getschedparam( pthread_t thread,
|
||||
int * policy,
|
||||
struct sched_param * param )
|
||||
{
|
||||
pthread_internal_t * pxThread = ( pthread_internal_t * ) thread;
|
||||
|
||||
*policy = SCHED_OTHER;
|
||||
*param = pxThread->xAttr.xSchedParam;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_equal( pthread_t t1,
|
||||
pthread_t t2 )
|
||||
{
|
||||
return t1 == t2;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void pthread_exit( void * value_ptr )
|
||||
{
|
||||
pthread_internal_t * pxThread = ( pthread_internal_t * ) pthread_self();
|
||||
|
||||
/* Set the return value. */
|
||||
pxThread->xReturn = value_ptr;
|
||||
|
||||
/* Exit this thread. */
|
||||
prvExitThread();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_join( pthread_t pthread,
|
||||
void ** retval )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_internal_t * pxThread = ( pthread_internal_t * ) pthread;
|
||||
|
||||
/* Make sure pthread is joinable. Otherwise, this function would block
|
||||
* forever waiting for an unjoinable thread. */
|
||||
if( pxThread->xAttr.iDetachState != PTHREAD_CREATE_JOINABLE )
|
||||
{
|
||||
iStatus = EDEADLK;
|
||||
}
|
||||
|
||||
/* Only one thread may attempt to join another. Lock the join mutex
|
||||
* to prevent other threads from calling pthread_join on the same thread. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( xSemaphoreTake( ( SemaphoreHandle_t ) &pxThread->xJoinMutex, 0 ) != pdPASS )
|
||||
{
|
||||
/* Another thread has already joined the requested thread, which would
|
||||
* cause this thread to wait forever. */
|
||||
iStatus = EDEADLK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempting to join the calling thread would cause a deadlock. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( pthread_equal( pthread_self(), pthread ) != 0 )
|
||||
{
|
||||
iStatus = EDEADLK;
|
||||
}
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Wait for the joining thread to finish. Because this call waits forever,
|
||||
* it should never fail. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier, portMAX_DELAY );
|
||||
|
||||
/* Create a critical section to clean up the joined thread. */
|
||||
vTaskSuspendAll();
|
||||
|
||||
/* Release xJoinBarrier and delete it. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );
|
||||
vSemaphoreDelete( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );
|
||||
|
||||
/* Release xJoinMutex and delete it. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinMutex );
|
||||
vSemaphoreDelete( ( SemaphoreHandle_t ) &pxThread->xJoinMutex );
|
||||
|
||||
/* Delete the FreeRTOS task that ran the thread. */
|
||||
vTaskDelete( pxThread->xTaskHandle );
|
||||
|
||||
/* Set the return value. */
|
||||
if( retval != NULL )
|
||||
{
|
||||
*retval = pxThread->xReturn;
|
||||
}
|
||||
|
||||
/* Free the thread object. */
|
||||
vPortFree( pxThread );
|
||||
|
||||
/* End the critical section. */
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
pthread_t pthread_self( void )
|
||||
{
|
||||
/* Return a reference to this pthread object, which is stored in the
|
||||
* FreeRTOS task tag. */
|
||||
return ( pthread_t ) xTaskGetApplicationTaskTag( NULL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_setschedparam( pthread_t thread,
|
||||
int policy,
|
||||
const struct sched_param * param )
|
||||
{
|
||||
pthread_internal_t * pxThread = ( pthread_internal_t * ) thread;
|
||||
|
||||
/* Silence compiler warnings about unused parameters. */
|
||||
( void ) policy;
|
||||
|
||||
/* Copy the give sched_param. */
|
||||
pxThread->xAttr.xSchedParam = *param;
|
||||
|
||||
/* Change the priority of the FreeRTOS task. */
|
||||
vTaskPrioritySet( pxThread->xTaskHandle, pxThread->xAttr.xSchedParam.sched_priority );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_pthread_barrier.c
|
||||
* @brief Implementation of barrier functions in pthread.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
|
||||
/*
|
||||
* Barriers are implemented on FreeRTOS event groups, of which 8 bits are usable
|
||||
* when configUSE_16_BIT_TICKS is 1. Otherwise, 24 bits are usable.
|
||||
*/
|
||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||
#define posixPTHREAD_BARRIER_MAX_COUNT ( 8 )
|
||||
#else
|
||||
#define posixPTHREAD_BARRIER_MAX_COUNT ( 24 )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Barrier object.
|
||||
*/
|
||||
typedef struct pthread_barrier_internal
|
||||
{
|
||||
unsigned uThreadCount; /**< Current number of threads that have entered barrier. */
|
||||
unsigned uThreshold; /**< The count argument of pthread_barrier_init. */
|
||||
StaticSemaphore_t xThreadCountMutex; /**< Guards access to uThreadCount. */
|
||||
StaticSemaphore_t xThreadCountSemaphore; /**< Prevents more than uThreshold threads from exiting pthread_barrier_wait at once. */
|
||||
StaticEventGroup_t xBarrierEventGroup; /**< FreeRTOS event group that blocks to wait on threads entering barrier. */
|
||||
} pthread_barrier_internal_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_barrier_destroy( pthread_barrier_t * barrier )
|
||||
{
|
||||
pthread_barrier_internal_t * pxBarrier = ( pthread_barrier_internal_t * ) ( *barrier );
|
||||
|
||||
/* Free all resources used by the barrier. */
|
||||
( void ) vEventGroupDelete( ( EventGroupHandle_t ) &pxBarrier->xBarrierEventGroup );
|
||||
( void ) vSemaphoreDelete( ( SemaphoreHandle_t ) &pxBarrier->xThreadCountMutex );
|
||||
( void ) vSemaphoreDelete( ( SemaphoreHandle_t ) &pxBarrier->xThreadCountSemaphore );
|
||||
|
||||
vPortFree( *barrier );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_barrier_init( pthread_barrier_t * barrier,
|
||||
const pthread_barrierattr_t * attr,
|
||||
unsigned count )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_barrier_internal_t * pxNewBarrier = NULL;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) attr;
|
||||
|
||||
/* Ensure count is greater than 0. */
|
||||
if( count == 0 )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure that count will fit in a FreeRTOS event group. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( count > posixPTHREAD_BARRIER_MAX_COUNT )
|
||||
{
|
||||
/* No memory exists in the event group for more than
|
||||
* posixPTHREAD_BARRIER_MAX_COUNT threads. */
|
||||
iStatus = ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory for a new barrier. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
pxNewBarrier = pvPortMalloc( sizeof( pthread_barrier_internal_t ) );
|
||||
|
||||
if( pxNewBarrier == NULL )
|
||||
{
|
||||
/* No memory. */
|
||||
iStatus = ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Set the current thread count and threshold. */
|
||||
pxNewBarrier->uThreadCount = 0;
|
||||
pxNewBarrier->uThreshold = count;
|
||||
|
||||
/* Create the FreeRTOS event group. This call will not fail when its
|
||||
* argument isn't NULL. */
|
||||
( void ) xEventGroupCreateStatic( &pxNewBarrier->xBarrierEventGroup );
|
||||
|
||||
/* Create the mutex that guards access to uThreadCount. This call
|
||||
* will not fail when its argument isn't NULL. */
|
||||
( void ) xSemaphoreCreateMutexStatic( &pxNewBarrier->xThreadCountMutex );
|
||||
|
||||
/* Create the semaphore that prevents more than count threads from being
|
||||
* unblocked by a single successful pthread_barrier_wait. This semaphore
|
||||
* counts down from count and cannot decrement below 0. */
|
||||
( void ) xSemaphoreCreateCountingStatic( ( UBaseType_t ) count, /* Max count. */
|
||||
( UBaseType_t ) count, /* Initial count. */
|
||||
&pxNewBarrier->xThreadCountSemaphore );
|
||||
|
||||
/* Set output parameter. */
|
||||
*barrier = pxNewBarrier;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_barrier_wait( pthread_barrier_t * barrier )
|
||||
{
|
||||
int iStatus = 0;
|
||||
unsigned i = 0; /* Loop iterator. */
|
||||
pthread_barrier_internal_t * pxBarrier = ( pthread_barrier_internal_t * ) ( *barrier );
|
||||
unsigned uThreadNumber = 0;
|
||||
|
||||
/* Decrement the number of threads waiting on this barrier. This will prevent more
|
||||
* than pxBarrier->uThreshold threads from being unblocked by a single successful
|
||||
* pthread_barrier_wait call.
|
||||
*
|
||||
* This call will never fail because it blocks forever.
|
||||
*/
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxBarrier->xThreadCountSemaphore, portMAX_DELAY );
|
||||
|
||||
/* Lock the mutex so that this thread can change uThreadCount. This call will
|
||||
* never fail because it blocks forever.*/
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxBarrier->xThreadCountMutex, portMAX_DELAY );
|
||||
|
||||
/* Increment thread count. This is the order that this thread entered the
|
||||
* barrier, i.e. uThreadNumber-1 threads entered the barrier before this one. */
|
||||
pxBarrier->uThreadCount++;
|
||||
uThreadNumber = pxBarrier->uThreadCount;
|
||||
configASSERT( uThreadNumber > 0 );
|
||||
|
||||
/* Unlock the thread count mutex to allow other threads to change thread count.
|
||||
* This call will never fail because xThreadCountMutex is owned by this thread. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxBarrier->xThreadCountMutex );
|
||||
|
||||
/* Set the bit in the event group representing this thread, then wait for the other
|
||||
* threads to set their bit. This call should wait forever until all threads have set
|
||||
* their bit, so the return value is ignored. */
|
||||
( void ) xEventGroupSync( ( EventGroupHandle_t ) &pxBarrier->xBarrierEventGroup,
|
||||
1 << ( uThreadNumber - 1 ), /* Which bit in the event group to set. */
|
||||
( 1 << pxBarrier->uThreshold ) - 1, /* Wait for all threads to set their bits. */
|
||||
portMAX_DELAY );
|
||||
|
||||
/* The first thread to enter the barrier gets PTHREAD_BARRIER_SERIAL_THREAD as its
|
||||
* return value and resets xThreadCountSemaphore. */
|
||||
if( uThreadNumber == 1 )
|
||||
{
|
||||
iStatus = PTHREAD_BARRIER_SERIAL_THREAD;
|
||||
|
||||
/* uThreadCount can be safely changed without locking xThreadCountMutex
|
||||
* because xThreadCountSemaphore is currently 0. */
|
||||
pxBarrier->uThreadCount = 0;
|
||||
|
||||
/* Reset xThreadCountSemaphore. This allows more threads to enter the
|
||||
* barrier, starting a new cycle. */
|
||||
for( i = 0; i < pxBarrier->uThreshold; i++ )
|
||||
{
|
||||
xSemaphoreGive( ( SemaphoreHandle_t ) &pxBarrier->xThreadCountSemaphore );
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_pthread_cond.c
|
||||
* @brief Implementation of condition variable functions in pthread.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <limits.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize a PTHREAD_COND_INITIALIZER cond.
|
||||
*
|
||||
* PTHREAD_COND_INITIALIZER sets a flag for a cond to be initialized later.
|
||||
* This function performs the initialization.
|
||||
* @param[in] pxCond The cond to initialize.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
static void prvInitializeStaticCond( pthread_cond_internal_t * pxCond );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitializeStaticCond( pthread_cond_internal_t * pxCond )
|
||||
{
|
||||
/* Check if the condition variable needs to be initialized. */
|
||||
if( pxCond->xIsInitialized == pdFALSE )
|
||||
{
|
||||
/* Cond initialization must be in a critical section to prevent two threads
|
||||
* from initializing it at the same time. */
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* Check again that the cond is still uninitialized, i.e. it wasn't
|
||||
* initialized while this function was waiting to enter the critical
|
||||
* section. */
|
||||
if( pxCond->xIsInitialized == pdFALSE )
|
||||
{
|
||||
/* Set the members of the cond. The semaphore create calls will never fail
|
||||
* when their arguments aren't NULL. */
|
||||
pxCond->xIsInitialized = pdTRUE;
|
||||
( void ) xSemaphoreCreateMutexStatic( &pxCond->xCondMutex );
|
||||
( void ) xSemaphoreCreateCountingStatic( INT_MAX, 0U, &pxCond->xCondWaitSemaphore );
|
||||
pxCond->iWaitingThreads = 0;
|
||||
}
|
||||
|
||||
/* Exit the critical section. */
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_cond_broadcast( pthread_cond_t * cond )
|
||||
{
|
||||
int i = 0;
|
||||
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( *cond );
|
||||
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvInitializeStaticCond( pxCond );
|
||||
|
||||
/* Lock xCondMutex to protect access to iWaitingThreads.
|
||||
* This call will never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxCond->xCondMutex, portMAX_DELAY );
|
||||
|
||||
/* Unblock all threads waiting on this condition variable. */
|
||||
for( i = 0; i < pxCond->iWaitingThreads; i++ )
|
||||
{
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore );
|
||||
}
|
||||
|
||||
/* All threads were unblocked, set waiting threads to 0. */
|
||||
pxCond->iWaitingThreads = 0;
|
||||
|
||||
/* Release xCondMutex. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_cond_destroy( pthread_cond_t * cond )
|
||||
{
|
||||
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( *cond );
|
||||
|
||||
/* Free all resources in use by the cond. */
|
||||
vSemaphoreDelete( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
|
||||
vSemaphoreDelete( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore );
|
||||
vPortFree( pxCond );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_cond_init( pthread_cond_t * cond,
|
||||
const pthread_condattr_t * attr )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_cond_internal_t * pxCond = NULL;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) attr;
|
||||
|
||||
pxCond = pvPortMalloc( sizeof( pthread_cond_internal_t ) );
|
||||
|
||||
if( pxCond == NULL )
|
||||
{
|
||||
iStatus = ENOMEM;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Set the members of the cond. The semaphore create calls will never fail
|
||||
* when their arguments aren't NULL. */
|
||||
pxCond->xIsInitialized = pdTRUE;
|
||||
( void ) xSemaphoreCreateMutexStatic( &pxCond->xCondMutex );
|
||||
( void ) xSemaphoreCreateCountingStatic( INT_MAX, 0U, &pxCond->xCondWaitSemaphore );
|
||||
pxCond->iWaitingThreads = 0;
|
||||
|
||||
/* Set the output. */
|
||||
*cond = pxCond;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_cond_signal( pthread_cond_t * cond )
|
||||
{
|
||||
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( *cond );
|
||||
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvInitializeStaticCond( pxCond );
|
||||
|
||||
/* Check that at least one thread is waiting for a signal. */
|
||||
if( pxCond->iWaitingThreads > 0 )
|
||||
{
|
||||
/* Lock xCondMutex to protect access to iWaitingThreads.
|
||||
* This call will never fail because it blocks forever. */
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxCond->xCondMutex, portMAX_DELAY );
|
||||
|
||||
/* Check again that at least one thread is waiting for a signal after
|
||||
* taking xCondMutex. If so, unblock it. */
|
||||
if( pxCond->iWaitingThreads > 0 )
|
||||
{
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore );
|
||||
|
||||
/* Decrease the number of waiting threads. */
|
||||
pxCond->iWaitingThreads--;
|
||||
}
|
||||
|
||||
/* Release xCondMutex. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_cond_timedwait( pthread_cond_t * cond,
|
||||
pthread_mutex_t * mutex,
|
||||
const struct timespec * abstime )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( *cond );
|
||||
TickType_t xDelay = portMAX_DELAY;
|
||||
|
||||
/* If the cond is uninitialized, perform initialization. */
|
||||
prvInitializeStaticCond( pxCond );
|
||||
|
||||
/* Convert abstime to a delay in TickType_t if provided. */
|
||||
if( abstime != NULL )
|
||||
{
|
||||
iStatus = UTILS_AbsoluteTimespecToTicks( abstime, &xDelay );
|
||||
}
|
||||
|
||||
/* Increase the counter of threads blocking on condition variable, then
|
||||
* unlock mutex. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxCond->xCondMutex, portMAX_DELAY );
|
||||
pxCond->iWaitingThreads++;
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
|
||||
|
||||
iStatus = pthread_mutex_unlock( mutex );
|
||||
}
|
||||
|
||||
/* Wait on the condition variable. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( xSemaphoreTake( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore,
|
||||
xDelay ) == pdPASS )
|
||||
{
|
||||
/* When successful, relock mutex. */
|
||||
iStatus = pthread_mutex_lock( mutex );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Timeout. Relock mutex and decrement number of waiting threads. */
|
||||
iStatus = ETIMEDOUT;
|
||||
( void ) pthread_mutex_lock( mutex );
|
||||
|
||||
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxCond->xCondMutex, portMAX_DELAY );
|
||||
pxCond->iWaitingThreads--;
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_cond_wait( pthread_cond_t * cond,
|
||||
pthread_mutex_t * mutex )
|
||||
{
|
||||
return pthread_cond_timedwait( cond, mutex, NULL );
|
||||
}
|
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_pthread_mutex.c
|
||||
* @brief Implementation of mutex functions in pthread.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize a PTHREAD_MUTEX_INITIALIZER mutex.
|
||||
*
|
||||
* PTHREAD_MUTEX_INITIALIZER sets a flag for a mutex to be initialized later.
|
||||
* This function performs the initialization.
|
||||
* @param[in] pxMutex The mutex to initialize.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
static void prvInitializeStaticMutex( pthread_mutex_internal_t * pxMutex );
|
||||
|
||||
/**
|
||||
* @brief Default pthread_mutexattr_t.
|
||||
*/
|
||||
static const pthread_mutexattr_internal_t xDefaultMutexAttributes =
|
||||
{
|
||||
.iType = PTHREAD_MUTEX_DEFAULT,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitializeStaticMutex( pthread_mutex_internal_t * pxMutex )
|
||||
{
|
||||
/* Check if the mutex needs to be initialized. */
|
||||
if( pxMutex->xIsInitialized == pdFALSE )
|
||||
{
|
||||
/* Mutex initialization must be in a critical section to prevent two threads
|
||||
* from initializing it at the same time. */
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* Check again that the mutex is still uninitialized, i.e. it wasn't
|
||||
* initialized while this function was waiting to enter the critical
|
||||
* section. */
|
||||
if( pxMutex->xIsInitialized == pdFALSE )
|
||||
{
|
||||
/* Set the mutex as the default type. */
|
||||
pxMutex->xAttr.iType = PTHREAD_MUTEX_DEFAULT;
|
||||
|
||||
/* Call the correct FreeRTOS mutex initialization function based on
|
||||
* the mutex type. */
|
||||
#if PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_RECURSIVE
|
||||
( void ) xSemaphoreCreateRecursiveMutexStatic( &pxMutex->xMutex );
|
||||
#else
|
||||
( void ) xSemaphoreCreateMutexStatic( &pxMutex->xMutex );
|
||||
#endif
|
||||
|
||||
pxMutex->xIsInitialized = pdTRUE;
|
||||
}
|
||||
|
||||
/* Exit the critical section. */
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutex_destroy( pthread_mutex_t * mutex )
|
||||
{
|
||||
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) ( *mutex );
|
||||
|
||||
/* Free resources in use by the mutex. */
|
||||
if( pxMutex->xTaskOwner == NULL )
|
||||
{
|
||||
vSemaphoreDelete( ( SemaphoreHandle_t ) &pxMutex->xMutex );
|
||||
vPortFree( pxMutex );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutex_init( pthread_mutex_t * mutex,
|
||||
const pthread_mutexattr_t * attr )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_mutex_internal_t * pxMutex = NULL;
|
||||
|
||||
/* Allocate memory for new mutex object. */
|
||||
pxMutex = ( pthread_mutex_internal_t * ) pvPortMalloc( sizeof( pthread_mutex_internal_t ) );
|
||||
|
||||
if( pxMutex == NULL )
|
||||
{
|
||||
/* No memory. */
|
||||
iStatus = ENOMEM;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Clear the newly-allocated mutex. */
|
||||
( void ) memset( pxMutex, 0x00, sizeof( pthread_mutex_internal_t ) );
|
||||
|
||||
/* No attributes given, use default attributes. */
|
||||
if( attr == NULL )
|
||||
{
|
||||
pxMutex->xAttr = xDefaultMutexAttributes;
|
||||
}
|
||||
/* Otherwise, use provided attributes. */
|
||||
else
|
||||
{
|
||||
pxMutex->xAttr = *( ( pthread_mutexattr_internal_t * ) ( *attr ) );
|
||||
}
|
||||
|
||||
/* Call the correct FreeRTOS mutex creation function based on mutex type. */
|
||||
if( pxMutex->xAttr.iType == PTHREAD_MUTEX_RECURSIVE )
|
||||
{
|
||||
/* Recursive mutex. */
|
||||
( void ) xSemaphoreCreateRecursiveMutexStatic( &pxMutex->xMutex );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All other mutex types. */
|
||||
( void ) xSemaphoreCreateMutexStatic( &pxMutex->xMutex );
|
||||
}
|
||||
|
||||
/* Ensure that the FreeRTOS mutex was successfully created. */
|
||||
if( ( SemaphoreHandle_t ) &pxMutex->xMutex == NULL )
|
||||
{
|
||||
/* Failed to create mutex. Set error EAGAIN and free mutex object. */
|
||||
iStatus = EAGAIN;
|
||||
vPortFree( pxMutex );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mutex successfully created. */
|
||||
pxMutex->xIsInitialized = pdTRUE;
|
||||
*mutex = ( pthread_mutex_t ) pxMutex;
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutex_lock( pthread_mutex_t * mutex )
|
||||
{
|
||||
return pthread_mutex_timedlock( mutex, NULL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutex_timedlock( pthread_mutex_t * mutex,
|
||||
const struct timespec * abstime )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) ( *mutex );
|
||||
TickType_t xDelay = portMAX_DELAY;
|
||||
BaseType_t xFreeRTOSMutexTakeStatus = pdFALSE;
|
||||
|
||||
/* If mutex in uninitialized, perform initialization. */
|
||||
prvInitializeStaticMutex( pxMutex );
|
||||
|
||||
/* At this point, the mutex should be initialized. */
|
||||
configASSERT( pxMutex->xIsInitialized == pdTRUE );
|
||||
|
||||
/* Convert abstime to a delay in TickType_t if provided. */
|
||||
if( abstime != NULL )
|
||||
{
|
||||
iStatus = UTILS_AbsoluteTimespecToTicks( abstime, &xDelay );
|
||||
|
||||
/* If abstime was in the past, still attempt to lock the mutex without
|
||||
* blocking, per POSIX spec. */
|
||||
if( iStatus == ETIMEDOUT )
|
||||
{
|
||||
xDelay = 0;
|
||||
iStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if trying to lock a currently owned mutex. */
|
||||
if( ( iStatus == 0 ) &&
|
||||
( pxMutex->xAttr.iType == PTHREAD_MUTEX_ERRORCHECK ) && /* Only PTHREAD_MUTEX_ERRORCHECK type detects deadlock. */
|
||||
( pxMutex->xTaskOwner == xTaskGetCurrentTaskHandle() ) ) /* Check if locking a currently owned mutex. */
|
||||
{
|
||||
iStatus = EDEADLK;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Call the correct FreeRTOS mutex take function based on mutex type. */
|
||||
if( pxMutex->xAttr.iType == PTHREAD_MUTEX_RECURSIVE )
|
||||
{
|
||||
xFreeRTOSMutexTakeStatus = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &pxMutex->xMutex, xDelay );
|
||||
}
|
||||
else
|
||||
{
|
||||
xFreeRTOSMutexTakeStatus = xSemaphoreTake( ( SemaphoreHandle_t ) &pxMutex->xMutex, xDelay );
|
||||
}
|
||||
|
||||
/* If the mutex was successfully taken, set its owner. */
|
||||
if( xFreeRTOSMutexTakeStatus == pdPASS )
|
||||
{
|
||||
pxMutex->xTaskOwner = xTaskGetCurrentTaskHandle();
|
||||
}
|
||||
/* Otherwise, the mutex take timed out. */
|
||||
else
|
||||
{
|
||||
iStatus = ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutex_trylock( pthread_mutex_t * mutex )
|
||||
{
|
||||
int iStatus = 0;
|
||||
struct timespec xTimeout =
|
||||
{
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = 0
|
||||
};
|
||||
|
||||
/* Attempt to lock with no timeout. */
|
||||
iStatus = pthread_mutex_timedlock( mutex, &xTimeout );
|
||||
|
||||
/* POSIX specifies that this function should return EBUSY instead of
|
||||
* ETIMEDOUT for attempting to lock a locked mutex. */
|
||||
if( iStatus == ETIMEDOUT )
|
||||
{
|
||||
iStatus = EBUSY;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutex_unlock( pthread_mutex_t * mutex )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) ( *mutex );
|
||||
|
||||
/* If mutex in uninitialized, perform initialization. */
|
||||
prvInitializeStaticMutex( pxMutex );
|
||||
|
||||
/* Check if trying to unlock an unowned mutex. */
|
||||
if( ( ( pxMutex->xAttr.iType == PTHREAD_MUTEX_ERRORCHECK ) ||
|
||||
( pxMutex->xAttr.iType == PTHREAD_MUTEX_RECURSIVE ) ) &&
|
||||
( pxMutex->xTaskOwner != xTaskGetCurrentTaskHandle() ) )
|
||||
{
|
||||
iStatus = EPERM;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Call the correct FreeRTOS mutex unlock function based on mutex type. */
|
||||
if( pxMutex->xAttr.iType == PTHREAD_MUTEX_RECURSIVE )
|
||||
{
|
||||
( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &pxMutex->xMutex );
|
||||
}
|
||||
else
|
||||
{
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxMutex->xMutex );
|
||||
}
|
||||
|
||||
/* Update the owner of the mutex. A recursive mutex may still have an
|
||||
* owner, so it should be updated with xSemaphoreGetMutexHolder. */
|
||||
pxMutex->xTaskOwner = xSemaphoreGetMutexHolder( ( SemaphoreHandle_t ) &pxMutex->xMutex );
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutexattr_destroy( pthread_mutexattr_t * attr )
|
||||
{
|
||||
/* Free mutex attributes object. */
|
||||
vPortFree( *attr );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr,
|
||||
int * type )
|
||||
{
|
||||
pthread_mutexattr_internal_t * pxAttr = ( pthread_mutexattr_internal_t * ) ( *attr );
|
||||
|
||||
*type = pxAttr->iType;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutexattr_init( pthread_mutexattr_t * attr )
|
||||
{
|
||||
int iStatus = 0;
|
||||
|
||||
/* Allocate memory for new mutex attributes object. */
|
||||
*attr = pvPortMalloc( sizeof( pthread_mutexattr_internal_t ) );
|
||||
|
||||
if( *attr == NULL )
|
||||
{
|
||||
/* No memory. */
|
||||
iStatus = ENOMEM;
|
||||
}
|
||||
|
||||
/* Set the mutex attributes to default values. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
*( ( pthread_mutexattr_internal_t * ) ( *attr ) ) = xDefaultMutexAttributes;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int pthread_mutexattr_settype( pthread_mutexattr_t * attr,
|
||||
int type )
|
||||
{
|
||||
int iStatus = 0;
|
||||
pthread_mutexattr_internal_t * pxAttr = ( pthread_mutexattr_internal_t * ) ( *attr );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case PTHREAD_MUTEX_NORMAL:
|
||||
case PTHREAD_MUTEX_RECURSIVE:
|
||||
case PTHREAD_MUTEX_ERRORCHECK:
|
||||
pxAttr->iType = type;
|
||||
break;
|
||||
|
||||
default:
|
||||
iStatus = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_sched.c
|
||||
* @brief Implementation of scheduler functions in sched.h
|
||||
*/
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/sched.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sched_get_priority_max( int policy )
|
||||
{
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) policy;
|
||||
|
||||
return configMAX_PRIORITIES - 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sched_yield( void )
|
||||
{
|
||||
taskYIELD();
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_semaphore.c
|
||||
* @brief Implementation of functions in semaphore.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/semaphore.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/**
|
||||
* @brief Semaphore type.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
StaticSemaphore_t xSemaphore; /**< FreeRTOS semaphore. */
|
||||
} sem_internal_t;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_destroy( sem_t * sem )
|
||||
{
|
||||
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
|
||||
|
||||
/* Free the resources in use by the semaphore. */
|
||||
vSemaphoreDelete( ( SemaphoreHandle_t ) &pxSem->xSemaphore );
|
||||
vPortFree( pxSem );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_getvalue( sem_t * sem,
|
||||
int * sval )
|
||||
{
|
||||
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
|
||||
|
||||
/* Get the semaphore count using the FreeRTOS API. */
|
||||
*sval = ( int ) uxSemaphoreGetCount( ( SemaphoreHandle_t ) &pxSem->xSemaphore );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_init( sem_t * sem,
|
||||
int pshared,
|
||||
unsigned value )
|
||||
{
|
||||
int iStatus = 0;
|
||||
sem_internal_t * pxSem = NULL;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) pshared;
|
||||
|
||||
/* Check value parameter. */
|
||||
if( value > SEM_VALUE_MAX )
|
||||
{
|
||||
errno = EINVAL;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
/* Allocate memory for a new semaphore. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
pxSem = pvPortMalloc( sizeof( sem_internal_t ) );
|
||||
|
||||
if( pxSem == NULL )
|
||||
{
|
||||
errno = ENOSPC;
|
||||
iStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the FreeRTOS semaphore. This call will not fail because the
|
||||
* memory for the semaphore has already been allocated. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
( void ) xSemaphoreCreateCountingStatic( SEM_VALUE_MAX, value, &pxSem->xSemaphore );
|
||||
*sem = pxSem;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_post( sem_t * sem )
|
||||
{
|
||||
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
|
||||
|
||||
/* Give the semaphore using the FreeRTOS API. */
|
||||
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxSem->xSemaphore );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_timedwait( sem_t * sem,
|
||||
const struct timespec * abstime )
|
||||
{
|
||||
int iStatus = 0;
|
||||
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
|
||||
TickType_t xDelay = portMAX_DELAY;
|
||||
|
||||
if( abstime != NULL )
|
||||
{
|
||||
/* If the provided timespec is invalid, still attempt to take the
|
||||
* semaphore without blocking, per POSIX spec. */
|
||||
if( UTILS_ValidateTimespec( abstime ) == false )
|
||||
{
|
||||
xDelay = 0;
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
iStatus = UTILS_AbsoluteTimespecToTicks( abstime, &xDelay );
|
||||
|
||||
/* If abstime was in the past, still attempt to take the semaphore without
|
||||
* blocking, per POSIX spec. */
|
||||
if( iStatus == ETIMEDOUT )
|
||||
{
|
||||
xDelay = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Take the semaphore using the FreeRTOS API. */
|
||||
if( xSemaphoreTake( ( SemaphoreHandle_t ) &pxSem->xSemaphore,
|
||||
xDelay ) != pdTRUE )
|
||||
{
|
||||
errno = iStatus;
|
||||
iStatus = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iStatus = 0;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_trywait( sem_t * sem )
|
||||
{
|
||||
int iStatus = 0;
|
||||
|
||||
/* Setting an absolute timeout of 0 (i.e. in the past) will cause sem_timedwait
|
||||
* to not block. */
|
||||
struct timespec xTimeout = { 0 };
|
||||
|
||||
iStatus = sem_timedwait( sem, &xTimeout );
|
||||
|
||||
/* POSIX specifies that this function should set errno to EAGAIN and not
|
||||
* ETIMEDOUT. */
|
||||
if( ( iStatus == -1 ) && ( errno == ETIMEDOUT ) )
|
||||
{
|
||||
errno = EAGAIN;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int sem_wait( sem_t * sem )
|
||||
{
|
||||
return sem_timedwait( sem, NULL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_timer.c
|
||||
* @brief Implementation of timer functions in time.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
#include "FreeRTOS_POSIX/signal.h"
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/* FreeRTOS timer include. */
|
||||
#include "timers.h"
|
||||
|
||||
/**
|
||||
* #brief Timespec zero check macros.
|
||||
*/
|
||||
/**@{ */
|
||||
#define TIMESPEC_IS_ZERO( xTimespec ) ( xTimespec.tv_sec == 0 && xTimespec.tv_nsec == 0 ) /**< Check for 0. */
|
||||
#define TIMESPEC_IS_NOT_ZERO( xTimespec ) ( !( TIMESPEC_IS_ZERO( xTimespec ) ) ) /**< Check for not 0. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Internal timer structure.
|
||||
*/
|
||||
typedef struct timer_internal
|
||||
{
|
||||
StaticTimer_t xTimerBuffer; /**< Memory that holds the FreeRTOS timer. */
|
||||
struct sigevent xTimerEvent; /**< What to do when this timer expires. */
|
||||
TickType_t xTimerPeriod; /**< Period of this timer. */
|
||||
} timer_internal_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void prvTimerCallback( TimerHandle_t xTimerHandle )
|
||||
{
|
||||
timer_internal_t * pxTimer = ( timer_internal_t * ) pvTimerGetTimerID( xTimerHandle );
|
||||
pthread_t xTimerNotificationThread;
|
||||
pthread_attr_t xThreadAttributes;
|
||||
|
||||
/* The value of the timer ID, set in timer_create, should not be NULL. */
|
||||
configASSERT( pxTimer != NULL );
|
||||
|
||||
/* A value of SIGEV_SIGNAL isn't supported and should not have been successfully
|
||||
* set. */
|
||||
configASSERT( pxTimer->xTimerEvent.sigev_notify != SIGEV_SIGNAL );
|
||||
|
||||
/* Update the timer period, which may need to be set to an it_interval
|
||||
* argument. This call should not block. */
|
||||
if( pxTimer->xTimerPeriod > 0 )
|
||||
{
|
||||
xTimerChangePeriod( xTimerHandle, pxTimer->xTimerPeriod, 0 );
|
||||
}
|
||||
|
||||
/* Create the timer notification thread if requested. */
|
||||
if( pxTimer->xTimerEvent.sigev_notify == SIGEV_THREAD )
|
||||
{
|
||||
/* By default, create a detached thread. But if the user has provided
|
||||
* thread attributes, use the provided attributes. */
|
||||
if( pxTimer->xTimerEvent.sigev_notify_attributes == NULL )
|
||||
{
|
||||
if( pthread_attr_init( &xThreadAttributes ) == 0 )
|
||||
{
|
||||
if( pthread_attr_setdetachstate( &xThreadAttributes,
|
||||
PTHREAD_CREATE_DETACHED ) == 0 )
|
||||
{
|
||||
( void ) pthread_create( &xTimerNotificationThread,
|
||||
&xThreadAttributes,
|
||||
( void * ( * )( void * ) )pxTimer->xTimerEvent.sigev_notify_function,
|
||||
pxTimer->xTimerEvent.sigev_value.sival_ptr );
|
||||
}
|
||||
|
||||
( void ) pthread_attr_destroy( &xThreadAttributes );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
( void ) pthread_create( &xTimerNotificationThread,
|
||||
pxTimer->xTimerEvent.sigev_notify_attributes,
|
||||
( void * ( * )( void * ) )pxTimer->xTimerEvent.sigev_notify_function,
|
||||
pxTimer->xTimerEvent.sigev_value.sival_ptr );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int timer_create( clockid_t clockid,
|
||||
struct sigevent * evp,
|
||||
timer_t * timerid )
|
||||
{
|
||||
int iStatus = 0;
|
||||
timer_internal_t * pxTimer = NULL;
|
||||
|
||||
/* Silence warnings about unused parameters. */
|
||||
( void ) clockid;
|
||||
|
||||
/* POSIX specifies that when evp is NULL, the behavior shall be as is
|
||||
* sigev_notify is SIGEV_SIGNAL. SIGEV_SIGNAL is currently not supported. */
|
||||
if( ( evp == NULL ) || ( evp->sigev_notify == SIGEV_SIGNAL ) )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
iStatus = -1;
|
||||
}
|
||||
|
||||
/* Allocate memory for a new timer object. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
pxTimer = pvPortMalloc( sizeof( timer_internal_t ) );
|
||||
|
||||
if( pxTimer == NULL )
|
||||
{
|
||||
errno = EAGAIN;
|
||||
iStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Copy the event notification structure and set the current timer period. */
|
||||
pxTimer->xTimerEvent = *evp;
|
||||
pxTimer->xTimerPeriod = 0;
|
||||
|
||||
/* Create a new FreeRTOS timer. This call will not fail because the
|
||||
* memory for it has already been allocated, so the output parameter is
|
||||
* also set. */
|
||||
*timerid = ( timer_t ) xTimerCreateStatic( posixconfigTIMER_NAME, /* Timer name. */
|
||||
portMAX_DELAY, /* Initial timer period. Timers are created disarmed. */
|
||||
pdFALSE, /* Don't auto-reload timer. */
|
||||
( void * ) pxTimer, /* Timer id. */
|
||||
prvTimerCallback, /* Timer expiration callback. */
|
||||
&pxTimer->xTimerBuffer ); /* Pre-allocated memory for timer. */
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int timer_delete( timer_t timerid )
|
||||
{
|
||||
TimerHandle_t xTimerHandle = timerid;
|
||||
timer_internal_t * pxTimer = ( timer_internal_t * ) pvTimerGetTimerID( xTimerHandle );
|
||||
|
||||
/* The value of the timer ID, set in timer_create, should not be NULL. */
|
||||
configASSERT( pxTimer != NULL );
|
||||
|
||||
/* Stop the FreeRTOS timer. Because the timer is statically allocated, no call
|
||||
* to xTimerDelete is necessary. The timer is stopped so that it's not referenced
|
||||
* anywhere. xTimerStop will not fail when it has unlimited block time. */
|
||||
( void ) xTimerStop( xTimerHandle, portMAX_DELAY );
|
||||
|
||||
/* Wait until the timer stop command is processed. */
|
||||
while( xTimerIsTimerActive( xTimerHandle ) == pdTRUE )
|
||||
{
|
||||
vTaskDelay( 1 );
|
||||
}
|
||||
|
||||
/* Free the memory in use by the timer. */
|
||||
vPortFree( pxTimer );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int timer_getoverrun( timer_t timerid )
|
||||
{
|
||||
( void ) timerid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int timer_settime( timer_t timerid,
|
||||
int flags,
|
||||
const struct itimerspec * value,
|
||||
struct itimerspec * ovalue )
|
||||
{
|
||||
int iStatus = 0;
|
||||
TimerHandle_t xTimerHandle = timerid;
|
||||
timer_internal_t * pxTimer = ( timer_internal_t * ) pvTimerGetTimerID( xTimerHandle );
|
||||
TickType_t xNextTimerExpiration = 0, xTimerExpirationPeriod = 0;
|
||||
|
||||
/* Validate the value argument, but only if the timer isn't being disarmed. */
|
||||
if( TIMESPEC_IS_NOT_ZERO( value->it_value ) )
|
||||
{
|
||||
if( ( UTILS_ValidateTimespec( &value->it_interval ) == false ) ||
|
||||
( UTILS_ValidateTimespec( &value->it_value ) == false ) )
|
||||
{
|
||||
errno = EINVAL;
|
||||
iStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set ovalue, if given. */
|
||||
if( ovalue != NULL )
|
||||
{
|
||||
( void ) timer_gettime( timerid, ovalue );
|
||||
}
|
||||
|
||||
/* Stop the timer if it's currently active. */
|
||||
if( ( iStatus == 0 ) && xTimerIsTimerActive( xTimerHandle ) )
|
||||
{
|
||||
( void ) xTimerStop( xTimerHandle, portMAX_DELAY );
|
||||
}
|
||||
|
||||
/* Only restart the timer if it_value is not zero. */
|
||||
if( ( iStatus == 0 ) && TIMESPEC_IS_NOT_ZERO( value->it_value ) )
|
||||
{
|
||||
/* Convert it_interval to ticks, but only if it_interval is not 0. If
|
||||
* it_interval is 0, then the timer is not periodic. */
|
||||
if( TIMESPEC_IS_NOT_ZERO( value->it_interval ) )
|
||||
{
|
||||
( void ) UTILS_TimespecToTicks( &value->it_interval, &xTimerExpirationPeriod );
|
||||
}
|
||||
|
||||
/* Set the new timer period. A non-periodic timer will have its period set
|
||||
* to portMAX_DELAY. */
|
||||
pxTimer->xTimerPeriod = xTimerExpirationPeriod;
|
||||
|
||||
/* Convert it_value to ticks, but only if it_value is not 0. If it_value
|
||||
* is 0, then the timer will remain disarmed. */
|
||||
if( TIMESPEC_IS_NOT_ZERO( value->it_value ) )
|
||||
{
|
||||
/* Absolute timeout. */
|
||||
if( ( flags & TIMER_ABSTIME ) == TIMER_ABSTIME )
|
||||
{
|
||||
( void ) UTILS_AbsoluteTimespecToTicks( &value->it_value, &xNextTimerExpiration );
|
||||
}
|
||||
/* Relative timeout. */
|
||||
else
|
||||
{
|
||||
( void ) UTILS_TimespecToTicks( &value->it_value, &xNextTimerExpiration );
|
||||
}
|
||||
}
|
||||
|
||||
/* If xNextTimerExpiration is still 0, that means that it_value specified
|
||||
* an absolute timeout in the past. Per POSIX spec, a notification should be
|
||||
* triggered immediately. */
|
||||
if( xNextTimerExpiration == 0 )
|
||||
{
|
||||
prvTimerCallback( xTimerHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the timer to expire at the it_value, then start it. */
|
||||
( void ) xTimerChangePeriod( xTimerHandle, xNextTimerExpiration, portMAX_DELAY );
|
||||
( void ) xTimerStart( xTimerHandle, xNextTimerExpiration );
|
||||
}
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int timer_gettime( timer_t timerid,
|
||||
struct itimerspec * value )
|
||||
{
|
||||
TimerHandle_t xTimerHandle = timerid;
|
||||
timer_internal_t * pxTimer = ( timer_internal_t * ) pvTimerGetTimerID( xTimerHandle );
|
||||
TickType_t xNextExpirationTime = xTimerGetExpiryTime( xTimerHandle ) - xTaskGetTickCount(),
|
||||
xTimerExpirationPeriod = pxTimer->xTimerPeriod;
|
||||
|
||||
/* Set it_value only if the timer is armed. Otherwise, set it to 0. */
|
||||
if( xTimerIsTimerActive( xTimerHandle ) != pdFALSE )
|
||||
{
|
||||
value->it_value.tv_sec = ( time_t ) ( xNextExpirationTime / configTICK_RATE_HZ );
|
||||
value->it_value.tv_nsec = ( long ) ( ( xNextExpirationTime % configTICK_RATE_HZ ) * NANOSECONDS_PER_TICK );
|
||||
}
|
||||
else
|
||||
{
|
||||
value->it_value.tv_sec = 0;
|
||||
value->it_value.tv_nsec = 0;
|
||||
}
|
||||
|
||||
/* Set it_interval only if the timer is periodic. Otherwise, set it to 0. */
|
||||
if( xTimerExpirationPeriod != portMAX_DELAY )
|
||||
{
|
||||
value->it_interval.tv_sec = ( time_t ) ( xTimerExpirationPeriod / configTICK_RATE_HZ );
|
||||
value->it_interval.tv_nsec = ( long ) ( ( xTimerExpirationPeriod % configTICK_RATE_HZ ) * NANOSECONDS_PER_TICK );
|
||||
}
|
||||
else
|
||||
{
|
||||
value->it_interval.tv_sec = 0;
|
||||
value->it_interval.tv_nsec = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_unistd.c
|
||||
* @brief Implementation of functions in unistd.h
|
||||
*/
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/unistd.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
unsigned sleep( unsigned seconds )
|
||||
{
|
||||
vTaskDelay( pdMS_TO_TICKS( seconds * 1000 ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int usleep( useconds_t usec )
|
||||
{
|
||||
/* To avoid delaying for less than usec, always round up. */
|
||||
vTaskDelay( pdMS_TO_TICKS( usec / 1000 + ( usec % 1000 != 0 ) ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file FreeRTOS_POSIX_utils.c
|
||||
* @brief Implementation of utility functions in utils.h
|
||||
*/
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/utils.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t UTILS_strnlen( const char * const pcString,
|
||||
size_t xMaxLength )
|
||||
{
|
||||
const char * pcCharPointer = pcString;
|
||||
size_t xLength = 0;
|
||||
|
||||
if( pcString != NULL )
|
||||
{
|
||||
while( ( *pcCharPointer != '\0' ) && ( xLength < xMaxLength ) )
|
||||
{
|
||||
xLength++;
|
||||
pcCharPointer++;
|
||||
}
|
||||
}
|
||||
|
||||
return xLength;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int UTILS_AbsoluteTimespecToTicks( const struct timespec * const pxAbsoluteTime,
|
||||
TickType_t * const pxResult )
|
||||
{
|
||||
int iStatus = 0;
|
||||
struct timespec xCurrentTime = { 0 }, xDifference = { 0 };
|
||||
|
||||
/* Check parameters. */
|
||||
if( ( pxAbsoluteTime == NULL ) || ( pxResult == NULL ) )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
|
||||
/* Get the current time. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
|
||||
{
|
||||
iStatus = errno;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the difference between the current time and pxAbsoluteTime. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
if( UTILS_TimespecSubtract( &xDifference, pxAbsoluteTime, &xCurrentTime ) != 0 )
|
||||
{
|
||||
/* pxAbsoluteTime was in the past. */
|
||||
iStatus = ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the time difference to ticks. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
iStatus = UTILS_TimespecToTicks( &xDifference, pxResult );
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
|
||||
TickType_t * const pxResult )
|
||||
{
|
||||
int iStatus = 0;
|
||||
uint64_t ullTotalTicks = 0;
|
||||
long lNanoseconds = 0;
|
||||
|
||||
/* Check parameters. */
|
||||
if( ( pxTimespec == NULL ) || ( pxResult == NULL ) )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
else if( ( pxTimespec != NULL ) && ( UTILS_ValidateTimespec( pxTimespec ) == false ) )
|
||||
{
|
||||
iStatus = EINVAL;
|
||||
}
|
||||
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
/* Convert timespec.tv_sec to ticks. */
|
||||
ullTotalTicks = ( uint64_t ) configTICK_RATE_HZ * ( uint64_t ) ( pxTimespec->tv_sec );
|
||||
|
||||
/* Convert timespec.tv_nsec to ticks. This value does not have to be checked
|
||||
* for overflow because a valid timespec has 0 <= tv_nsec < 1000000000 and
|
||||
* NANOSECONDS_PER_TICK > 1. */
|
||||
lNanoseconds = pxTimespec->tv_nsec / ( long ) NANOSECONDS_PER_TICK + /* Whole nanoseconds. */
|
||||
( long ) ( pxTimespec->tv_nsec % ( long ) NANOSECONDS_PER_TICK != 0 ); /* Add 1 to round up if needed. */
|
||||
|
||||
/* Add the nanoseconds to the total ticks. */
|
||||
ullTotalTicks += ( uint64_t ) lNanoseconds;
|
||||
|
||||
/* Write result. */
|
||||
*pxResult = ( TickType_t ) ullTotalTicks;
|
||||
}
|
||||
|
||||
return iStatus;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void UTILS_NanosecondsToTimespec( int64_t llSource,
|
||||
struct timespec * const pxDestination )
|
||||
{
|
||||
long lCarrySec = 0;
|
||||
|
||||
/* Convert to timespec. */
|
||||
pxDestination->tv_sec = ( time_t ) ( llSource / NANOSECONDS_PER_SECOND );
|
||||
pxDestination->tv_nsec = ( long ) ( llSource % NANOSECONDS_PER_SECOND );
|
||||
|
||||
/* Subtract from tv_sec if tv_nsec < 0. */
|
||||
if( pxDestination->tv_nsec < 0L )
|
||||
{
|
||||
/* Compute the number of seconds to carry. */
|
||||
lCarrySec = ( pxDestination->tv_nsec / ( long ) NANOSECONDS_PER_SECOND ) + 1L;
|
||||
|
||||
pxDestination->tv_sec -= ( time_t ) ( lCarrySec );
|
||||
pxDestination->tv_nsec += lCarrySec * ( long ) NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int UTILS_TimespecAdd( struct timespec * const pxResult,
|
||||
const struct timespec * const x,
|
||||
const struct timespec * const y )
|
||||
{
|
||||
int64_t llResult64 = 0;
|
||||
|
||||
/* Check parameters. */
|
||||
if( ( pxResult == NULL ) || ( x == NULL ) || ( y == NULL ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Perform addition. */
|
||||
llResult64 = ( ( ( int64_t ) ( x->tv_sec ) * NANOSECONDS_PER_SECOND ) + ( int64_t ) ( x->tv_nsec ) )
|
||||
+ ( ( ( int64_t ) ( y->tv_sec ) * NANOSECONDS_PER_SECOND ) + ( int64_t ) ( y->tv_nsec ) );
|
||||
|
||||
/* Convert result to timespec. */
|
||||
UTILS_NanosecondsToTimespec( llResult64, pxResult );
|
||||
|
||||
return ( int ) ( llResult64 < 0LL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int UTILS_TimespecAddNanoseconds( struct timespec * const pxResult,
|
||||
const struct timespec * const x,
|
||||
int64_t llNanoseconds )
|
||||
{
|
||||
struct timespec y = { .tv_sec = ( time_t ) 0, .tv_nsec = 0L };
|
||||
|
||||
/* Check parameters. */
|
||||
if( ( pxResult == NULL ) || ( x == NULL ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Convert llNanoseconds to a timespec. */
|
||||
UTILS_NanosecondsToTimespec( llNanoseconds, &y );
|
||||
|
||||
/* Perform addition. */
|
||||
return UTILS_TimespecAdd( pxResult, x, &y );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int UTILS_TimespecSubtract( struct timespec * const pxResult,
|
||||
const struct timespec * const x,
|
||||
const struct timespec * const y )
|
||||
{
|
||||
int64_t llResult64 = 0;
|
||||
|
||||
/* Check parameters. */
|
||||
if( ( pxResult == NULL ) || ( x == NULL ) || ( y == NULL ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Perform addition. */
|
||||
llResult64 = ( ( ( int64_t ) ( x->tv_sec ) * NANOSECONDS_PER_SECOND ) + ( int64_t ) ( x->tv_nsec ) )
|
||||
- ( ( ( int64_t ) ( y->tv_sec ) * NANOSECONDS_PER_SECOND ) + ( int64_t ) ( y->tv_nsec ) );
|
||||
|
||||
/* Convert result to timespec. */
|
||||
UTILS_NanosecondsToTimespec( llResult64, pxResult );
|
||||
|
||||
return ( int ) ( llResult64 < 0LL );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
bool UTILS_ValidateTimespec( const struct timespec * const pxTimespec )
|
||||
{
|
||||
bool xReturn = false;
|
||||
|
||||
if( pxTimespec != NULL )
|
||||
{
|
||||
/* Verify 0 <= tv_nsec < 1000000000. */
|
||||
if( ( pxTimespec->tv_nsec >= 0 ) &&
|
||||
( pxTimespec->tv_nsec < NANOSECONDS_PER_SECOND ) )
|
||||
{
|
||||
xReturn = true;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file errno.h
|
||||
* @brief System error numbers.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
|
||||
*
|
||||
* The values defined in this file may not be compatible with the strerror
|
||||
* function provided by this system.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_ERRNO_H_
|
||||
#define _FREERTOS_POSIX_ERRNO_H_
|
||||
|
||||
/* Undefine all errnos to avoid redefinition errors with system errnos. */
|
||||
#undef EPERM
|
||||
#undef ENOENT
|
||||
#undef EBADF
|
||||
#undef EAGAIN
|
||||
#undef ENOMEM
|
||||
#undef EEXIST
|
||||
#undef EBUSY
|
||||
#undef EINVAL
|
||||
#undef ENOSPC
|
||||
#undef ERANGE
|
||||
#undef ENAMETOOLONG
|
||||
#undef EDEADLK
|
||||
#undef EOVERFLOW
|
||||
#undef ENOSYS
|
||||
#undef EMSGSIZE
|
||||
#undef ENOTSUP
|
||||
#undef ETIMEDOUT
|
||||
|
||||
/**
|
||||
* @brief posix_errno Definition of POSIX errnos.
|
||||
*/
|
||||
/**@{ */
|
||||
#define EPERM 1 /**< Operation not permitted. */
|
||||
#define ENOENT 2 /**< No such file or directory. */
|
||||
#define EBADF 9 /**< Bad file descriptor. */
|
||||
#define EAGAIN 11 /**< Resource unavailable, try again. */
|
||||
#define ENOMEM 12 /**< Not enough space. */
|
||||
#define EEXIST 17 /**< File exists. */
|
||||
#define EBUSY 16 /**< Device or resource busy. */
|
||||
#define EINVAL 22 /**< Invalid argument. */
|
||||
#define ENOSPC 28 /**< No space left on device. */
|
||||
#define ERANGE 34 /**< Result too large. */
|
||||
#define ENAMETOOLONG 36 /**< File name too long. */
|
||||
#define EDEADLK 45 /**< Resource deadlock would occur. */
|
||||
#define EOVERFLOW 75 /**< Value too large to be stored in data type. */
|
||||
#define ENOSYS 88 /**< Function not supported. */
|
||||
#define EMSGSIZE 90 /**< Message too long. */
|
||||
#define ENOTSUP 95 /**< Operation not supported. */
|
||||
#define ETIMEDOUT 116 /**< Connection timed out. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @name System Variable
|
||||
*
|
||||
* @brief Define FreeRTOS+POSIX errno, if enabled.
|
||||
* Set configUSE_POSIX_ERRNO to enable, and clear to disable. See FreeRTOS.h.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#if ( configUSE_POSIX_ERRNO == 1 )
|
||||
extern int FreeRTOS_errno;
|
||||
#ifndef errno
|
||||
#define errno FreeRTOS_errno
|
||||
#endif
|
||||
#endif
|
||||
/**@} */
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_ERRNO_H_ */
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fcntl.h
|
||||
* @brief File control options.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_FCNTL_H_
|
||||
#define _FREERTOS_POSIX_FCNTL_H_
|
||||
|
||||
/**
|
||||
* @name File creation flags for use in the oflag value to open() and openat().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define O_CLOEXEC 0x0001 /**< Close the file descriptor upon exec(). */
|
||||
#define O_CREAT 0x0002 /**< Create file if it does not exist. */
|
||||
#define O_DIRECTORY 0x0004 /**< Fail if file is a non-directory file. */
|
||||
#define O_EXCL 0x0008 /**< Exclusive use flag. */
|
||||
#define O_NOCTTY 0x0010 /**< Do not assign controlling terminal. */
|
||||
#define O_NOFOLLOW 0x0020 /**< Do not follow symbolic links. */
|
||||
#define O_TRUNC 0x0040 /**< Truncate flag. */
|
||||
#define O_TTY_INIT 0x0080 /**< termios structure provides conforming behavior. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @name File status flags for open(), openat(), and fcntl().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define O_APPEND 0x0100 /**< Set append mode. */
|
||||
#define O_DSYNC 0x0200 /**< Write according to synchronized I/O data integrity completion. */
|
||||
#define O_NONBLOCK 0x0400 /**< Non-blocking mode. */
|
||||
#define O_RSYNC 0x0800 /**< Synchronized read I/O operations. */
|
||||
#define O_SYNC 0x0200 /**< Write according to synchronized I/O file integrity completion. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @name Mask for file access modes.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define O_ACCMODE 0xF000
|
||||
|
||||
/**
|
||||
* @name File access modes for open(), openat(), and fcntl().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define O_EXEC 0x1000 /**< Open for execute only (non-directory files). */
|
||||
#define O_RDONLY 0x2000 /**< Open for reading only. */
|
||||
#define O_RDWR 0xA000 /**< Open for reading and writing. */
|
||||
#define O_SEARCH 0x4000 /**< Open directory for search only. */
|
||||
#define O_WRONLY 0x8000 /**< Open for writing only. */
|
||||
/**@} */
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_FCNTL_H_ */
|
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mqueue.h
|
||||
* @brief Message queues.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_MQUEUE_H_
|
||||
#define _FREERTOS_POSIX_MQUEUE_H_
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
|
||||
/**
|
||||
* @brief Message queue descriptor.
|
||||
*/
|
||||
typedef void * mqd_t;
|
||||
|
||||
/**
|
||||
* @brief Message queue attributes.
|
||||
*/
|
||||
struct mq_attr
|
||||
{
|
||||
long mq_flags; /**< Message queue flags. */
|
||||
long mq_maxmsg; /**< Maximum number of messages. */
|
||||
long mq_msgsize; /**< Maximum message size. */
|
||||
long mq_curmsgs; /**< Number of messages currently queued. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Close a message queue.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval -1 - A error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EBADF - The mqdes argument is not a valid message queue descriptor.
|
||||
*/
|
||||
int mq_close( mqd_t mqdes );
|
||||
|
||||
/**
|
||||
* @brief Get message queue attributes.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval -1 - A error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* DBADF - The mqdes argument is not a valid message queue descriptor.
|
||||
*/
|
||||
int mq_getattr( mqd_t mqdes,
|
||||
struct mq_attr * mqstat );
|
||||
|
||||
/**
|
||||
* @brief Open a message queue.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html
|
||||
*
|
||||
* @note Supported name pattern: leading <slash> character in name is always required;
|
||||
* the maximum length (excluding null-terminator) of the name argument can be NAME_MAX.
|
||||
* The default value of NAME_MAX in FreeRTOS_POSIX_portable_default.h is 64, which can be
|
||||
* overwritten by user.
|
||||
* @note mode argument is not supported.
|
||||
* @note Supported oflags: O_RDWR, O_CREAT, O_EXCL, and O_NONBLOCK.
|
||||
*
|
||||
* @retval Message queue descriptor -- Upon successful completion
|
||||
* @retval (mqd_t) - 1 -- An error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EINVAL - name argument is invalid (not following name pattern),
|
||||
* OR if O_CREAT is specified in oflag with attr argument not NULL and either mq_maxmsg or mq_msgsize is equal to or less than zero,
|
||||
* OR either O_CREAT or O_EXCL is not set and a queue with the same name is unlinked but pending to be removed.
|
||||
* <br>
|
||||
* EEXIST - O_CREAT and O_EXCL are set and the named message queue already exists.
|
||||
* <br>
|
||||
* ENOSPC - There is insufficient space for the creation of the new message queue.
|
||||
* <br>
|
||||
* ENOENT - O_CREAT is not set and the named message queue does not exist.
|
||||
*/
|
||||
mqd_t mq_open( const char * name,
|
||||
int oflag,
|
||||
mode_t mode,
|
||||
struct mq_attr * attr );
|
||||
|
||||
/**
|
||||
* @brief Receive a message from a message queue.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html
|
||||
*
|
||||
* @note msg_prio argument is not supported. Messages are not checked for corruption.
|
||||
*
|
||||
* @retval The length of the selected message in bytes - Upon successful completion.
|
||||
* The message is removed from the queue
|
||||
* @retval -1 - An error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EBADF - The mqdes argument is not a valid message queue descriptor open for reading.
|
||||
* <br>
|
||||
* EMSGSIZE - The specified message buffer size, msg_len, is less than the message size attribute of the message queue.
|
||||
* <br>
|
||||
* ETIMEDOUT - The O_NONBLOCK flag was not set when the message queue was opened,
|
||||
* but no message arrived on the queue before the specified timeout expired.
|
||||
* <br>
|
||||
* EAGAIN - O_NONBLOCK was set in the message description associated with mqdes, and the specified message queue is empty.
|
||||
*/
|
||||
ssize_t mq_receive( mqd_t mqdes,
|
||||
char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned int * msg_prio );
|
||||
|
||||
/**
|
||||
* @brief Send a message to a message queue.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html
|
||||
*
|
||||
* @note msg_prio argument is not supported.
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
* @retval -1 - An error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EBADF - The mqdes argument is not a valid message queue descriptor open for writing.
|
||||
* <br>
|
||||
* EMSGSIZE - The specified message length, msg_len, exceeds the message size attribute of the message queue,
|
||||
* OR insufficient memory for the message to be sent.
|
||||
* <br>
|
||||
* ETIMEDOUT - The O_NONBLOCK flag was not set when the message queue was opened,
|
||||
* but the timeout expired before the message could be added to the queue.
|
||||
* <br>
|
||||
* EAGAIN - The O_NONBLOCK flag is set in the message queue description associated with mqdes,
|
||||
* and the specified message queue is full.
|
||||
*
|
||||
*/
|
||||
int mq_send( mqd_t mqdes,
|
||||
const char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned msg_prio );
|
||||
|
||||
/**
|
||||
* @brief Receive a message from a message queue with timeout.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_timedreceive.html
|
||||
*
|
||||
* @note msg_prio argument is not supported. Messages are not checked for corruption.
|
||||
*
|
||||
* @retval The length of the selected message in bytes - Upon successful completion.
|
||||
* The message is removed from the queue
|
||||
* @retval -1 - An error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EBADF - The mqdes argument is not a valid message queue descriptor open for reading.
|
||||
* <br>
|
||||
* EMSGSIZE - The specified message buffer size, msg_len, is less than the message size attribute of the message queue.
|
||||
* <br>
|
||||
* EINVAL - The process or thread would have blocked, and the abstime parameter specified a nanoseconds field value
|
||||
* less than zero or greater than or equal to 1000 million.
|
||||
* <br>
|
||||
* ETIMEDOUT - The O_NONBLOCK flag was not set when the message queue was opened,
|
||||
* but no message arrived on the queue before the specified timeout expired.
|
||||
* <br>
|
||||
* EAGAIN - O_NONBLOCK was set in the message description associated with mqdes, and the specified message queue is empty.
|
||||
*/
|
||||
ssize_t mq_timedreceive( mqd_t mqdes,
|
||||
char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned * msg_prio,
|
||||
const struct timespec * abstime );
|
||||
|
||||
/**
|
||||
* @brief Send a message to a message queue with timeout.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_timedsend.html
|
||||
*
|
||||
* @note msg_prio argument is not supported.
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
* @retval -1 - An error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EBADF - The mqdes argument is not a valid message queue descriptor open for writing.
|
||||
* <br>
|
||||
* EMSGSIZE - The specified message length, msg_len, exceeds the message size attribute of the message queue,
|
||||
* OR insufficient memory for the message to be sent.
|
||||
* <br>
|
||||
* EINVAL - The process or thread would have blocked, and the abstime parameter specified a nanoseconds field
|
||||
* value less than zero or greater than or equal to 1000 million.
|
||||
* <br>
|
||||
* ETIMEDOUT - The O_NONBLOCK flag was not set when the message queue was opened,
|
||||
* but the timeout expired before the message could be added to the queue.
|
||||
* <br>
|
||||
* EAGAIN - The O_NONBLOCK flag is set in the message queue description associated with mqdes,
|
||||
* and the specified message queue is full.
|
||||
*
|
||||
*/
|
||||
int mq_timedsend( mqd_t mqdes,
|
||||
const char * msg_ptr,
|
||||
size_t msg_len,
|
||||
unsigned msg_prio,
|
||||
const struct timespec * abstime );
|
||||
|
||||
/**
|
||||
* @brief Remove a message queue.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
* @retval -1 - An error occurred. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EINVAL - name argument is invalid. Refer to requirements on name argument in mq_open().
|
||||
* <br>
|
||||
* ENOENT - The named message queue does not exist.
|
||||
*/
|
||||
int mq_unlink( const char * name );
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_MQUEUE_H_ */
|
@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file pthread.h
|
||||
* @brief Threads.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_PTHREAD_H_
|
||||
#define _FREERTOS_POSIX_PTHREAD_H_
|
||||
|
||||
/* FreeRTOS+POSIX includes. POSIX states that this header shall make symbols
|
||||
* defined in sched.h and time.h visible. */
|
||||
#include "FreeRTOS_POSIX/sched.h"
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
|
||||
/**
|
||||
* @brief pthread detach state.
|
||||
*/
|
||||
/**@{ */
|
||||
#define PTHREAD_CREATE_DETACHED 0 /**< Detached. */
|
||||
#define PTHREAD_CREATE_JOINABLE 1 /**< Joinable (default). */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Returned to a single thread after a successful pthread_barrier_wait.
|
||||
*
|
||||
* POSIX specifies that "The constant PTHREAD_BARRIER_SERIAL_THREAD is defined in <pthread.h> and its value shall be distinct from any other value returned by pthread_barrier_wait()."
|
||||
* So it's defined as negative to distinguish it from the errnos, which are positive.
|
||||
*/
|
||||
#define PTHREAD_BARRIER_SERIAL_THREAD ( -2 )
|
||||
|
||||
/**
|
||||
* @brief Mutex types.
|
||||
*/
|
||||
/**@{ */
|
||||
#ifndef PTHREAD_MUTEX_NORMAL
|
||||
#define PTHREAD_MUTEX_NORMAL 0 /**< Non-robust, deadlock on relock, does not remember owner. */
|
||||
#endif
|
||||
#ifndef PTHREAD_MUTEX_ERRORCHECK
|
||||
#define PTHREAD_MUTEX_ERRORCHECK 1 /**< Non-robust, error on relock, remembers owner. */
|
||||
#endif
|
||||
#ifndef PTHREAD_MUTEX_RECURSIVE
|
||||
#define PTHREAD_MUTEX_RECURSIVE 2 /**< Non-robust, recursive relock, remembers owner. */
|
||||
#endif
|
||||
#ifndef PTHREAD_MUTEX_DEFAULT
|
||||
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL /**< PTHREAD_MUTEX_NORMAL (default). */
|
||||
#endif
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Compile-time initializers.
|
||||
*/
|
||||
/**@{ */
|
||||
#define PTHREAD_COND_INITIALIZER FREERTOS_POSIX_COND_INITIALIZER /**< pthread_cond_t. */
|
||||
|
||||
#if posixconfigENABLE_PTHREAD_MUTEX_T == 1
|
||||
/**
|
||||
* @brief To use this initializer, posixconfigENABLE_PTHREAD_MUTEX_T needs to be set to 1 in FreeRTOS_POSIX_portable_default.h.
|
||||
*/
|
||||
#define PTHREAD_MUTEX_INITIALIZER FREERTOS_POSIX_MUTEX_INITIALIZER /**< pthread_mutex_t. */
|
||||
#endif
|
||||
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Destroy the thread attributes object.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_destroy.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_attr_destroy( pthread_attr_t * attr );
|
||||
|
||||
/**
|
||||
* @brief Get detachstate attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getdetachstate.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*
|
||||
*/
|
||||
int pthread_attr_getdetachstate( const pthread_attr_t * attr,
|
||||
int * detachstate );
|
||||
|
||||
/**
|
||||
* @brief Get schedparam attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getschedparam.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_attr_getschedparam( const pthread_attr_t * attr,
|
||||
struct sched_param * param );
|
||||
|
||||
/**
|
||||
* @brief Get stacksize attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstacksize.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_attr_getstacksize( const pthread_attr_t * attr,
|
||||
size_t * stacksize );
|
||||
|
||||
/**
|
||||
* @brief Initialize the thread attributes object.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_init.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval ENOMEM - Insufficient memory exists to initialize the thread attributes object.
|
||||
*
|
||||
* @note Currently, only stack size, sched param, and detach state attributes
|
||||
* are supported. Also see pthread_attr_get*() and pthread_attr_set*().
|
||||
*/
|
||||
int pthread_attr_init( pthread_attr_t * attr );
|
||||
|
||||
/**
|
||||
* @brief Set detachstate attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setdetachstate.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The value of detachstate was not valid. Currently, supported detach states are -- PTHREAD_CREATE_DETACHED and PTHREAD_CREATE_JOINABLE.
|
||||
*/
|
||||
int pthread_attr_setdetachstate( pthread_attr_t * attr,
|
||||
int detachstate );
|
||||
|
||||
/**
|
||||
* @brief Set schedparam attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setschedparam.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The value of param is not valid.
|
||||
* @retval ENOTSUP - An attempt was made to set the attribute to an unsupported value.
|
||||
*/
|
||||
int pthread_attr_setschedparam( pthread_attr_t * attr,
|
||||
const struct sched_param * param );
|
||||
|
||||
/**
|
||||
* @brief Set stacksize attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setstacksize.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The value of stacksize is less than {PTHREAD_STACK_MIN}
|
||||
*/
|
||||
int pthread_attr_setstacksize( pthread_attr_t * attr,
|
||||
size_t stacksize );
|
||||
|
||||
/**
|
||||
* @brief Destroy a barrier object.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_barrier_destroy.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*
|
||||
* @note This function does not validate whether there is any thread blocking on the barrier before destroying.
|
||||
*/
|
||||
int pthread_barrier_destroy( pthread_barrier_t * barrier );
|
||||
|
||||
/**
|
||||
* @brief Initialize a barrier object.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_barrier_init.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The value specified by count is equal to zero.
|
||||
* @retval ENOMEM - count cannot fit into FreeRTOS event group type OR insufficient memory exists to initialize the barrier.
|
||||
*
|
||||
* @note attr is ignored.
|
||||
*
|
||||
* @note pthread_barrier_init() is implemented with FreeRTOS event group.
|
||||
* To ensure count fits in event group, count may be at most 8 when configUSE_16_BIT_TICKS is 1; it may be at most 24 otherwise.
|
||||
* configUSE_16_BIT_TICKS is configured in application FreeRTOSConfig.h file, which defines how many bits tick count type has.
|
||||
* See further details and limitation about event group and configUSE_16_BIT_TICKS in FreeRTOS site.
|
||||
*/
|
||||
int pthread_barrier_init( pthread_barrier_t * barrier,
|
||||
const pthread_barrierattr_t * attr,
|
||||
unsigned count );
|
||||
|
||||
/**
|
||||
* @brief Synchronize at a barrier.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_barrier_wait.html
|
||||
*
|
||||
* @retval PTHREAD_BARRIER_SERIAL_THREAD - Upon successful completion, the first thread.
|
||||
* @retval 0 - Upon successful completion, other thread(s).
|
||||
*/
|
||||
int pthread_barrier_wait( pthread_barrier_t * barrier );
|
||||
|
||||
/**
|
||||
* @brief Thread creation.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_create.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EAGAIN - Insufficient memory for either thread structure or task creation.
|
||||
*/
|
||||
int pthread_create( pthread_t * thread,
|
||||
const pthread_attr_t * attr,
|
||||
void *( *startroutine )( void * ),
|
||||
void * arg );
|
||||
|
||||
/**
|
||||
* @brief Broadcast a condition.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_cond_broadcast( pthread_cond_t * cond );
|
||||
|
||||
/**
|
||||
* @brief Destroy condition variables.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_destroy.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_cond_destroy( pthread_cond_t * cond );
|
||||
|
||||
/**
|
||||
* @brief Initialize condition variables.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_init.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval ENOMEM - Insufficient memory exists to initialize the condition variable.
|
||||
*
|
||||
* @note attr is ignored and treated as NULL. Default setting is always used.
|
||||
*/
|
||||
int pthread_cond_init( pthread_cond_t * cond,
|
||||
const pthread_condattr_t * attr );
|
||||
|
||||
/**
|
||||
* @brief Signal a condition.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_signal.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_cond_signal( pthread_cond_t * cond );
|
||||
|
||||
/**
|
||||
* @brief Wait on a condition with a timeout.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The abstime argument passed in does not refer to an initialized structure OR
|
||||
* the abstime parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
|
||||
* @retval ETIMEDOUT - The time specified by abstime to pthread_cond_timedwait() has passed.
|
||||
*/
|
||||
int pthread_cond_timedwait( pthread_cond_t * cond,
|
||||
pthread_mutex_t * mutex,
|
||||
const struct timespec * abstime );
|
||||
|
||||
/**
|
||||
* @brief Wait on a condition.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_wait.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_cond_wait( pthread_cond_t * cond,
|
||||
pthread_mutex_t * mutex );
|
||||
|
||||
/**
|
||||
* @brief Compare thread IDs.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_equal.html
|
||||
*
|
||||
* @retval 0 - t1 and t2 are both not NULL && equal
|
||||
* @retval non-zero - otherwise
|
||||
*/
|
||||
int pthread_equal( pthread_t t1,
|
||||
pthread_t t2 );
|
||||
|
||||
/**
|
||||
* @brief Thread termination.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_exit.html
|
||||
*
|
||||
* @retval void - this function cannot return to its caller.
|
||||
*/
|
||||
void pthread_exit( void * value_ptr );
|
||||
|
||||
/**
|
||||
* @brief Dynamic thread scheduling parameters access.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getschedparam.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*
|
||||
* @note policy is always set to SCHED_OTHER by this function.
|
||||
*/
|
||||
int pthread_getschedparam( pthread_t thread,
|
||||
int * policy,
|
||||
struct sched_param * param );
|
||||
|
||||
/**
|
||||
* @brief Wait for thread termination.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EDEADLK - The value specified by the thread argument to pthread_join() does not refer to
|
||||
* a joinable thread OR multiple simultaneous calls to pthread_join() specifying the same target thread OR
|
||||
* the value specified by the thread argument to pthread_join() refers to the calling thread.
|
||||
*/
|
||||
int pthread_join( pthread_t thread,
|
||||
void ** retval );
|
||||
|
||||
/**
|
||||
* @brief Destroy a mutex.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_destroy.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*
|
||||
* @note If there exists a thread holding this mutex, this function returns 0 with mutex not being destroyed.
|
||||
*
|
||||
*/
|
||||
int pthread_mutex_destroy( pthread_mutex_t * mutex );
|
||||
|
||||
/**
|
||||
* @brief Initialize a mutex.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_init.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval ENOMEM - Insufficient memory exists to initialize the mutex structure.
|
||||
* @retval EAGAIN - Unable to initialize the mutex structure member(s).
|
||||
*/
|
||||
int pthread_mutex_init( pthread_mutex_t * mutex,
|
||||
const pthread_mutexattr_t * attr );
|
||||
|
||||
/**
|
||||
* @brief Lock a mutex.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - the abstime parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
|
||||
* @retval EDEADLK - The mutex type is PTHREAD_MUTEX_ERRORCHECK and the current thread already owns the mutex.
|
||||
*
|
||||
*/
|
||||
int pthread_mutex_lock( pthread_mutex_t * mutex );
|
||||
|
||||
/**
|
||||
* @brief Lock a mutex with timeout.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_timedlock.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The abstime argument passed in does not refer to an initialized structure OR
|
||||
* the abstime parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
|
||||
* @retval EDEADLK - The mutex type is PTHREAD_MUTEX_ERRORCHECK and the current thread already owns the mutex.
|
||||
* @retval ETIMEDOUT - The mutex could not be locked before the specified timeout expired.
|
||||
*
|
||||
*/
|
||||
int pthread_mutex_timedlock( pthread_mutex_t * mutex,
|
||||
const struct timespec * abstime );
|
||||
|
||||
/**
|
||||
* @brief Attempt to lock a mutex. Fail immediately if mutex is already locked.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_trylock.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - the abstime parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
|
||||
* @retval EDEADLK - The mutex type is PTHREAD_MUTEX_ERRORCHECK and the current thread already owns the mutex.
|
||||
* @retval EBUSY - The mutex could not be acquired because it was already locked.
|
||||
*
|
||||
*/
|
||||
int pthread_mutex_trylock( pthread_mutex_t * mutex );
|
||||
|
||||
/**
|
||||
* @brief Unlock a mutex.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_unlock.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EPERM - The mutex type is PTHREAD_MUTEX_ERRORCHECK or PTHREAD_MUTEX_RECURSIVE, and the current thread does not own the mutex.
|
||||
*/
|
||||
int pthread_mutex_unlock( pthread_mutex_t * mutex );
|
||||
|
||||
/**
|
||||
* @brief Destroy the mutex attributes object.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_destroy.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_mutexattr_destroy( pthread_mutexattr_t * attr );
|
||||
|
||||
/**
|
||||
* @brief Get the mutex type attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_gettype.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr,
|
||||
int * type );
|
||||
|
||||
/**
|
||||
* @brief Initialize the mutex attributes object.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_init.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval ENOMEM - Insufficient memory exists to initialize the mutex attributes object.
|
||||
*
|
||||
* @note Currently, only the type attribute is supported. Also see pthread_mutexattr_settype() and pthread_mutexattr_gettype().
|
||||
*/
|
||||
int pthread_mutexattr_init( pthread_mutexattr_t * attr );
|
||||
|
||||
/**
|
||||
* @brief Set the mutex type attribute.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_settype.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
* @retval EINVAL - The value type is invalid.
|
||||
*/
|
||||
int pthread_mutexattr_settype( pthread_mutexattr_t * attr,
|
||||
int type );
|
||||
|
||||
/**
|
||||
* @brief Get the calling thread ID.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html
|
||||
*
|
||||
* @retval the thread ID of the calling thread.
|
||||
*/
|
||||
pthread_t pthread_self( void );
|
||||
|
||||
/**
|
||||
* @brief Dynamic thread scheduling parameters access.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_setschedparam.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*
|
||||
* @note policy is ignored; only priority (param.sched_priority) may be changed.
|
||||
*/
|
||||
int pthread_setschedparam( pthread_t thread,
|
||||
int policy,
|
||||
const struct sched_param * param );
|
||||
|
||||
#endif /* _FREERTOS_POSIX_PTHREAD_H_ */
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sched.h
|
||||
* @brief Execution scheduling.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sched.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_SCHED_H_
|
||||
#define _FREERTOS_POSIX_SCHED_H_
|
||||
|
||||
/**
|
||||
* @brief Scheduling Policies
|
||||
*/
|
||||
/**@{ */
|
||||
#define SCHED_OTHER 0 /**< Another scheduling policy. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Scheduling parameters required for implementation of each supported
|
||||
* scheduling policy.
|
||||
*/
|
||||
struct sched_param
|
||||
{
|
||||
int sched_priority; /**< Process or thread execution scheduling priority. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get priority limit.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_get_priority_max.html
|
||||
*
|
||||
* @note policy is ignored.
|
||||
*
|
||||
* @return the maxium priority value (0-based) system configuration allows.
|
||||
* <br>
|
||||
* e.g. if configMAX_PRIORITIES == 7, this function returns (configMAX_PRIORITIES - 1).
|
||||
* configMAX_PRIORITIES is configured in appication FreeRTOSConfig.h file.
|
||||
*/
|
||||
int sched_get_priority_max( int policy );
|
||||
|
||||
/**
|
||||
* @brief Yield the processor.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*/
|
||||
int sched_yield( void );
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_SCHED_H_ */
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file semaphore.h
|
||||
* @brief Semaphores.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/semaphore.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_SEMAPHORE_H_
|
||||
#define _FREERTOS_POSIX_SEMAPHORE_H_
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
|
||||
/**
|
||||
* @brief Semaphore type.
|
||||
*/
|
||||
typedef void * sem_t;
|
||||
|
||||
/**
|
||||
* @brief Destroy an unnamed semaphore.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_destroy.html
|
||||
*
|
||||
* @retval 0 - upon successful completion
|
||||
*
|
||||
* @note Semaphore is destroyed regardless of whether there is any thread currently blocked on this semaphore.
|
||||
*/
|
||||
int sem_destroy( sem_t * sem );
|
||||
|
||||
/**
|
||||
* @brief Get the value of a semaphore.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion
|
||||
*
|
||||
* @note If sem is locked, then the object to which sval points is set to zero.
|
||||
*/
|
||||
int sem_getvalue( sem_t * sem,
|
||||
int * sval );
|
||||
|
||||
/**
|
||||
* @brief Initialize an unnamed semaphore.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html
|
||||
*
|
||||
* @note pshared is ignored. Semaphores will always be considered "shared".
|
||||
*
|
||||
* @retval 0 - upon successful completion
|
||||
* @retval -1 - otherwise. System error variable errno is also set in this case.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EINVAL - The value argument exceeds {SEM_VALUE_MAX}.
|
||||
* <br>
|
||||
* ENOSPC - A resource required to initialize the semaphore has been exhausted.
|
||||
*
|
||||
*/
|
||||
int sem_init( sem_t * sem,
|
||||
int pshared,
|
||||
unsigned value );
|
||||
|
||||
/**
|
||||
* @brief Unlock a semaphore.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html
|
||||
*
|
||||
* @retval 0 - upon successful completion
|
||||
*/
|
||||
int sem_post( sem_t * sem );
|
||||
|
||||
/**
|
||||
* @brief Lock a semaphore with timeout.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html
|
||||
*
|
||||
* @retval 0 - upon successful completion
|
||||
* @retval -1 - otherwise. System error variable errno is also set in this case.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EINVAL - parameter specified a nanoseconds field value less than zero or greater
|
||||
* than or equal to 1000 million
|
||||
* <br>
|
||||
* ETIMEDOUT - The semaphore could not be locked before the specified timeout expired.
|
||||
*
|
||||
* @note Deadlock detection is not implemented.
|
||||
*/
|
||||
int sem_timedwait( sem_t * sem,
|
||||
const struct timespec * abstime );
|
||||
|
||||
/**
|
||||
* @brief Lock a semaphore if available.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_trywait.html
|
||||
*
|
||||
* @retval 0 - upon successful completion
|
||||
* @retval -1 - otherwise. System error variable errno is also set in this case.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EAGAIN - The semaphore was already locked, so it cannot be immediately locked by the sem_trywait() operation.
|
||||
*/
|
||||
int sem_trywait( sem_t * sem );
|
||||
|
||||
/**
|
||||
* @brief Lock a semaphore.
|
||||
*
|
||||
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html
|
||||
*
|
||||
* @retval 0 - upon successful completion
|
||||
* @retval -1 - otherwise. System error variable errno is also set in this case.
|
||||
*
|
||||
* @note Deadlock detection is not implemented.
|
||||
*/
|
||||
int sem_wait( sem_t * sem );
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_SEMAPHORE_H_ */
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file signal.h
|
||||
* @brief Signals.
|
||||
*
|
||||
* Signals are currently not implemented in FreeRTOS+POSIX. This header only
|
||||
* defines the signal data structures used elsewhere.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FREERTOS_POSIX_SIGNAL_H_
|
||||
#define _FREERTOS_POSIX_SIGNAL_H_
|
||||
|
||||
/**
|
||||
* @brief Values of sigev_notify.
|
||||
*/
|
||||
/**@{ */
|
||||
#define SIGEV_NONE 0 /**< No asynchronous notification is delivered when the event of interest occurs. */
|
||||
#define SIGEV_SIGNAL 1 /**< A queued signal, with an application-defined value, is generated when the event of interest occurs. Not supported. */
|
||||
#define SIGEV_THREAD 2 /**< A notification function is called to perform notification. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Signal value.
|
||||
*/
|
||||
union sigval
|
||||
{
|
||||
int sival_int; /**< Integer signal value. */
|
||||
void * sival_ptr; /**< Pointer signal value. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Signal event structure.
|
||||
*/
|
||||
struct sigevent
|
||||
{
|
||||
int sigev_notify; /**< Notification type. A value of SIGEV_SIGNAL is not supported. */
|
||||
int sigev_signo; /**< Signal number. This member is ignored. */
|
||||
union sigval sigev_value; /**< Signal value. Only the sival_ptr member is used. */
|
||||
void ( * sigev_notify_function ) ( union sigval ); /**< Notification function. */
|
||||
pthread_attr_t * sigev_notify_attributes; /**< Notification attributes. */
|
||||
};
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_SIGNAL_H_ */
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sys/types.h
|
||||
* @brief Data types.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_TYPES_H_
|
||||
#define _FREERTOS_POSIX_TYPES_H_
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Used for system times in clock ticks or CLOCKS_PER_SEC.
|
||||
* Enabled/disabled by posixconfigENABLE_CLOCK_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_CLOCK_T ) || ( posixconfigENABLE_CLOCK_T == 1 )
|
||||
typedef uint32_t clock_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for clock ID type in the clock and timer functions.
|
||||
* Enabled/disabled by posixconfigENABLE_CLOCKID_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_CLOCKID_T ) || ( posixconfigENABLE_CLOCKID_T == 1 )
|
||||
typedef int clockid_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for some file attributes.
|
||||
* Enabled/disabled by posixconfigENABLE_MODE_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_MODE_T ) || ( posixconfigENABLE_MODE_T == 1 )
|
||||
typedef int mode_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for process IDs and process group IDs.
|
||||
* Enabled/disabled by posixconfigENABLE_PID_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PID_T ) || ( posixconfigENABLE_PID_T == 1 )
|
||||
typedef int pid_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used to identify a thread attribute object.
|
||||
* Enabled/disabled by posixconfigENABLE_PTHREAD_ATTR_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PTHREAD_ATTR_T ) || ( posixconfigENABLE_PTHREAD_ATTR_T == 1 )
|
||||
typedef void * pthread_attr_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used to identify a barrier.
|
||||
*/
|
||||
typedef void * pthread_barrier_t;
|
||||
|
||||
/**
|
||||
* @brief Used to define a barrier attributes object.
|
||||
*/
|
||||
typedef void * pthread_barrierattr_t;
|
||||
|
||||
/**
|
||||
* @brief Used for condition variables.
|
||||
* Enabled/disabled by posixconfigENABLE_PTHREAD_COND_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PTHREAD_COND_T ) || ( posixconfigENABLE_PTHREAD_COND_T == 1 )
|
||||
typedef void * pthread_cond_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used to identify a condition attribute object.
|
||||
* Enabled/disabled by posixconfigENABLE_PTHREAD_CONDATTR_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PTHREAD_CONDATTR_T ) || ( posixconfigENABLE_PTHREAD_CONDATTR_T == 1 )
|
||||
typedef void * pthread_condattr_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for mutexes.
|
||||
* Enabled/disabled by posixconfigENABLE_PTHREAD_MUTEX_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PTHREAD_MUTEX_T ) || ( posixconfigENABLE_PTHREAD_MUTEX_T == 1 )
|
||||
typedef void * pthread_mutex_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used to identify a mutex attribute object.
|
||||
* Enabled/disabled by posixconfigENABLE_PTHREAD_MUTEXATTR_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PTHREAD_MUTEXATTR_T ) || ( posixconfigENABLE_PTHREAD_MUTEXATTR_T == 1 )
|
||||
typedef void * pthread_mutexattr_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used to identify a thread.
|
||||
* Enabled/disabled by posixconfigENABLE_PTHREAD_T
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_PTHREAD_T ) || ( posixconfigENABLE_PTHREAD_T == 1 )
|
||||
typedef void * pthread_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for a count of bytes or an error indication.
|
||||
* Enabled/disabled by posixconfigENABLE_SSIZE_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_SSIZE_T ) || ( posixconfigENABLE_SSIZE_T == 1 )
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for time in seconds.
|
||||
* Enabled/disabled by posixconfigENABLE_TIME_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_TIME_T ) || ( posixconfigENABLE_TIME_T == 1 )
|
||||
typedef int64_t time_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for timer ID returned by timer_create().
|
||||
* Enabled/disabled by posixconfigENABLE_TIMER_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_TIMER_T ) || ( posixconfigENABLE_TIMER_T == 1 )
|
||||
typedef void * timer_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Used for time in microseconds.
|
||||
* Enabled/disabled by posixconfigENABLE_USECONDS_T.
|
||||
*/
|
||||
#if !defined( posixconfigENABLE_USECONDS_T ) || ( posixconfigENABLE_USECONDS_T == 1 )
|
||||
typedef unsigned long useconds_t;
|
||||
#endif
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_TYPES_H_ */
|
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Amazon FreeRTOS POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file time.h
|
||||
* @brief Time types.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_TIME_H_
|
||||
#define _FREERTOS_POSIX_TIME_H_
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX/sys/types.h"
|
||||
#include "FreeRTOS_POSIX/signal.h"
|
||||
|
||||
/**
|
||||
* @brief Unit conversion constants.
|
||||
*/
|
||||
/**@{ */
|
||||
#define MICROSECONDS_PER_SECOND ( 1000000LL ) /**< Microseconds per second. */
|
||||
#define NANOSECONDS_PER_SECOND ( 1000000000LL ) /**< Nanoseconds per second. */
|
||||
#define NANOSECONDS_PER_TICK ( NANOSECONDS_PER_SECOND / configTICK_RATE_HZ ) /**< Nanoseconds per FreeRTOS tick. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Clock identifiers.
|
||||
*/
|
||||
/**@{ */
|
||||
#define CLOCK_REALTIME 0 /**< The identifier of the system-wide clock measuring real time. */
|
||||
#define CLOCK_MONOTONIC 1 /**< The identifier for the system-wide monotonic clock.*/
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief A number used to convert the value returned by the clock() function into seconds.
|
||||
*/
|
||||
#define CLOCKS_PER_SEC ( ( clock_t ) configTICK_RATE_HZ )
|
||||
|
||||
/**
|
||||
* @brief Flag indicating time is absolute.
|
||||
*
|
||||
* For functions taking timer objects, this refers to the clock associated with the timer.
|
||||
*/
|
||||
#define TIMER_ABSTIME 0x01
|
||||
|
||||
#if !defined( posixconfigENABLE_TIMESPEC ) || ( posixconfigENABLE_TIMESPEC == 1 )
|
||||
/**
|
||||
* @brief represents an elapsed time
|
||||
*/
|
||||
struct timespec
|
||||
{
|
||||
time_t tv_sec; /**< Seconds. */
|
||||
long tv_nsec; /**< Nanoseconds. */
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !defined( posixconfigENABLE_ITIMERSPEC ) || ( posixconfigENABLE_ITIMERSPEC == 1 )
|
||||
/**
|
||||
* @brief timer
|
||||
*/
|
||||
struct itimerspec
|
||||
{
|
||||
struct timespec it_interval; /**< Timer period. */
|
||||
struct timespec it_value; /**< Timer expiration. */
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !defined( posixconfigENABLE_TM ) || ( posixconfigENABLE_TM == 1 )
|
||||
/**
|
||||
* @brief calendar representation of time
|
||||
*/
|
||||
struct tm
|
||||
{
|
||||
time_t tm_tick; /**< FreeRTOS tick count. */
|
||||
int tm_sec; /**< Seconds [0,60]. Not used. */
|
||||
int tm_min; /**< Minutes [0,59]. Not used. */
|
||||
int tm_hour; /**< Hour [0,23]. Not used. */
|
||||
int tm_mday; /**< Day of month [1,31]. Not used. */
|
||||
int tm_mon; /**< Month of year [0,11]. Not used. */
|
||||
int tm_year; /**< Years since 1900. Not used. */
|
||||
int tm_wday; /**< Day of week [0,6] (Sunday=0). Not used. */
|
||||
int tm_yday; /**< Day of year [0,365]. Not used. */
|
||||
int tm_isdst; /**< Daylight Savings flag. Not used. */
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Report CPU time used.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html
|
||||
*
|
||||
* @return The number of FreeRTOS ticks since the scheduler
|
||||
* was started minus the ticks spent in the idle task.
|
||||
*
|
||||
* @note This function does NOT report the number of ticks spent by the calling thread.
|
||||
*/
|
||||
clock_t clock( void );
|
||||
|
||||
/**
|
||||
* @brief Access a process CPU-time clock.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getcpuclockid.html
|
||||
*
|
||||
* @retval EPERM
|
||||
*
|
||||
* @note This function is currently unsupported.
|
||||
*
|
||||
*/
|
||||
int clock_getcpuclockid( pid_t pid,
|
||||
clockid_t * clock_id );
|
||||
|
||||
/**
|
||||
* @brief Returns the resolution of a clock.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html
|
||||
*
|
||||
* @note clock_id is ignored
|
||||
* @note This function stores the resolution of the FreeRTOS tick count in the object res points to.
|
||||
*
|
||||
* @retval 0 - Upon successful execution
|
||||
*/
|
||||
int clock_getres( clockid_t clock_id,
|
||||
struct timespec * res );
|
||||
|
||||
/**
|
||||
* @brief Returns the current value for the specified clock, clock_id.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html
|
||||
*
|
||||
* @note clock_id is ignored
|
||||
* @note this function does not check for overflows of time_t.
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
*
|
||||
*/
|
||||
int clock_gettime( clockid_t clock_id,
|
||||
struct timespec * tp );
|
||||
|
||||
/**
|
||||
* @brief High resolution sleep with specifiable clock.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html
|
||||
*
|
||||
* @note clock_id is ignored, as this function uses the FreeRTOS tick count as its clock.
|
||||
* @note flags is ignored, if INCLUDE_vTaskDelayUntil is 0. i.e. the FreeRTOS function vTaskDelayUntil isn't available.
|
||||
* @note rmtp is also ignored, as signals are not implemented.
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
* @retval EINVAL - The rqtp argument specified a nanosecond value less than zero or greater than or equal to 1000 million.
|
||||
*/
|
||||
int clock_nanosleep( clockid_t clock_id,
|
||||
int flags,
|
||||
const struct timespec * rqtp,
|
||||
struct timespec * rmtp );
|
||||
|
||||
/**
|
||||
* @brief Sets the time for the specified clock.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_settime.html
|
||||
*
|
||||
* @retval -1 with errno set to EPERM.
|
||||
*
|
||||
* @note This function is currently unsupported, as FreeRTOS does not provide a function to modify the tick count.
|
||||
*/
|
||||
int clock_settime( clockid_t clock_id,
|
||||
const struct timespec * tp );
|
||||
|
||||
/**
|
||||
* @brief Convert a time value to a broken-down local time.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime_r.html
|
||||
*
|
||||
* @note timer is ignored
|
||||
*
|
||||
* @note This function can only store the time as tm.tm_tick. All other members of
|
||||
* the struct will be set to 0.
|
||||
*
|
||||
* @note In order to store tm.tm_tick in result, posixconfgENABLE_TM needs to be set to 1.
|
||||
* See FreeRTOS_POSIX_portable_default.h for porting configurations.
|
||||
*
|
||||
* @return Upon successful completion, returns a pointer points to the object holding structure of type tm.
|
||||
* @return If any error, rutrns NULL, with errno set to ENOTSUP.
|
||||
*/
|
||||
struct tm * localtime_r( const time_t * timer,
|
||||
struct tm * result );
|
||||
|
||||
/**
|
||||
* @brief High resolution sleep.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html
|
||||
*
|
||||
* @note rmtp is ignored, as signals are not implemented.
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
* @retval -1 - The rqtp argument is invalid OR the rqtp argument specified a nanosecond value less than zero or greater than or equal to 1000 million.
|
||||
*
|
||||
*/
|
||||
int nanosleep( const struct timespec * rqtp,
|
||||
struct timespec * rmtp );
|
||||
|
||||
/**
|
||||
* @brief Convert date and time to a string.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html
|
||||
*
|
||||
* @note format is ignored.
|
||||
*
|
||||
* @retval the number of bytes placed into the array pointed to by s,
|
||||
* if the total number of resulting bytes including the terminating null byte is not more than maxsize.
|
||||
* @retval 0, otherwise. In this case, the array pointed to by s contains partially copied data.
|
||||
*/
|
||||
size_t strftime( char * s,
|
||||
size_t maxsize,
|
||||
const char * format,
|
||||
const struct tm * timeptr );
|
||||
|
||||
/**
|
||||
* @brief Get time.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/time.html
|
||||
*
|
||||
* @note This function returns the FreeRTOS tick count, not the seconds since UNIX epoch.
|
||||
*
|
||||
* @retval FreeRTOS tick count - upon successful completion
|
||||
*/
|
||||
time_t time( time_t * tloc );
|
||||
|
||||
/**
|
||||
* @brief Create a per-process timer.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html
|
||||
*
|
||||
* @note clock_id is ignored, as this function used the FreeRTOS tick count as its clock.
|
||||
* @note evp.sigev_notify must be set to SIGEV_THREAD, since signals are currently not supported.
|
||||
*
|
||||
* @retval 0 - Upon successful completion, with location referenced by timerid updated.
|
||||
* @retval -1 - If an error occurs. errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* ENOTSUP - If evp is NULL OR evp->sigen_notify == SIGEV_SIGNAL.
|
||||
* <br>
|
||||
* EAGAIN - The system lacks sufficient signal queuing resources to honor the request.
|
||||
*/
|
||||
int timer_create( clockid_t clockid,
|
||||
struct sigevent * evp,
|
||||
timer_t * timerid );
|
||||
|
||||
/**
|
||||
* @brief Delete a per-process timer.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_delete.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
*/
|
||||
int timer_delete( timer_t timerid );
|
||||
|
||||
/**
|
||||
* @brief Get the timer overrun count.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_getoverrun.html
|
||||
*
|
||||
* @retval 0 - Always return 0, since signals are not supported.
|
||||
*/
|
||||
int timer_getoverrun( timer_t timerid );
|
||||
|
||||
/**
|
||||
* @brief Get the amount of time until the timer expires.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_gettime.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
*/
|
||||
int timer_gettime( timer_t timerid,
|
||||
struct itimerspec * value );
|
||||
|
||||
/**
|
||||
* @brief Set the time until the next expiration of the timer.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime.html
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
* @retval -1 - An error occured, errno is also set.
|
||||
*
|
||||
* \sideeffect Possible errno values
|
||||
* <br>
|
||||
* EINVAL - A value structure specified a nanosecond value less than zero or greater than or equal to 1000 million,
|
||||
* AND the it_value member of that structure did not specify zero seconds and nanoseconds.
|
||||
*/
|
||||
int timer_settime( timer_t timerid,
|
||||
int flags,
|
||||
const struct itimerspec * value,
|
||||
struct itimerspec * ovalue );
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_TIME_H_ */
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file unistd.h
|
||||
* @brief Standard symbolic constants and types
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_UNISTD_H_
|
||||
#define _FREERTOS_POSIX_UNISTD_H_
|
||||
|
||||
/**
|
||||
* @brief Suspend execution for an interval of time.
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html
|
||||
*
|
||||
* @param[in] seconds The number of seconds to suspend execution.
|
||||
*
|
||||
* @retval 0 - Upon successful completion.
|
||||
*
|
||||
* @note Return value of a positive number is not yet supported.
|
||||
*/
|
||||
unsigned sleep( unsigned seconds );
|
||||
|
||||
/**
|
||||
* @brief Suspend execution for microsecond intervals.
|
||||
*
|
||||
* This is a useful, non-POSIX function.
|
||||
* @param[in] usec The number of microseconds to suspend execution.
|
||||
*
|
||||
* @retval 0 - Upon successful cocmpletion.
|
||||
*/
|
||||
int usleep( useconds_t usec );
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_UNISTD_H_ */
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Amazon FreeRTOS+POSIX V1.0.0
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file utils.h
|
||||
* @brief Utility functions used by FreeRTOS+POSIX.
|
||||
*/
|
||||
|
||||
#ifndef _FREERTOS_POSIX_UTILS_
|
||||
#define _FREERTOS_POSIX_UTILS_
|
||||
|
||||
/* C standard library includes. */
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS+POSIX includes. */
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
|
||||
/**
|
||||
* @brief Calculates the length of pcString, up to xMaxLength.
|
||||
*
|
||||
* @param[in] pcString The string to find the length of.
|
||||
* @param[in] xMaxLength The limit when searching for the end of pcString.
|
||||
*
|
||||
* @return 0 if pcString is NULL; otherwise, the length of pcString or xMaxLength,
|
||||
* whichever is smaller.
|
||||
*/
|
||||
size_t UTILS_strnlen( const char * const pcString,
|
||||
size_t xMaxLength );
|
||||
|
||||
/**
|
||||
* @brief Calculates the number of ticks between now and a given timespec.
|
||||
*
|
||||
* @param[in] pxAbsoluteTime A time in the future, specified as seconds and
|
||||
* nanoseconds since CLOCK_REALTIME's 0.
|
||||
* @param[out] pxResult Where the result of the conversion is stored. The result
|
||||
* is rounded up for fractional ticks.
|
||||
*
|
||||
* @return 0 on success. Otherwise, ETIMEDOUT if pxAbsoluteTime is in the past,
|
||||
* or EINVAL for invalid parameters.
|
||||
*/
|
||||
int UTILS_AbsoluteTimespecToTicks( const struct timespec * const pxAbsoluteTime,
|
||||
TickType_t * const pxResult );
|
||||
|
||||
/**
|
||||
* @brief Converts a struct timespec to FreeRTOS ticks.
|
||||
*
|
||||
* @param[in] pxTimespec The timespec to convert.
|
||||
* @param[out] pxResult Where the result of the conversion is stored. The result is rounded
|
||||
* up for fractional ticks.
|
||||
*
|
||||
* @return 0 on success. Otherwise, EINVAL for invalid parameters.
|
||||
*/
|
||||
int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
|
||||
TickType_t * const pxResult );
|
||||
|
||||
/**
|
||||
* @brief Converts an integer value to a timespec.
|
||||
*
|
||||
* @param[in] llSource The value to convert.
|
||||
* @param[out] pxDestination Where to store the converted value.
|
||||
*
|
||||
* @return No return value.
|
||||
*/
|
||||
void UTILS_NanosecondsToTimespec( int64_t llSource,
|
||||
struct timespec * const pxDestination );
|
||||
|
||||
/**
|
||||
* @brief Calculates pxResult = x + y.
|
||||
*
|
||||
* @param[out] pxResult Where the result of the calculation is stored.
|
||||
* @param[in] x The first argument for addition.
|
||||
* @param[in] y The second argument for addition.
|
||||
*
|
||||
* @return -1 if any argument was NULL; 1 if result is negative; otherwise, 0.
|
||||
*/
|
||||
int UTILS_TimespecAdd( struct timespec * const pxResult,
|
||||
const struct timespec * const x,
|
||||
const struct timespec * const y );
|
||||
|
||||
/**
|
||||
* @brief Calculates pxResult = x + ( struct timespec ) nanosec.
|
||||
*
|
||||
* @param[out] pxResult Where the result of the calculation is stored.
|
||||
* @param[in] x The first argument for addition.
|
||||
* @param[in] llNanoseconds The second argument for addition.
|
||||
*
|
||||
* @return -1 if pxResult or x was NULL; 1 if result is negative; otherwise, 0.
|
||||
*/
|
||||
int UTILS_TimespecAddNanoseconds( struct timespec * const pxResult,
|
||||
const struct timespec * const x,
|
||||
int64_t llNanoseconds );
|
||||
|
||||
/**
|
||||
* @brief Calculates pxResult = x - y.
|
||||
*
|
||||
* @param[out] pxResult Where the result of the calculation is stored.
|
||||
* @param[in] x The first argument for subtraction.
|
||||
* @param[in] y The second argument for subtraction.
|
||||
*
|
||||
* @return -1 if any argument was NULL; 1 if result is negative; otherwise, 0.
|
||||
*/
|
||||
int UTILS_TimespecSubtract( struct timespec * const pxResult,
|
||||
const struct timespec * const x,
|
||||
const struct timespec * const y );
|
||||
|
||||
/**
|
||||
* @brief Checks that a timespec conforms to POSIX.
|
||||
*
|
||||
* A valid timespec must have 0 <= tv_nsec < 1000000000.
|
||||
*
|
||||
* @param[in] pxTimespec The timespec to validate.
|
||||
*
|
||||
* @return true if the pxTimespec is valid, false otherwise.
|
||||
*/
|
||||
bool UTILS_ValidateTimespec(const struct timespec * const pxTimespec);
|
||||
|
||||
#endif /* ifndef _FREERTOS_POSIX_UTILS_ */
|
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Amazon FreeRTOS
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file aws_doubly_linked_list.h
|
||||
* @brief Doubly Linked List implementation.
|
||||
*
|
||||
* A generic implementation of circular Doubly Linked List which consists of a
|
||||
* list head and some list entries (zero in case of an empty list).
|
||||
*
|
||||
* To start with, a structure of type Link_t should be embedded in the structure
|
||||
* which is to be organized as doubly linked list.
|
||||
* @code
|
||||
* typedef struct UserStruct
|
||||
* {
|
||||
* uint32_t ulField1;
|
||||
* uint32_t ulField2;
|
||||
* Link_t xLink;
|
||||
* } UserStruct_t;
|
||||
* @endcode
|
||||
*
|
||||
* A List head should then be defined and initialized.
|
||||
* @code
|
||||
* Link_t xListHead;
|
||||
* listINIT_HEAD( &xListHead );
|
||||
* @endcode
|
||||
*
|
||||
* listADD can then be used to add nodes to the list.
|
||||
* @code
|
||||
* listADD( &( xListHead ), &( pxUserStruct->xLink ) );
|
||||
* @endcode
|
||||
*
|
||||
* listFOR_EACH can be used for traversing the list.
|
||||
* @code
|
||||
* Link_t *pxLink;
|
||||
* UserStruct_t *pxUserStruct;
|
||||
* listFOR_EACH( pxLink, &( xListHead ) )
|
||||
* {
|
||||
* pxUserStruct = listCONTAINER( pxLink, UserStruct_t, xLink );
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* listFOR_EACH_SAFE should be used if you want to perform destructive operations
|
||||
* (like free) on nodes while traversing the list.
|
||||
* @code
|
||||
* Link_t *pxLink, *pxTempLink;
|
||||
* UserStruct_t *pxUserStruct;
|
||||
* listFOR_EACH( pxLink, pxTempLink, &( xListHead ) )
|
||||
* {
|
||||
* pxUserStruct = listCONTAINER( pxLink, UserStruct_t, xLink );
|
||||
* free( pxUserStruct );
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
#ifndef _AWS_DOUBLY_LINKED_LIST_H_
|
||||
#define _AWS_DOUBLY_LINKED_LIST_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Struct embedded in any struct to make it a doubly linked
|
||||
* list.
|
||||
*
|
||||
* pxNext in the head points to the first node in the list and pxPrev
|
||||
* in the head points to the last node in the list. In case of empty
|
||||
* list, both pxPrev and pxNext in the head point to the head node itself.
|
||||
*/
|
||||
typedef struct Link
|
||||
{
|
||||
struct Link * pxPrev; /**< Pointer to the previous node. */
|
||||
struct Link * pxNext; /**< Pointer to the next node. */
|
||||
} Link_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the given list head to an empty list.
|
||||
*
|
||||
* @param[in] pxHead The given list head to initialize.
|
||||
*/
|
||||
#define listINIT_HEAD( pxHead ) \
|
||||
{ \
|
||||
( pxHead )->pxPrev = ( pxHead ); \
|
||||
( pxHead )->pxNext = ( pxHead ); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds the given new node to the given list.
|
||||
*
|
||||
* @param[in] pxHead The head of the given list.
|
||||
* @param[in] pxLink The given new node to be added to the given
|
||||
* list.
|
||||
*/
|
||||
#define listADD( pxHead, pxLink ) \
|
||||
{ \
|
||||
Link_t * pxPrevLink = ( pxHead ); \
|
||||
Link_t * pxNextLink = ( ( pxHead )->pxNext ); \
|
||||
\
|
||||
( pxLink )->pxNext = pxNextLink; \
|
||||
pxNextLink->pxPrev = ( pxLink ); \
|
||||
pxPrevLink->pxNext = ( pxLink ); \
|
||||
( pxLink )->pxPrev = ( pxPrevLink ); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes the given node from the list it is part of.
|
||||
*
|
||||
* If the given node is not a part of any list (i.e. next and previous
|
||||
* nodes are NULL), nothing happens.
|
||||
*
|
||||
* @param[in] pxLink The given node to remove from the list.
|
||||
*/
|
||||
#define listREMOVE( pxLink ) \
|
||||
{ \
|
||||
/* If the link is part of a list, remove it from the list. */ \
|
||||
if( ( pxLink )->pxNext != NULL && ( pxLink )->pxPrev != NULL ) \
|
||||
{ \
|
||||
( pxLink )->pxPrev->pxNext = ( pxLink )->pxNext; \
|
||||
( pxLink )->pxNext->pxPrev = ( pxLink )->pxPrev; \
|
||||
} \
|
||||
\
|
||||
/* Make sure that this link is not part of any list anymore. */ \
|
||||
( pxLink )->pxPrev = NULL; \
|
||||
( pxLink )->pxNext = NULL; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given the head of a list, checks if the list is empty.
|
||||
*
|
||||
* @param[in] pxHead The head of the given list.
|
||||
*/
|
||||
#define listIS_EMPTY( pxHead ) ( ( ( pxHead ) == NULL ) || ( ( pxHead )->pxNext == ( pxHead ) ) )
|
||||
|
||||
/**
|
||||
* @brief Removes the first node from the given list and returns it.
|
||||
*
|
||||
* Removes the first node from the given list and assigns it to the
|
||||
* pxLink parameter. If the list is empty, it assigns NULL to the
|
||||
* pxLink.
|
||||
*
|
||||
* @param[in] pxHead The head of the list from which to remove the
|
||||
* first node.
|
||||
* @param[out] pxLink The output parameter to receive the removed
|
||||
* node.
|
||||
*/
|
||||
#define listPOP( pxHead, pxLink ) \
|
||||
{ \
|
||||
if( listIS_EMPTY( ( pxHead ) ) ) \
|
||||
{ \
|
||||
( pxLink ) = NULL; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
( pxLink ) = ( pxHead )->pxNext; \
|
||||
/* If the link is part of a list, remove it from the list. */ \
|
||||
if( ( pxLink )->pxNext != NULL && ( pxLink )->pxPrev != NULL ) \
|
||||
{ \
|
||||
( pxLink )->pxPrev->pxNext = ( pxLink )->pxNext; \
|
||||
( pxLink )->pxNext->pxPrev = ( pxLink )->pxPrev; \
|
||||
} \
|
||||
\
|
||||
/* Make sure that this link is not part of any list anymore. */ \
|
||||
( pxLink )->pxPrev = NULL; \
|
||||
( pxLink )->pxNext = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Merges a list into a given list.
|
||||
*
|
||||
* @param[in] pxHeadResultList The head of the given list into which the
|
||||
* other list should be merged.
|
||||
* @param[in] pxHeadListToMerge The head of the list to be merged into the
|
||||
* given list.
|
||||
*/
|
||||
#define listMERGE( pxHeadResultList, pxHeadListToMerge ) \
|
||||
{ \
|
||||
if( !listIS_EMPTY( ( pxHeadListToMerge ) ) ) \
|
||||
{ \
|
||||
/* Setup links between last node of listToMerge and first node of resultList. */ \
|
||||
( pxHeadListToMerge )->pxPrev->pxNext = ( pxHeadResultList )->pxNext; \
|
||||
( pxHeadResultList )->pxNext->pxPrev = ( pxHeadListToMerge )->pxPrev; \
|
||||
\
|
||||
/* Setup links between first node of listToMerge and the head of resultList. */ \
|
||||
( pxHeadListToMerge )->pxNext->pxPrev = ( pxHeadResultList ); \
|
||||
( pxHeadResultList )->pxNext = ( pxHeadListToMerge )->pxNext; \
|
||||
/* Empty the merged list. */ \
|
||||
listINIT_HEAD( ( pxHeadListToMerge ) ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to iterate over a list. pxLink contains the link node
|
||||
* in each iteration.
|
||||
*/
|
||||
#define listFOR_EACH( pxLink, pxHead ) \
|
||||
for( ( pxLink ) = ( pxHead )->pxNext; \
|
||||
( pxLink ) != ( pxHead ); \
|
||||
( pxLink ) = ( pxLink )->pxNext )
|
||||
|
||||
/**
|
||||
* @brief Helper macro to iterate over a list. It is safe to destroy/free the
|
||||
* nodes while iterating. pxLink contains the link node in each iteration.
|
||||
*/
|
||||
#define listFOR_EACH_SAFE( pxLink, pxTempLink, pxHead ) \
|
||||
for( ( pxLink ) = ( pxHead )->pxNext, ( pxTempLink ) = ( pxLink )->pxNext; \
|
||||
( pxLink ) != ( pxHead ); \
|
||||
( pxLink ) = ( pxTempLink ), ( pxTempLink ) = ( pxLink )->pxNext )
|
||||
|
||||
/**
|
||||
* @brief Given the pointer to the link member (of type Link_t) in a struct,
|
||||
* extracts the pointer to the containing struct.
|
||||
*
|
||||
* @param[in] pxLink The pointer to the link member.
|
||||
* @param[in] type The type of the containing struct.
|
||||
* @param[in] member Name of the link member in the containing struct.
|
||||
*/
|
||||
#define listCONTAINER( pxLink, type, member ) ( ( type * ) ( ( uint8_t * ) ( pxLink ) - ( uint8_t * ) ( &( ( type * ) 0 )->member ) ) )
|
||||
|
||||
#endif /* _AWS_DOUBLY_LINKED_LIST_H_ */
|
197
FreeRTOS-Plus/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/main.c
Executable file
197
FreeRTOS-Plus/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/main.c
Executable file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* FreeRTOS POSIX Demo V1.0.0
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* -NOTE- The Win32 port is a simulation (or is that emulation?) only! Do not
|
||||
* expect to get real time behaviour from the Win32 port or this demo
|
||||
* application. It is provided as a convenient development and demonstration
|
||||
* test bed only. This was tested using Windows 10 with Intel Core i7-6700 CPU.
|
||||
*
|
||||
* Windows will not be running the FreeRTOS simulator threads continuously, so
|
||||
* the timing information has no meaningful units. See the documentation page for
|
||||
* the Windows simulator for an explanation of the slow timing:
|
||||
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
|
||||
* - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -
|
||||
*
|
||||
* Documentation for this demo can be found on:
|
||||
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/demo/posix_demo.html
|
||||
******************************************************************************
|
||||
*
|
||||
*
|
||||
* /* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* System headers */
|
||||
#include <stdio.h>
|
||||
|
||||
/* demo include */
|
||||
#include "posix_demo.h"
|
||||
|
||||
/* Demo task priority */
|
||||
#define mainPOSIX_DEMO_PRIORITY ( tskIDLE_PRIORITY + 4 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int main( void )
|
||||
{
|
||||
configASSERT( ( mainPOSIX_DEMO_PRIORITY < configMAX_PRIORITIES ) );
|
||||
|
||||
const uint32_t ulLongTime_ms = pdMS_TO_TICKS( 1000UL );
|
||||
|
||||
printf( "FreeRTOS POSIX demo\n" );
|
||||
|
||||
/* Start the task to run POSIX demo */
|
||||
xTaskCreate( vStartPOSIXDemo,
|
||||
"posix",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainPOSIX_DEMO_PRIORITY,
|
||||
NULL );
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well, the scheduler will now be running, and the following
|
||||
* line will never be reached. If the following line does execute, then
|
||||
* there was insufficient FreeRTOS heap memory available for the idle and/or
|
||||
* timer tasks to be created. See the memory management section on the
|
||||
* FreeRTOS web site for more details (this is standard text that is not
|
||||
* really applicable to the Win32 simulator port). */
|
||||
for( ; ; )
|
||||
{
|
||||
Sleep( ulLongTime_ms );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vAssertCalled( const char * pcFile,
|
||||
uint32_t ulLine )
|
||||
{
|
||||
const uint32_t ulLongSleep = 1000UL;
|
||||
volatile uint32_t ulBlockVariable = 0UL;
|
||||
volatile char * pcFileName = ( volatile char * ) pcFile;
|
||||
volatile uint32_t ulLineNumber = ulLine;
|
||||
|
||||
( void ) pcFileName;
|
||||
( void ) ulLineNumber;
|
||||
|
||||
printf( "vAssertCalled %s, %ld\n", pcFile, ( long ) ulLine );
|
||||
fflush( stdout );
|
||||
|
||||
/* Setting ulBlockVariable to a non-zero value in the debugger will allow
|
||||
* this function to be exited. */
|
||||
taskDISABLE_INTERRUPTS();
|
||||
{
|
||||
while( ulBlockVariable == 0UL )
|
||||
{
|
||||
Sleep( ulLongSleep );
|
||||
}
|
||||
}
|
||||
taskENABLE_INTERRUPTS();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
|
||||
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
||||
* used by the Idle task. */
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
|
||||
StackType_t ** ppxIdleTaskStackBuffer,
|
||||
uint32_t * pulIdleTaskStackSize )
|
||||
{
|
||||
/* If the buffers to be provided to the Idle task are declared inside this
|
||||
* function then they must be declared static - otherwise they will be allocated on
|
||||
* the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Idle
|
||||
* task's state will be stored. */
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Idle task's stack. */
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||
* Note that, as the array is necessarily of type StackType_t,
|
||||
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||
* to provide the memory that is used by the Timer service task. */
|
||||
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
|
||||
StackType_t ** ppxTimerTaskStackBuffer,
|
||||
uint32_t * pulTimerTaskStackSize )
|
||||
{
|
||||
/* If the buffers to be provided to the Timer task are declared inside this
|
||||
* function then they must be declared static - otherwise they will be allocated on
|
||||
* the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xTimerTaskTCB;
|
||||
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
||||
* task's state will be stored. */
|
||||
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Timer task's stack. */
|
||||
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
||||
* Note that, as the array is necessarily of type StackType_t,
|
||||
* configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
|
||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Warn user if pvPortMalloc fails.
|
||||
*
|
||||
* Called if a call to pvPortMalloc() fails because there is insufficient
|
||||
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
|
||||
* internally by FreeRTOS API functions that create tasks, queues, software
|
||||
* timers, and semaphores. The size of the FreeRTOS heap is set by the
|
||||
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h.
|
||||
*
|
||||
*/
|
||||
void vApplicationMallocFailedHook()
|
||||
{
|
||||
taskDISABLE_INTERRUPTS();
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
366
FreeRTOS-Plus/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/posix_demo.c
Executable file
366
FreeRTOS-Plus/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/posix_demo.c
Executable file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* FreeRTOS POSIX Demo V1.0.0
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Demo intro: job distribution with actor model.
|
||||
*
|
||||
* This demo simulates job distribution with actor model.
|
||||
* https://en.wikipedia.org/wiki/Actor_model
|
||||
*
|
||||
* In this demo, vStartPOSIXDemo() first creates all mailboxes
|
||||
* which will be used by actors to send and receive messages.
|
||||
* Then it spins up two types of actors -- Dispatcher and Workers.
|
||||
*
|
||||
* Dispatcher -- Distributing sub-tasks to workers.
|
||||
* Distribution is done by putting messages into each worker's inbox,
|
||||
* which is essentially an mqueue. Dispatcher keeps distributing tasks
|
||||
* until all intended tasks are distributed.
|
||||
*
|
||||
* Workers -- Take sub-tasks and perform predefined routine for each type of tasks.
|
||||
*
|
||||
* Upon finishing distributing all tasks, Dispatcher will send a "terminate" message to
|
||||
* each worker. vStartPOSIXDemo() will then join all actor threads and clean up mailboxes.
|
||||
*
|
||||
* @note A few assumptions are made in this demo, which a user might have to alter
|
||||
* if to adopt this model in a new application:
|
||||
*
|
||||
* - The upper limit for MQUEUE_NUMBER_OF_WORKERS is set to 10.
|
||||
* This is not due to physical constraint (e.g. memory), rather to make queue
|
||||
* names end with a single digit number.
|
||||
*
|
||||
* - Message enum is cast to char/uint8_t directly, with the assumption that
|
||||
* the system is not going to have more than 254 messages, which is often true
|
||||
* in practice. Could extend bits used in a message to either have more messages
|
||||
* or include additional arguments for a message. Proper typecasting is needed
|
||||
* in that case.
|
||||
*
|
||||
* - The philosophy is "failure is expected". It is shown in both the way dispatcher
|
||||
* delivers messages (i.e. messages can be dropped by worker(s)), and also the
|
||||
* way workers process messages (i.e. workers do not inform dispatcher success or
|
||||
* failure).
|
||||
*
|
||||
* - Following the philosophy, dispatcher shall never use blocking calls to distribute
|
||||
* tasks. The only exception made here is that dispatcher needs to make sure the
|
||||
* successful delivery of "terminate" messages. So that, main thread could join
|
||||
* all actor threads and finish the demo.
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
|
||||
/* System headers. */
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Demo includes. */
|
||||
#include "posix_demo.h"
|
||||
|
||||
/* FreeRTOS+POSIX. */
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
#include "FreeRTOS_POSIX/mqueue.h"
|
||||
#include "FreeRTOS_POSIX/time.h"
|
||||
#include "FreeRTOS_POSIX/fcntl.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
|
||||
/* Constants. */
|
||||
#define LINE_BREAK "\r\n"
|
||||
|
||||
/**
|
||||
* @brief Control messages.
|
||||
*
|
||||
* uint8_t is sufficient for this enum, that we are going to cast to char directly.
|
||||
* If ever needed, implement a function to properly typecast.
|
||||
*/
|
||||
/**@{ */
|
||||
typedef enum ControlMessage
|
||||
{
|
||||
eMSG_LOWER_INAVLID = 0x00, /**< Guard, let's not use 0x00 for messages. */
|
||||
eWORKER_CTRL_MSG_CONTINUE = 0x01, /**< Dispatcher to worker, distributing another job. */
|
||||
eWORKER_CTRL_MSG_EXIT = 0x02, /**< Dispatcher to worker, all jobs are finished and the worker receiving such can exit. */
|
||||
|
||||
/* define additional messages here */
|
||||
|
||||
eMSG_UPPER_INVALID = 0xFF /**< Guard, additional tasks shall be defined above. */
|
||||
} eControlMessage;
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @defgroup Configuration constants for the dispatcher-worker demo.
|
||||
*/
|
||||
/**@{ */
|
||||
#define MQUEUE_NUMBER_OF_WORKERS ( 4 ) /**< The number of worker threads, each thread has one queue which is used as income box. */
|
||||
|
||||
#if ( MQUEUE_NUMBER_OF_WORKERS > 10 )
|
||||
#error "Please keep MQUEUE_NUMBER_OF_WORKERS < 10."
|
||||
#endif
|
||||
|
||||
#define MQUEUE_WORKER_QNAME_BASE "/qNode0" /**< Queue name base. */
|
||||
#define MQUEUE_WORKER_QNAME_BASE_LEN ( 6 ) /** Queue name base length. */
|
||||
|
||||
#define MQUEUE_TIMEOUT_SECONDS ( 1 ) /**< Relative timeout for mqueue functions. */
|
||||
#define MQUEUE_MAX_NUMBER_OF_MESSAGES_WORKER ( 1 ) /**< Maximum number of messages in a queue. */
|
||||
|
||||
#define MQUEUE_MSG_WORKER_CTRL_MSG_SIZE sizeof( uint8_t ) /**< Control message size. */
|
||||
#define DEMO_ERROR ( -1 ) /**< Any non-zero value would work. */
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Structure used by Worker thread.
|
||||
*/
|
||||
/**@{ */
|
||||
typedef struct WorkerThreadResources
|
||||
{
|
||||
pthread_t pxID; /**< thread ID. */
|
||||
mqd_t xInboxID; /**< mqueue inbox ID. */
|
||||
} WorkerThreadResources_t;
|
||||
/**@} */
|
||||
|
||||
/**
|
||||
* @brief Structure used by Dispatcher thread.
|
||||
*/
|
||||
/**@{ */
|
||||
typedef struct DispatcherThreadResources
|
||||
{
|
||||
pthread_t pxID; /**< thread ID. */
|
||||
mqd_t * pOutboxID; /**< a list of mqueue outbox ID. */
|
||||
} DispatcherThreadResources_t;
|
||||
/**@} */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void * prvWorkerThread( void * pvArgs )
|
||||
{
|
||||
WorkerThreadResources_t pArgList = *( WorkerThreadResources_t * ) pvArgs;
|
||||
|
||||
printf( "Worker thread #[%d] - start %s", ( int ) pArgList.pxID, LINE_BREAK );
|
||||
|
||||
struct timespec xReceiveTimeout = { 0 };
|
||||
|
||||
ssize_t xMessageSize = 0;
|
||||
char pcReceiveBuffer[ MQUEUE_MSG_WORKER_CTRL_MSG_SIZE ] = { 0 };
|
||||
|
||||
/* This is a worker thread that reacts based on what is sent to its inbox (mqueue). */
|
||||
while( true )
|
||||
{
|
||||
clock_gettime( CLOCK_REALTIME, &xReceiveTimeout );
|
||||
xReceiveTimeout.tv_sec += MQUEUE_TIMEOUT_SECONDS;
|
||||
|
||||
xMessageSize = mq_receive( pArgList.xInboxID,
|
||||
pcReceiveBuffer,
|
||||
MQUEUE_MSG_WORKER_CTRL_MSG_SIZE,
|
||||
0 );
|
||||
|
||||
/* Parse messages */
|
||||
if( xMessageSize == MQUEUE_MSG_WORKER_CTRL_MSG_SIZE )
|
||||
{
|
||||
switch( ( int ) pcReceiveBuffer[ 0 ] )
|
||||
{
|
||||
case eWORKER_CTRL_MSG_CONTINUE:
|
||||
/* Task branch, currently only prints message to screen. */
|
||||
/* Could perform tasks here. Could also notify dispatcher upon completion, if desired. */
|
||||
printf( "Worker thread #[%d] -- Received eWORKER_CTRL_MSG_CONTINUE %s", ( int ) pArgList.pxID, LINE_BREAK );
|
||||
break;
|
||||
|
||||
case eWORKER_CTRL_MSG_EXIT:
|
||||
printf( "Worker thread #[%d] -- Finished. Exit now. %s", ( int ) pArgList.pxID, LINE_BREAK );
|
||||
|
||||
return NULL;
|
||||
|
||||
default:
|
||||
/* Received a message that we don't care or not defined. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid message. Error handling can be done here, if desired. */
|
||||
}
|
||||
}
|
||||
|
||||
/* You should never hit here. */
|
||||
/* return NULL; */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void * prvDispatcherThread( void * pvArgs )
|
||||
{
|
||||
DispatcherThreadResources_t pArgList = *( DispatcherThreadResources_t * ) pvArgs;
|
||||
|
||||
printf( "Dispatcher thread - start %s", LINE_BREAK );
|
||||
|
||||
struct timespec xSendTimeout = { 0 };
|
||||
|
||||
ssize_t xMessageSize = 0;
|
||||
char pcSendBuffer[ MQUEUE_MSG_WORKER_CTRL_MSG_SIZE ] = { 0 };
|
||||
|
||||
/* Just for fun, let threads do a total of 100 independent tasks. */
|
||||
int i = 0;
|
||||
const int totalNumOfJobsPerThread = 100;
|
||||
|
||||
/* Distribute 1000 independent tasks to workers, in round-robin fashion. */
|
||||
pcSendBuffer[ 0 ] = ( char ) eWORKER_CTRL_MSG_CONTINUE;
|
||||
|
||||
for( i = 0; i < totalNumOfJobsPerThread; i++ )
|
||||
{
|
||||
clock_gettime( CLOCK_REALTIME, &xSendTimeout );
|
||||
xSendTimeout.tv_sec += MQUEUE_TIMEOUT_SECONDS;
|
||||
|
||||
printf( "Dispatcher iteration #[%d] -- Sending msg to worker thread #[%d]. %s", i, ( int ) pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], LINE_BREAK );
|
||||
|
||||
xMessageSize = mq_timedsend( pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ],
|
||||
pcSendBuffer,
|
||||
MQUEUE_MSG_WORKER_CTRL_MSG_SIZE,
|
||||
0,
|
||||
&xSendTimeout );
|
||||
|
||||
if( xMessageSize != 0 )
|
||||
{
|
||||
/* This error is acceptable in our setup.
|
||||
* Since inbox for each thread fits only one message.
|
||||
* In reality, balance inbox size, message arrival rate, and message drop rate. */
|
||||
printf( "An acceptable failure -- dispatcher failed to send eWORKER_CTRL_MSG_CONTINUE to outbox ID: %x. errno %d %s",
|
||||
( int ) pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], errno, LINE_BREAK );
|
||||
}
|
||||
}
|
||||
|
||||
/* Control thread is now done with distributing jobs. Tell workers they are done. */
|
||||
pcSendBuffer[ 0 ] = ( char ) eWORKER_CTRL_MSG_EXIT;
|
||||
|
||||
for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ )
|
||||
{
|
||||
printf( "Dispatcher [%d] -- Sending eWORKER_CTRL_MSG_EXIT to worker thread #[%d]. %s", i, ( int ) pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], LINE_BREAK );
|
||||
|
||||
/* This is a blocking call, to guarantee worker thread exits. */
|
||||
xMessageSize = mq_send( pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ],
|
||||
pcSendBuffer,
|
||||
MQUEUE_MSG_WORKER_CTRL_MSG_SIZE,
|
||||
0 );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Job distribution with actor model.
|
||||
*
|
||||
* See the top of this file for detailed description.
|
||||
*/
|
||||
void vStartPOSIXDemo( void )
|
||||
{
|
||||
int i = 0;
|
||||
int iStatus = 0;
|
||||
|
||||
/* Handles of the threads and related resources. */
|
||||
DispatcherThreadResources_t pxDispatcher = { 0 };
|
||||
WorkerThreadResources_t pxWorkers[ MQUEUE_NUMBER_OF_WORKERS ] = { { 0 } };
|
||||
mqd_t workerMqueues[ MQUEUE_NUMBER_OF_WORKERS ] = { 0 };
|
||||
|
||||
struct mq_attr xQueueAttributesWorker =
|
||||
{
|
||||
.mq_flags = 0,
|
||||
.mq_maxmsg = MQUEUE_MAX_NUMBER_OF_MESSAGES_WORKER,
|
||||
.mq_msgsize = MQUEUE_MSG_WORKER_CTRL_MSG_SIZE,
|
||||
.mq_curmsgs = 0
|
||||
};
|
||||
|
||||
pxDispatcher.pOutboxID = workerMqueues;
|
||||
|
||||
/* Create message queues for each worker thread. */
|
||||
for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ )
|
||||
{
|
||||
/* Prepare a unique queue name for each worker. */
|
||||
char qName[] = MQUEUE_WORKER_QNAME_BASE;
|
||||
qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] = qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] + i;
|
||||
|
||||
/* Open a queue with --
|
||||
* O_CREAT -- create a message queue.
|
||||
* O_RDWR -- both receiving and sending messages.
|
||||
*/
|
||||
pxWorkers[ i ].xInboxID = mq_open( qName,
|
||||
O_CREAT | O_RDWR,
|
||||
( mode_t ) 0,
|
||||
&xQueueAttributesWorker );
|
||||
|
||||
if( pxWorkers[ i ].xInboxID == ( mqd_t ) -1 )
|
||||
{
|
||||
printf( "Invalid inbox (mqueue) for worker. %s", LINE_BREAK );
|
||||
iStatus = DEMO_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Outboxes of dispatcher thread is the inboxes of all worker threads. */
|
||||
pxDispatcher.pOutboxID[ i ] = pxWorkers[ i ].xInboxID;
|
||||
}
|
||||
|
||||
/* Create and start Worker threads. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ )
|
||||
{
|
||||
( void ) pthread_create( &( pxWorkers[ i ].pxID ), NULL, prvWorkerThread, &pxWorkers[ i ] );
|
||||
}
|
||||
|
||||
/* Create and start dispatcher thread. */
|
||||
( void ) pthread_create( &( pxDispatcher.pxID ), NULL, prvDispatcherThread, &pxDispatcher );
|
||||
|
||||
/* Actors will do predefined tasks in threads. Current implementation is that
|
||||
* dispatcher actor notifies worker actors to terminate upon finishing distributing tasks. */
|
||||
|
||||
/* Wait for worker threads to join. */
|
||||
for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ )
|
||||
{
|
||||
( void ) pthread_join( pxWorkers[ i ].pxID, NULL );
|
||||
}
|
||||
|
||||
/* Wait for dispatcher thread to join. */
|
||||
( void ) pthread_join( pxDispatcher.pxID, NULL );
|
||||
}
|
||||
|
||||
/* Close and unlink worker message queues. */
|
||||
for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ )
|
||||
{
|
||||
char qName[] = MQUEUE_WORKER_QNAME_BASE;
|
||||
qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] = qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] + i;
|
||||
|
||||
if( pxWorkers[ i ].xInboxID != NULL )
|
||||
{
|
||||
( void ) mq_close( pxWorkers[ i ].xInboxID );
|
||||
( void ) mq_unlink( qName );
|
||||
}
|
||||
}
|
||||
|
||||
/* Have something on console. */
|
||||
if( iStatus == 0 )
|
||||
{
|
||||
printf( "All threads finished. %s", LINE_BREAK );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Queues did not get initialized properly. Did not run demo. %s", LINE_BREAK );
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef _POSIX_DEMO_H_
|
||||
#define _POSIX_DEMO_H_
|
||||
void vStartPOSIXDemo( void * pvParameters );
|
||||
|
||||
#endif /* _POSIX_DEMO_H_ */
|
@ -0,0 +1,6 @@
|
||||
Directories:
|
||||
|
||||
+ FreeRTOS-Plus\Demo\FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator
|
||||
contains a FreeRTOS windows simulator demo project for FreeRTOS+POSIX.
|
||||
See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/ for information about this project.
|
||||
|
9
FreeRTOS-Plus/Demo/readme.txt
Executable file
9
FreeRTOS-Plus/Demo/readme.txt
Executable file
@ -0,0 +1,9 @@
|
||||
Directories:
|
||||
|
||||
+ The FreeRTOS-Plus/Demo directory contains a demo application for every most of
|
||||
the FreeRTOS+ components. Lots of the demo applications use the FreeRTOS
|
||||
Windows simulator for easy evaluation. Be aware that FreeRTOS is much slower
|
||||
and not deterministic when executed in a simulated environment.
|
||||
|
||||
+ See http://www.freertos.org/plus
|
||||
|
351
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c
Executable file
351
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c
Executable file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* FreeRTOS+CLI V1.0.4
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Utils includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* If the application writer needs to place the buffer used by the CLI at a
|
||||
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
|
||||
FreeRTOSConfig.h, then declare an array with the following name and size in
|
||||
one of the application files:
|
||||
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
|
||||
*/
|
||||
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer
|
||||
#define configAPPLICATION_PROVIDES_cOutputBuffer 0
|
||||
#endif
|
||||
|
||||
typedef struct xCOMMAND_INPUT_LIST
|
||||
{
|
||||
const CLI_Command_Definition_t *pxCommandLineDefinition;
|
||||
struct xCOMMAND_INPUT_LIST *pxNext;
|
||||
} CLI_Definition_List_Item_t;
|
||||
|
||||
/*
|
||||
* The callback function that is executed when "help" is entered. This is the
|
||||
* only default command that is always present.
|
||||
*/
|
||||
static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/*
|
||||
* Return the number of parameters that follow the command name.
|
||||
*/
|
||||
static int8_t prvGetNumberOfParameters( const char *pcCommandString );
|
||||
|
||||
/* The definition of the "help" command. This command is always at the front
|
||||
of the list of registered commands. */
|
||||
static const CLI_Command_Definition_t xHelpCommand =
|
||||
{
|
||||
"help",
|
||||
"\r\nhelp:\r\n Lists all the registered commands\r\n\r\n",
|
||||
prvHelpCommand,
|
||||
0
|
||||
};
|
||||
|
||||
/* The definition of the list of commands. Commands that are registered are
|
||||
added to this list. */
|
||||
static CLI_Definition_List_Item_t xRegisteredCommands =
|
||||
{
|
||||
&xHelpCommand, /* The first command in the list is always the help command, defined in this file. */
|
||||
NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */
|
||||
};
|
||||
|
||||
/* A buffer into which command outputs can be written is declared here, rather
|
||||
than in the command console implementation, to allow multiple command consoles
|
||||
to share the same buffer. For example, an application may allow access to the
|
||||
command interpreter by UART and by Ethernet. Sharing a buffer is done purely
|
||||
to save RAM. Note, however, that the command console itself is not re-entrant,
|
||||
so only one command interpreter interface can be used at any one time. For that
|
||||
reason, no attempt at providing mutual exclusion to the cOutputBuffer array is
|
||||
attempted.
|
||||
|
||||
configAPPLICATION_PROVIDES_cOutputBuffer is provided to allow the application
|
||||
writer to provide their own cOutputBuffer declaration in cases where the
|
||||
buffer needs to be placed at a fixed address (rather than by the linker). */
|
||||
#if( configAPPLICATION_PROVIDES_cOutputBuffer == 0 )
|
||||
static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
|
||||
#else
|
||||
extern char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister )
|
||||
{
|
||||
static CLI_Definition_List_Item_t *pxLastCommandInList = &xRegisteredCommands;
|
||||
CLI_Definition_List_Item_t *pxNewListItem;
|
||||
BaseType_t xReturn = pdFAIL;
|
||||
|
||||
/* Check the parameter is not NULL. */
|
||||
configASSERT( pxCommandToRegister );
|
||||
|
||||
/* Create a new list item that will reference the command being registered. */
|
||||
pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) );
|
||||
configASSERT( pxNewListItem );
|
||||
|
||||
if( pxNewListItem != NULL )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Reference the command being registered from the newly created
|
||||
list item. */
|
||||
pxNewListItem->pxCommandLineDefinition = pxCommandToRegister;
|
||||
|
||||
/* The new list item will get added to the end of the list, so
|
||||
pxNext has nowhere to point. */
|
||||
pxNewListItem->pxNext = NULL;
|
||||
|
||||
/* Add the newly created list item to the end of the already existing
|
||||
list. */
|
||||
pxLastCommandInList->pxNext = pxNewListItem;
|
||||
|
||||
/* Set the end of list marker to the new list item. */
|
||||
pxLastCommandInList = pxNewListItem;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen )
|
||||
{
|
||||
static const CLI_Definition_List_Item_t *pxCommand = NULL;
|
||||
BaseType_t xReturn = pdTRUE;
|
||||
const char *pcRegisteredCommandString;
|
||||
size_t xCommandStringLength;
|
||||
|
||||
/* Note: This function is not re-entrant. It must not be called from more
|
||||
thank one task. */
|
||||
|
||||
if( pxCommand == NULL )
|
||||
{
|
||||
/* Search for the command string in the list of registered commands. */
|
||||
for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext )
|
||||
{
|
||||
pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand;
|
||||
xCommandStringLength = strlen( pcRegisteredCommandString );
|
||||
|
||||
/* To ensure the string lengths match exactly, so as not to pick up
|
||||
a sub-string of a longer command, check the byte after the expected
|
||||
end of the string is either the end of the string or a space before
|
||||
a parameter. */
|
||||
if( ( pcCommandInput[ xCommandStringLength ] == ' ' ) || ( pcCommandInput[ xCommandStringLength ] == 0x00 ) )
|
||||
{
|
||||
if( strncmp( pcCommandInput, pcRegisteredCommandString, xCommandStringLength ) == 0 )
|
||||
{
|
||||
/* The command has been found. Check it has the expected
|
||||
number of parameters. If cExpectedNumberOfParameters is -1,
|
||||
then there could be a variable number of parameters and no
|
||||
check is made. */
|
||||
if( pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters >= 0 )
|
||||
{
|
||||
if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) )
|
||||
{
|
||||
/* The command was found, but the number of parameters with the command
|
||||
was incorrect. */
|
||||
strncpy( pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen );
|
||||
pxCommand = NULL;
|
||||
}
|
||||
else if( pxCommand != NULL )
|
||||
{
|
||||
/* Call the callback function that is registered to this command. */
|
||||
xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput );
|
||||
|
||||
/* If xReturn is pdFALSE, then no further strings will be returned
|
||||
after this one, and pxCommand can be reset to NULL ready to search
|
||||
for the next entered command. */
|
||||
if( xReturn == pdFALSE )
|
||||
{
|
||||
pxCommand = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pxCommand was NULL, the command was not found. */
|
||||
strncpy( pcWriteBuffer, "Command not recognised. Enter 'help' to view a list of available commands.\r\n\r\n", xWriteBufferLen );
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
char *FreeRTOS_CLIGetOutputBuffer( void )
|
||||
{
|
||||
return cOutputBuffer;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength )
|
||||
{
|
||||
UBaseType_t uxParametersFound = 0;
|
||||
const char *pcReturn = NULL;
|
||||
|
||||
*pxParameterStringLength = 0;
|
||||
|
||||
while( uxParametersFound < uxWantedParameter )
|
||||
{
|
||||
/* Index the character pointer past the current word. If this is the start
|
||||
of the command string then the first word is the command itself. */
|
||||
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
|
||||
{
|
||||
pcCommandString++;
|
||||
}
|
||||
|
||||
/* Find the start of the next string. */
|
||||
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) )
|
||||
{
|
||||
pcCommandString++;
|
||||
}
|
||||
|
||||
/* Was a string found? */
|
||||
if( *pcCommandString != 0x00 )
|
||||
{
|
||||
/* Is this the start of the required parameter? */
|
||||
uxParametersFound++;
|
||||
|
||||
if( uxParametersFound == uxWantedParameter )
|
||||
{
|
||||
/* How long is the parameter? */
|
||||
pcReturn = pcCommandString;
|
||||
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
|
||||
{
|
||||
( *pxParameterStringLength )++;
|
||||
pcCommandString++;
|
||||
}
|
||||
|
||||
if( *pxParameterStringLength == 0 )
|
||||
{
|
||||
pcReturn = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pcReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
|
||||
{
|
||||
static const CLI_Definition_List_Item_t * pxCommand = NULL;
|
||||
BaseType_t xReturn;
|
||||
|
||||
( void ) pcCommandString;
|
||||
|
||||
if( pxCommand == NULL )
|
||||
{
|
||||
/* Reset the pxCommand pointer back to the start of the list. */
|
||||
pxCommand = &xRegisteredCommands;
|
||||
}
|
||||
|
||||
/* Return the next command help string, before moving the pointer on to
|
||||
the next command in the list. */
|
||||
strncpy( pcWriteBuffer, pxCommand->pxCommandLineDefinition->pcHelpString, xWriteBufferLen );
|
||||
pxCommand = pxCommand->pxNext;
|
||||
|
||||
if( pxCommand == NULL )
|
||||
{
|
||||
/* There are no more commands in the list, so there will be no more
|
||||
strings to return after this one and pdFALSE should be returned. */
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int8_t prvGetNumberOfParameters( const char *pcCommandString )
|
||||
{
|
||||
int8_t cParameters = 0;
|
||||
BaseType_t xLastCharacterWasSpace = pdFALSE;
|
||||
|
||||
/* Count the number of space delimited words in pcCommandString. */
|
||||
while( *pcCommandString != 0x00 )
|
||||
{
|
||||
if( ( *pcCommandString ) == ' ' )
|
||||
{
|
||||
if( xLastCharacterWasSpace != pdTRUE )
|
||||
{
|
||||
cParameters++;
|
||||
xLastCharacterWasSpace = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xLastCharacterWasSpace = pdFALSE;
|
||||
}
|
||||
|
||||
pcCommandString++;
|
||||
}
|
||||
|
||||
/* If the command string ended with spaces, then there will have been too
|
||||
many parameters counted. */
|
||||
if( xLastCharacterWasSpace == pdTRUE )
|
||||
{
|
||||
cParameters--;
|
||||
}
|
||||
|
||||
/* The value returned is one less than the number of space delimited words,
|
||||
as the first word should be the command itself. */
|
||||
return cParameters;
|
||||
}
|
||||
|
105
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h
Executable file
105
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h
Executable file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* FreeRTOS+CLI V1.0.4
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef COMMAND_INTERPRETER_H
|
||||
#define COMMAND_INTERPRETER_H
|
||||
|
||||
/* The prototype to which callback functions used to process command line
|
||||
commands must comply. pcWriteBuffer is a buffer into which the output from
|
||||
executing the command can be written, xWriteBufferLen is the length, in bytes of
|
||||
the pcWriteBuffer buffer, and pcCommandString is the entire string as input by
|
||||
the user (from which parameters can be extracted).*/
|
||||
typedef BaseType_t (*pdCOMMAND_LINE_CALLBACK)( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
|
||||
|
||||
/* The structure that defines command line commands. A command line command
|
||||
should be defined by declaring a const structure of this type. */
|
||||
typedef struct xCOMMAND_LINE_INPUT
|
||||
{
|
||||
const char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */
|
||||
const char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */
|
||||
const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */
|
||||
int8_t cExpectedNumberOfParameters; /* Commands expect a fixed number of parameters, which may be zero. */
|
||||
} CLI_Command_Definition_t;
|
||||
|
||||
/* For backward compatibility. */
|
||||
#define xCommandLineInput CLI_Command_Definition_t
|
||||
|
||||
/*
|
||||
* Register the command passed in using the pxCommandToRegister parameter.
|
||||
* Registering a command adds the command to the list of commands that are
|
||||
* handled by the command interpreter. Once a command has been registered it
|
||||
* can be executed from the command line.
|
||||
*/
|
||||
BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister );
|
||||
|
||||
/*
|
||||
* Runs the command interpreter for the command string "pcCommandInput". Any
|
||||
* output generated by running the command will be placed into pcWriteBuffer.
|
||||
* xWriteBufferLen must indicate the size, in bytes, of the buffer pointed to
|
||||
* by pcWriteBuffer.
|
||||
*
|
||||
* FreeRTOS_CLIProcessCommand should be called repeatedly until it returns pdFALSE.
|
||||
*
|
||||
* pcCmdIntProcessCommand is not reentrant. It must not be called from more
|
||||
* than one task - or at least - by more than one task at a time.
|
||||
*/
|
||||
BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* A buffer into which command outputs can be written is declared in the
|
||||
* main command interpreter, rather than in the command console implementation,
|
||||
* to allow application that provide access to the command console via multiple
|
||||
* interfaces to share a buffer, and therefore save RAM. Note, however, that
|
||||
* the command interpreter itself is not re-entrant, so only one command
|
||||
* console interface can be used at any one time. For that reason, no attempt
|
||||
* is made to provide any mutual exclusion mechanism on the output buffer.
|
||||
*
|
||||
* FreeRTOS_CLIGetOutputBuffer() returns the address of the output buffer.
|
||||
*/
|
||||
char *FreeRTOS_CLIGetOutputBuffer( void );
|
||||
|
||||
/*
|
||||
* Return a pointer to the xParameterNumber'th word in pcCommandString.
|
||||
*/
|
||||
const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength );
|
||||
|
||||
#endif /* COMMAND_INTERPRETER_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
32
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/History.txt
Executable file
32
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/History.txt
Executable file
@ -0,0 +1,32 @@
|
||||
Changes between V1.0.3 and V1.0.4 released
|
||||
|
||||
+ Update to use stdint and the FreeRTOS specific typedefs that were
|
||||
introduced in FreeRTOS V8.0.0.
|
||||
|
||||
Changes between V1.0.2 and V1.0.3 released
|
||||
|
||||
+ Previously, and in line with good software engineering practice, the
|
||||
FreeRTOS coding standard did not permit the use of char types that were
|
||||
not explicitly qualified as either signed or unsigned. As a result char
|
||||
pointers used to reference strings required casts, as did the use of any
|
||||
standard string handling functions. The casts ensured compiler warnings
|
||||
were not generated by compilers that defaulted unqualified char types to
|
||||
be signed or compilers that defaulted unqualified char types to be
|
||||
unsigned. As it has in later MISRA standards, this rule has now been
|
||||
relaxed, and unqualified char types are now permitted, but only when:
|
||||
1) The char is used to point to a human readable text string.
|
||||
2) The char is used to hold a single ASCII character.
|
||||
|
||||
Changes between V1.0.1 and V1.0.2 released 14/10/2013
|
||||
|
||||
+ Changed double quotes (") to single quotes (') in the help string to
|
||||
allow the strings to be used with JSON in FreeRTOS+Nabto.
|
||||
|
||||
Changes between V1.0.0 and V1.0.1 released 05/07/2012
|
||||
|
||||
+ Change the name of the structure used to map a function that implements
|
||||
a CLI command to the string used to call the command from
|
||||
xCommandLineInput to CLI_Command_Definition_t, as it was always intended
|
||||
to be. A #define was added to map the old name to the new name for
|
||||
reasons of backward compatibility.
|
||||
|
19
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt
Executable file
19
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt
Executable file
@ -0,0 +1,19 @@
|
||||
FreeRTOS+CLI is released under the following MIT license.
|
||||
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
5
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/ReadMe.url
Executable file
5
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/ReadMe.url
Executable file
@ -0,0 +1,5 @@
|
||||
[InternetShortcut]
|
||||
URL=http://www.freertos.org/cli
|
||||
IDList=
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
4
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/readme.txt
Executable file
4
FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/readme.txt
Executable file
@ -0,0 +1,4 @@
|
||||
Contains source and header files that implement FreeRTOS+CLI. See
|
||||
http://www.FreeRTOS.org/cli for documentation and license information.
|
||||
|
||||
|
5
FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/LinkToDemo.url
Executable file
5
FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/LinkToDemo.url
Executable file
@ -0,0 +1,5 @@
|
||||
[InternetShortcut]
|
||||
URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml
|
||||
IDList=
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
7
FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/readme.txt
Executable file
7
FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/readme.txt
Executable file
@ -0,0 +1,7 @@
|
||||
It is not possible to create an example FreeRTOS+IO project for the Windows
|
||||
simulator. FreeRTOS+IO information can be found on http://www.FreeRTOS.org/IO.
|
||||
|
||||
A featured demo that includes telnet like functionality, a web server,
|
||||
a command line interface (using FreeRTOS+CLI) and a FAT file system is
|
||||
described on
|
||||
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml
|
653
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
Executable file
653
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
Executable file
@ -0,0 +1,653 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
|
||||
/* When the age of an entry in the ARP table reaches this value (it counts down
|
||||
to zero, so this is an old entry) an ARP request will be sent to see if the
|
||||
entry is still valid and can therefore be refreshed. */
|
||||
#define arpMAX_ARP_AGE_BEFORE_NEW_ARP_REQUEST ( 3 )
|
||||
|
||||
/* The time between gratuitous ARPs. */
|
||||
#ifndef arpGRATUITOUS_ARP_PERIOD
|
||||
#define arpGRATUITOUS_ARP_PERIOD ( pdMS_TO_TICKS( 20000 ) )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Lookup an MAC address in the ARP cache from the IP address.
|
||||
*/
|
||||
static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup, MACAddress_t * const pxMACAddress );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ARP cache. */
|
||||
static ARPCacheRow_t xARPCache[ ipconfigARP_CACHE_ENTRIES ];
|
||||
|
||||
/* The time at which the last gratuitous ARP was sent. Gratuitous ARPs are used
|
||||
to ensure ARP tables are up to date and to detect IP address conflicts. */
|
||||
static TickType_t xLastGratuitousARPTime = ( TickType_t ) 0;
|
||||
|
||||
/*
|
||||
* IP-clash detection is currently only used internally. When DHCP doesn't respond, the
|
||||
* driver can try out a random LinkLayer IP address (169.254.x.x). It will send out a
|
||||
* gratuitos ARP message and, after a period of time, check the variables here below:
|
||||
*/
|
||||
#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
||||
/* Becomes non-zero if another device responded to a gratuitos ARP message. */
|
||||
BaseType_t xARPHadIPClash;
|
||||
/* MAC-address of the other device containing the same IP-address. */
|
||||
MACAddress_t xARPClashMacAddress;
|
||||
#endif /* ipconfigARP_USE_CLASH_DETECTION */
|
||||
|
||||
/* Part of the Ethernet and ARP headers are always constant when sending an IPv4
|
||||
ARP packet. This array defines the constant parts, allowing this part of the
|
||||
packet to be filled in using a simple memcpy() instead of individual writes. */
|
||||
static const uint8_t xDefaultPartARPPacketHeader[] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Ethernet destination address. */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Ethernet source address. */
|
||||
0x08, 0x06, /* Ethernet frame type (ipARP_FRAME_TYPE). */
|
||||
0x00, 0x01, /* usHardwareType (ipARP_HARDWARE_TYPE_ETHERNET). */
|
||||
0x08, 0x00, /* usProtocolType. */
|
||||
ipMAC_ADDRESS_LENGTH_BYTES, /* ucHardwareAddressLength. */
|
||||
ipIP_ADDRESS_LENGTH_BYTES, /* ucProtocolAddressLength. */
|
||||
0x00, 0x01, /* usOperation (ipARP_REQUEST). */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* xSenderHardwareAddress. */
|
||||
0x00, 0x00, 0x00, 0x00, /* ulSenderProtocolAddress. */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* xTargetHardwareAddress. */
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
||||
{
|
||||
eFrameProcessingResult_t eReturn = eReleaseBuffer;
|
||||
ARPHeader_t *pxARPHeader;
|
||||
uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress;
|
||||
|
||||
pxARPHeader = &( pxARPFrame->xARPHeader );
|
||||
|
||||
/* The field ulSenderProtocolAddress is badly aligned, copy byte-by-byte. */
|
||||
memcpy( ( void *)&( ulSenderProtocolAddress ), ( void * )pxARPHeader->ucSenderProtocolAddress, sizeof( ulSenderProtocolAddress ) );
|
||||
/* The field ulTargetProtocolAddress is well-aligned, a 32-bits copy. */
|
||||
ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress;
|
||||
|
||||
traceARP_PACKET_RECEIVED();
|
||||
|
||||
/* Don't do anything if the local IP address is zero because
|
||||
that means a DHCP request has not completed. */
|
||||
if( *ipLOCAL_IP_ADDRESS_POINTER != 0UL )
|
||||
{
|
||||
switch( pxARPHeader->usOperation )
|
||||
{
|
||||
case ipARP_REQUEST :
|
||||
/* The packet contained an ARP request. Was it for the IP
|
||||
address of the node running this code? */
|
||||
if( ulTargetProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER )
|
||||
{
|
||||
iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress );
|
||||
|
||||
/* The request is for the address of this node. Add the
|
||||
entry into the ARP cache, or refresh the entry if it
|
||||
already exists. */
|
||||
vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
|
||||
|
||||
/* Generate a reply payload in the same buffer. */
|
||||
pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY;
|
||||
if( ulTargetProtocolAddress == ulSenderProtocolAddress )
|
||||
{
|
||||
/* A double IP address is detected! */
|
||||
/* Give the sources MAC address the value of the broadcast address, will be swapped later */
|
||||
memcpy( pxARPFrame->xEthernetHeader.xSourceAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( xBroadcastMACAddress ) );
|
||||
memset( pxARPHeader->xTargetHardwareAddress.ucBytes, '\0', sizeof( MACAddress_t ) );
|
||||
pxARPHeader->ulTargetProtocolAddress = 0UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( pxARPHeader->xTargetHardwareAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( MACAddress_t ) );
|
||||
pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress;
|
||||
}
|
||||
memcpy( pxARPHeader->xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
|
||||
memcpy( ( void* )pxARPHeader->ucSenderProtocolAddress, ( void* )ipLOCAL_IP_ADDRESS_POINTER, sizeof( pxARPHeader->ucSenderProtocolAddress ) );
|
||||
|
||||
eReturn = eReturnEthernetFrame;
|
||||
}
|
||||
break;
|
||||
|
||||
case ipARP_REPLY :
|
||||
iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress );
|
||||
vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
|
||||
/* Process received ARP frame to see if there is a clash. */
|
||||
#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
||||
{
|
||||
if( ulSenderProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER )
|
||||
{
|
||||
xARPHadIPClash = pdTRUE;
|
||||
memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) );
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigARP_USE_CLASH_DETECTION */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Invalid. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
|
||||
|
||||
uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress )
|
||||
{
|
||||
BaseType_t x;
|
||||
uint32_t lResult = 0;
|
||||
|
||||
/* For each entry in the ARP cache table. */
|
||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
if( ( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 ) )
|
||||
{
|
||||
lResult = xARPCache[ x ].ulIPAddress;
|
||||
memset( &xARPCache[ x ], '\0', sizeof( xARPCache[ x ] ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
#endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress )
|
||||
{
|
||||
BaseType_t x = 0;
|
||||
BaseType_t xIpEntry = -1;
|
||||
BaseType_t xMacEntry = -1;
|
||||
BaseType_t xUseEntry = 0;
|
||||
uint8_t ucMinAgeFound = 0U;
|
||||
|
||||
#if( ipconfigARP_STORES_REMOTE_ADDRESSES == 0 )
|
||||
/* Only process the IP address if it is on the local network.
|
||||
Unless: when '*ipLOCAL_IP_ADDRESS_POINTER' equals zero, the IP-address
|
||||
and netmask are still unknown. */
|
||||
if( ( ( ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) ) ||
|
||||
( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ) )
|
||||
#else
|
||||
/* If ipconfigARP_STORES_REMOTE_ADDRESSES is non-zero, IP addresses with
|
||||
a different netmask will also be stored. After when replying to a UDP
|
||||
message from a different netmask, the IP address can be looped up and a
|
||||
reply sent. This option is useful for systems with multiple gateways,
|
||||
the reply will surely arrive. If ipconfigARP_STORES_REMOTE_ADDRESSES is
|
||||
zero the the gateway address is the only option. */
|
||||
if( pdTRUE )
|
||||
#endif
|
||||
{
|
||||
/* Start with the maximum possible number. */
|
||||
ucMinAgeFound--;
|
||||
|
||||
/* For each entry in the ARP cache table. */
|
||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
/* Does this line in the cache table hold an entry for the IP
|
||||
address being queried? */
|
||||
if( xARPCache[ x ].ulIPAddress == ulIPAddress )
|
||||
{
|
||||
if( pxMACAddress == NULL )
|
||||
{
|
||||
/* In case the parameter pxMACAddress is NULL, an entry will be reserved to
|
||||
indicate that there is an outstanding ARP request, This entry will have
|
||||
"ucValid == pdFALSE". */
|
||||
xIpEntry = x;
|
||||
break;
|
||||
}
|
||||
|
||||
/* See if the MAC-address also matches. */
|
||||
if( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 )
|
||||
{
|
||||
/* This function will be called for each received packet
|
||||
As this is by far the most common path the coding standard
|
||||
is relaxed in this case and a return is permitted as an
|
||||
optimisation. */
|
||||
xARPCache[ x ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
|
||||
xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Found an entry containing ulIPAddress, but the MAC address
|
||||
doesn't match. Might be an entry with ucValid=pdFALSE, waiting
|
||||
for an ARP reply. Still want to see if there is match with the
|
||||
given MAC address.ucBytes. If found, either of the two entries
|
||||
must be cleared. */
|
||||
xIpEntry = x;
|
||||
}
|
||||
else if( ( pxMACAddress != NULL ) && ( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 ) )
|
||||
{
|
||||
/* Found an entry with the given MAC-address, but the IP-address
|
||||
is different. Continue looping to find a possible match with
|
||||
ulIPAddress. */
|
||||
#if( ipconfigARP_STORES_REMOTE_ADDRESSES != 0 )
|
||||
/* If ARP stores the MAC address of IP addresses outside the
|
||||
network, than the MAC address of the gateway should not be
|
||||
overwritten. */
|
||||
BaseType_t bIsLocal[ 2 ];
|
||||
bIsLocal[ 0 ] = ( ( xARPCache[ x ].ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) );
|
||||
bIsLocal[ 1 ] = ( ( ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) );
|
||||
if( bIsLocal[ 0 ] == bIsLocal[ 1 ] )
|
||||
{
|
||||
xMacEntry = x;
|
||||
}
|
||||
#else
|
||||
xMacEntry = x;
|
||||
#endif
|
||||
}
|
||||
/* _HT_
|
||||
Shouldn't we test for xARPCache[ x ].ucValid == pdFALSE here ? */
|
||||
else if( xARPCache[ x ].ucAge < ucMinAgeFound )
|
||||
{
|
||||
/* As the table is traversed, remember the table row that
|
||||
contains the oldest entry (the lowest age count, as ages are
|
||||
decremented to zero) so the row can be re-used if this function
|
||||
needs to add an entry that does not already exist. */
|
||||
ucMinAgeFound = xARPCache[ x ].ucAge;
|
||||
xUseEntry = x;
|
||||
}
|
||||
}
|
||||
|
||||
if( xMacEntry >= 0 )
|
||||
{
|
||||
xUseEntry = xMacEntry;
|
||||
|
||||
if( xIpEntry >= 0 )
|
||||
{
|
||||
/* Both the MAC address as well as the IP address were found in
|
||||
different locations: clear the entry which matches the
|
||||
IP-address */
|
||||
memset( &xARPCache[ xIpEntry ], '\0', sizeof( xARPCache[ xIpEntry ] ) );
|
||||
}
|
||||
}
|
||||
else if( xIpEntry >= 0 )
|
||||
{
|
||||
/* An entry containing the IP-address was found, but it had a different MAC address */
|
||||
xUseEntry = xIpEntry;
|
||||
}
|
||||
|
||||
/* If the entry was not found, we use the oldest entry and set the IPaddress */
|
||||
xARPCache[ xUseEntry ].ulIPAddress = ulIPAddress;
|
||||
|
||||
if( pxMACAddress != NULL )
|
||||
{
|
||||
memcpy( xARPCache[ xUseEntry ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) );
|
||||
|
||||
iptraceARP_TABLE_ENTRY_CREATED( ulIPAddress, (*pxMACAddress) );
|
||||
/* And this entry does not need immediate attention */
|
||||
xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
|
||||
xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdTRUE;
|
||||
}
|
||||
else if( xIpEntry < 0 )
|
||||
{
|
||||
xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_RETRANSMISSIONS;
|
||||
xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdFALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigUSE_ARP_REVERSED_LOOKUP == 1 )
|
||||
eARPLookupResult_t eARPGetCacheEntryByMac( MACAddress_t * const pxMACAddress, uint32_t *pulIPAddress )
|
||||
{
|
||||
BaseType_t x;
|
||||
eARPLookupResult_t eReturn = eARPCacheMiss;
|
||||
|
||||
/* Loop through each entry in the ARP cache. */
|
||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
/* Does this row in the ARP cache table hold an entry for the MAC
|
||||
address being searched? */
|
||||
if( memcmp( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
|
||||
{
|
||||
*pulIPAddress = xARPCache[ x ].ulIPAddress;
|
||||
eReturn = eARPCacheHit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif /* ipconfigUSE_ARP_REVERSED_LOOKUP */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
eARPLookupResult_t eARPGetCacheEntry( uint32_t *pulIPAddress, MACAddress_t * const pxMACAddress )
|
||||
{
|
||||
eARPLookupResult_t eReturn;
|
||||
uint32_t ulAddressToLookup;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
if( *pulIPAddress == ipLLMNR_IP_ADDR ) /* Is in network byte order. */
|
||||
{
|
||||
/* The LLMNR IP-address has a fixed virtual MAC address. */
|
||||
memcpy( pxMACAddress->ucBytes, xLLMNR_MacAdress.ucBytes, sizeof( MACAddress_t ) );
|
||||
eReturn = eARPCacheHit;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( ( *pulIPAddress == ipBROADCAST_IP_ADDRESS ) || /* Is it the general broadcast address 255.255.255.255? */
|
||||
( *pulIPAddress == xNetworkAddressing.ulBroadcastAddress ) )/* Or a local broadcast address, eg 192.168.1.255? */
|
||||
{
|
||||
/* This is a broadcast so uses the broadcast MAC address. */
|
||||
memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );
|
||||
eReturn = eARPCacheHit;
|
||||
}
|
||||
else if( *ipLOCAL_IP_ADDRESS_POINTER == 0UL )
|
||||
{
|
||||
/* The IP address has not yet been assigned, so there is nothing that
|
||||
can be done. */
|
||||
eReturn = eCantSendPacket;
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturn = eARPCacheMiss;
|
||||
|
||||
if( ( *pulIPAddress & xNetworkAddressing.ulNetMask ) != ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) )
|
||||
{
|
||||
#if( ipconfigARP_STORES_REMOTE_ADDRESSES == 1 )
|
||||
eReturn = prvCacheLookup( *pulIPAddress, pxMACAddress );
|
||||
|
||||
if( eReturn == eARPCacheHit )
|
||||
{
|
||||
/* The stack is configured to store 'remote IP addresses', i.e. addresses
|
||||
belonging to a different the netmask. prvCacheLookup() returned a hit, so
|
||||
the MAC address is known */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* The IP address is off the local network, so look up the
|
||||
hardware address of the router, if any. */
|
||||
if( xNetworkAddressing.ulGatewayAddress != ( uint32_t )0u )
|
||||
{
|
||||
ulAddressToLookup = xNetworkAddressing.ulGatewayAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulAddressToLookup = *pulIPAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The IP address is on the local network, so lookup the requested
|
||||
IP address directly. */
|
||||
ulAddressToLookup = *pulIPAddress;
|
||||
}
|
||||
|
||||
if( eReturn == eARPCacheMiss )
|
||||
{
|
||||
if( ulAddressToLookup == 0UL )
|
||||
{
|
||||
/* The address is not on the local network, and there is not a
|
||||
router. */
|
||||
eReturn = eCantSendPacket;
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturn = prvCacheLookup( ulAddressToLookup, pxMACAddress );
|
||||
|
||||
if( eReturn == eARPCacheMiss )
|
||||
{
|
||||
/* It might be that the ARP has to go to the gateway. */
|
||||
*pulIPAddress = ulAddressToLookup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup, MACAddress_t * const pxMACAddress )
|
||||
{
|
||||
BaseType_t x;
|
||||
eARPLookupResult_t eReturn = eARPCacheMiss;
|
||||
|
||||
/* Loop through each entry in the ARP cache. */
|
||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
/* Does this row in the ARP cache table hold an entry for the IP address
|
||||
being queried? */
|
||||
if( xARPCache[ x ].ulIPAddress == ulAddressToLookup )
|
||||
{
|
||||
/* A matching valid entry was found. */
|
||||
if( xARPCache[ x ].ucValid == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
/* This entry is waiting an ARP reply, so is not valid. */
|
||||
eReturn = eCantSendPacket;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A valid entry was found. */
|
||||
memcpy( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
|
||||
eReturn = eARPCacheHit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vARPAgeCache( void )
|
||||
{
|
||||
BaseType_t x;
|
||||
TickType_t xTimeNow;
|
||||
|
||||
/* Loop through each entry in the ARP cache. */
|
||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
/* If the entry is valid (its age is greater than zero). */
|
||||
if( xARPCache[ x ].ucAge > 0U )
|
||||
{
|
||||
/* Decrement the age value of the entry in this ARP cache table row.
|
||||
When the age reaches zero it is no longer considered valid. */
|
||||
( xARPCache[ x ].ucAge )--;
|
||||
|
||||
/* If the entry is not yet valid, then it is waiting an ARP
|
||||
reply, and the ARP request should be retransmitted. */
|
||||
if( xARPCache[ x ].ucValid == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
FreeRTOS_OutputARPRequest( xARPCache[ x ].ulIPAddress );
|
||||
}
|
||||
else if( xARPCache[ x ].ucAge <= ( uint8_t ) arpMAX_ARP_AGE_BEFORE_NEW_ARP_REQUEST )
|
||||
{
|
||||
/* This entry will get removed soon. See if the MAC address is
|
||||
still valid to prevent this happening. */
|
||||
iptraceARP_TABLE_ENTRY_WILL_EXPIRE( xARPCache[ x ].ulIPAddress );
|
||||
FreeRTOS_OutputARPRequest( xARPCache[ x ].ulIPAddress );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The age has just ticked down, with nothing to do. */
|
||||
}
|
||||
|
||||
if( xARPCache[ x ].ucAge == 0u )
|
||||
{
|
||||
/* The entry is no longer valid. Wipe it out. */
|
||||
iptraceARP_TABLE_ENTRY_EXPIRED( xARPCache[ x ].ulIPAddress );
|
||||
xARPCache[ x ].ulIPAddress = 0UL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xTimeNow = xTaskGetTickCount ();
|
||||
|
||||
if( ( xLastGratuitousARPTime == ( TickType_t ) 0 ) || ( ( xTimeNow - xLastGratuitousARPTime ) > ( TickType_t ) arpGRATUITOUS_ARP_PERIOD ) )
|
||||
{
|
||||
FreeRTOS_OutputARPRequest( *ipLOCAL_IP_ADDRESS_POINTER );
|
||||
xLastGratuitousARPTime = xTimeNow;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vARPSendGratuitous( void )
|
||||
{
|
||||
/* Setting xLastGratuitousARPTime to 0 will force a gratuitous ARP the next
|
||||
time vARPAgeCache() is called. */
|
||||
xLastGratuitousARPTime = ( TickType_t ) 0;
|
||||
|
||||
/* Let the IP-task call vARPAgeCache(). */
|
||||
xSendEventToIPTask( eARPTimerEvent );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress )
|
||||
{
|
||||
NetworkBufferDescriptor_t *pxNetworkBuffer;
|
||||
|
||||
/* This is called from the context of the IP event task, so a block time
|
||||
must not be used. */
|
||||
pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( ARPPacket_t ), ( TickType_t ) 0 );
|
||||
|
||||
if( pxNetworkBuffer != NULL )
|
||||
{
|
||||
pxNetworkBuffer->ulIPAddress = ulIPAddress;
|
||||
vARPGenerateRequestPacket( pxNetworkBuffer );
|
||||
|
||||
#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
||||
{
|
||||
if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
|
||||
for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
|
||||
{
|
||||
pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
|
||||
}
|
||||
pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
|
||||
}
|
||||
}
|
||||
|
||||
void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
|
||||
{
|
||||
ARPPacket_t *pxARPPacket;
|
||||
|
||||
pxARPPacket = ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
||||
|
||||
/* memcpy the const part of the header information into the correct
|
||||
location in the packet. This copies:
|
||||
xEthernetHeader.ulDestinationAddress
|
||||
xEthernetHeader.usFrameType;
|
||||
xARPHeader.usHardwareType;
|
||||
xARPHeader.usProtocolType;
|
||||
xARPHeader.ucHardwareAddressLength;
|
||||
xARPHeader.ucProtocolAddressLength;
|
||||
xARPHeader.usOperation;
|
||||
xARPHeader.xTargetHardwareAddress;
|
||||
*/
|
||||
memcpy( ( void * ) pxARPPacket, ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
|
||||
memcpy( ( void * ) pxARPPacket->xEthernetHeader.xSourceAddress.ucBytes , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
memcpy( ( void * ) pxARPPacket->xARPHeader.xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
|
||||
|
||||
memcpy( ( void* )pxARPPacket->xARPHeader.ucSenderProtocolAddress, ( void* )ipLOCAL_IP_ADDRESS_POINTER, sizeof( pxARPPacket->xARPHeader.ucSenderProtocolAddress ) );
|
||||
pxARPPacket->xARPHeader.ulTargetProtocolAddress = pxNetworkBuffer->ulIPAddress;
|
||||
|
||||
pxNetworkBuffer->xDataLength = sizeof( ARPPacket_t );
|
||||
|
||||
iptraceCREATING_ARP_REQUEST( pxNetworkBuffer->ulIPAddress );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FreeRTOS_ClearARP( void )
|
||||
{
|
||||
memset( xARPCache, '\0', sizeof( xARPCache ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigHAS_PRINTF != 0 ) || ( ipconfigHAS_DEBUG_PRINTF != 0 )
|
||||
|
||||
void FreeRTOS_PrintARPCache( void )
|
||||
{
|
||||
BaseType_t x, xCount = 0;
|
||||
|
||||
/* Loop through each entry in the ARP cache. */
|
||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
if( ( xARPCache[ x ].ulIPAddress != 0ul ) && ( xARPCache[ x ].ucAge > 0U ) )
|
||||
{
|
||||
/* See if the MAC-address also matches, and we're all happy */
|
||||
FreeRTOS_printf( ( "Arp %2ld: %3u - %16lxip : %02x:%02x:%02x : %02x:%02x:%02x\n",
|
||||
x,
|
||||
xARPCache[ x ].ucAge,
|
||||
xARPCache[ x ].ulIPAddress,
|
||||
xARPCache[ x ].xMACAddress.ucBytes[0],
|
||||
xARPCache[ x ].xMACAddress.ucBytes[1],
|
||||
xARPCache[ x ].xMACAddress.ucBytes[2],
|
||||
xARPCache[ x ].xMACAddress.ucBytes[3],
|
||||
xARPCache[ x ].xMACAddress.ucBytes[4],
|
||||
xARPCache[ x ].xMACAddress.ucBytes[5] ) );
|
||||
xCount++;
|
||||
}
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "Arp has %ld entries\n", xCount ) );
|
||||
}
|
||||
|
||||
#endif /* ( ipconfigHAS_PRINTF != 0 ) || ( ipconfigHAS_DEBUG_PRINTF != 0 ) */
|
1011
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
Executable file
1011
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
Executable file
File diff suppressed because it is too large
Load Diff
1424
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
Executable file
1424
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
Executable file
File diff suppressed because it is too large
Load Diff
2313
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
Executable file
2313
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
Executable file
File diff suppressed because it is too large
Load Diff
3632
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
Executable file
3632
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
Executable file
File diff suppressed because it is too large
Load Diff
199
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
Executable file
199
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
Executable file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
/*
|
||||
* uxStreamBufferAdd( )
|
||||
* Adds data to a stream buffer. If uxOffset > 0, data will be written at
|
||||
* an offset from uxHead while uxHead will not be moved yet. This possibility
|
||||
* will be used when TCP data is received while earlier data is still missing.
|
||||
* If 'pucData' equals NULL, the function is called to advance 'uxHead' only.
|
||||
*/
|
||||
size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount )
|
||||
{
|
||||
size_t uxSpace, uxNextHead, uxFirst;
|
||||
|
||||
uxSpace = uxStreamBufferGetSpace( pxBuffer );
|
||||
|
||||
/* If uxOffset > 0, items can be placed in front of uxHead */
|
||||
if( uxSpace > uxOffset )
|
||||
{
|
||||
uxSpace -= uxOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxSpace = 0u;
|
||||
}
|
||||
|
||||
/* The number of bytes that can be written is the minimum of the number of
|
||||
bytes requested and the number available. */
|
||||
uxCount = FreeRTOS_min_uint32( uxSpace, uxCount );
|
||||
|
||||
if( uxCount != 0u )
|
||||
{
|
||||
uxNextHead = pxBuffer->uxHead;
|
||||
|
||||
if( uxOffset != 0u )
|
||||
{
|
||||
/* ( uxOffset > 0 ) means: write in front if the uxHead marker */
|
||||
uxNextHead += uxOffset;
|
||||
if( uxNextHead >= pxBuffer->LENGTH )
|
||||
{
|
||||
uxNextHead -= pxBuffer->LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
if( pucData != NULL )
|
||||
{
|
||||
/* Calculate the number of bytes that can be added in the first
|
||||
write - which may be less than the total number of bytes that need
|
||||
to be added if the buffer will wrap back to the beginning. */
|
||||
uxFirst = FreeRTOS_min_uint32( pxBuffer->LENGTH - uxNextHead, uxCount );
|
||||
|
||||
/* Write as many bytes as can be written in the first write. */
|
||||
memcpy( ( void* ) ( pxBuffer->ucArray + uxNextHead ), pucData, uxFirst );
|
||||
|
||||
/* If the number of bytes written was less than the number that
|
||||
could be written in the first write... */
|
||||
if( uxCount > uxFirst )
|
||||
{
|
||||
/* ...then write the remaining bytes to the start of the
|
||||
buffer. */
|
||||
memcpy( ( void * )pxBuffer->ucArray, pucData + uxFirst, uxCount - uxFirst );
|
||||
}
|
||||
}
|
||||
|
||||
if( uxOffset == 0u )
|
||||
{
|
||||
/* ( uxOffset == 0 ) means: write at uxHead position */
|
||||
uxNextHead += uxCount;
|
||||
if( uxNextHead >= pxBuffer->LENGTH )
|
||||
{
|
||||
uxNextHead -= pxBuffer->LENGTH;
|
||||
}
|
||||
pxBuffer->uxHead = uxNextHead;
|
||||
}
|
||||
|
||||
if( xStreamBufferLessThenEqual( pxBuffer, pxBuffer->uxFront, uxNextHead ) != pdFALSE )
|
||||
{
|
||||
/* Advance the front pointer */
|
||||
pxBuffer->uxFront = uxNextHead;
|
||||
}
|
||||
}
|
||||
|
||||
return uxCount;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* uxStreamBufferGet( )
|
||||
* 'uxOffset' can be used to read data located at a certain offset from 'lTail'.
|
||||
* If 'pucData' equals NULL, the function is called to advance 'lTail' only.
|
||||
* if 'xPeek' is pdTRUE, or if 'uxOffset' is non-zero, the 'lTail' pointer will
|
||||
* not be advanced.
|
||||
*/
|
||||
size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek )
|
||||
{
|
||||
size_t uxSize, uxCount, uxFirst, uxNextTail;
|
||||
|
||||
/* How much data is available? */
|
||||
uxSize = uxStreamBufferGetSize( pxBuffer );
|
||||
|
||||
if( uxSize > uxOffset )
|
||||
{
|
||||
uxSize -= uxOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxSize = 0u;
|
||||
}
|
||||
|
||||
/* Use the minimum of the wanted bytes and the available bytes. */
|
||||
uxCount = FreeRTOS_min_uint32( uxSize, uxMaxCount );
|
||||
|
||||
if( uxCount > 0u )
|
||||
{
|
||||
uxNextTail = pxBuffer->uxTail;
|
||||
|
||||
if( uxOffset != 0u )
|
||||
{
|
||||
uxNextTail += uxOffset;
|
||||
if( uxNextTail >= pxBuffer->LENGTH )
|
||||
{
|
||||
uxNextTail -= pxBuffer->LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
if( pucData != NULL )
|
||||
{
|
||||
/* Calculate the number of bytes that can be read - which may be
|
||||
less than the number wanted if the data wraps around to the start of
|
||||
the buffer. */
|
||||
uxFirst = FreeRTOS_min_uint32( pxBuffer->LENGTH - uxNextTail, uxCount );
|
||||
|
||||
/* Obtain the number of bytes it is possible to obtain in the first
|
||||
read. */
|
||||
memcpy( pucData, pxBuffer->ucArray + uxNextTail, uxFirst );
|
||||
|
||||
/* If the total number of wanted bytes is greater than the number
|
||||
that could be read in the first read... */
|
||||
if( uxCount > uxFirst )
|
||||
{
|
||||
/*...then read the remaining bytes from the start of the buffer. */
|
||||
memcpy( pucData + uxFirst, pxBuffer->ucArray, uxCount - uxFirst );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( xPeek == pdFALSE ) && ( uxOffset == 0UL ) )
|
||||
{
|
||||
/* Move the tail pointer to effecively remove the data read from
|
||||
the buffer. */
|
||||
uxNextTail += uxCount;
|
||||
|
||||
if( uxNextTail >= pxBuffer->LENGTH )
|
||||
{
|
||||
uxNextTail -= pxBuffer->LENGTH;
|
||||
}
|
||||
|
||||
pxBuffer->uxTail = uxNextTail;
|
||||
}
|
||||
}
|
||||
|
||||
return uxCount;
|
||||
}
|
||||
|
3309
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
Executable file
3309
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
Executable file
File diff suppressed because it is too large
Load Diff
1981
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
Executable file
1981
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
Executable file
File diff suppressed because it is too large
Load Diff
378
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
Executable file
378
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
Executable file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
#if( ipconfigUSE_DNS == 1 )
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#endif
|
||||
|
||||
/* The expected IP version and header length coded into the IP header itself. */
|
||||
#define ipIP_VERSION_AND_HEADER_LENGTH_BYTE ( ( uint8_t ) 0x45 )
|
||||
|
||||
/* Part of the Ethernet and IP headers are always constant when sending an IPv4
|
||||
UDP packet. This array defines the constant parts, allowing this part of the
|
||||
packet to be filled in using a simple memcpy() instead of individual writes. */
|
||||
UDPPacketHeader_t xDefaultPartUDPPacketHeader =
|
||||
{
|
||||
/* .ucBytes : */
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Ethernet source MAC address. */
|
||||
0x08, 0x00, /* Ethernet frame type. */
|
||||
ipIP_VERSION_AND_HEADER_LENGTH_BYTE, /* ucVersionHeaderLength. */
|
||||
0x00, /* ucDifferentiatedServicesCode. */
|
||||
0x00, 0x00, /* usLength. */
|
||||
0x00, 0x00, /* usIdentification. */
|
||||
0x00, 0x00, /* usFragmentOffset. */
|
||||
ipconfigUDP_TIME_TO_LIVE, /* ucTimeToLive */
|
||||
ipPROTOCOL_UDP, /* ucProtocol. */
|
||||
0x00, 0x00, /* usHeaderChecksum. */
|
||||
0x00, 0x00, 0x00, 0x00 /* Source IP address. */
|
||||
}
|
||||
};
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
|
||||
{
|
||||
UDPPacket_t *pxUDPPacket;
|
||||
IPHeader_t *pxIPHeader;
|
||||
eARPLookupResult_t eReturned;
|
||||
uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
|
||||
/* Map the UDP packet onto the start of the frame. */
|
||||
pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
||||
|
||||
/* Determine the ARP cache status for the requested IP address. */
|
||||
eReturned = eARPGetCacheEntry( &( ulIPAddress ), &( pxUDPPacket->xEthernetHeader.xDestinationAddress ) );
|
||||
|
||||
if( eReturned != eCantSendPacket )
|
||||
{
|
||||
if( eReturned == eARPCacheHit )
|
||||
{
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||
uint8_t ucSocketOptions;
|
||||
#endif
|
||||
iptraceSENDING_UDP_PACKET( pxNetworkBuffer->ulIPAddress );
|
||||
|
||||
/* Create short cuts to the data within the packet. */
|
||||
pxIPHeader = &( pxUDPPacket->xIPHeader );
|
||||
|
||||
#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
|
||||
/* Is it possible that the packet is not actually a UDP packet
|
||||
after all, but an ICMP packet. */
|
||||
if( pxNetworkBuffer->usPort != ipPACKET_CONTAINS_ICMP_DATA )
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
{
|
||||
UDPHeader_t *pxUDPHeader;
|
||||
|
||||
pxUDPHeader = &( pxUDPPacket->xUDPHeader );
|
||||
|
||||
pxUDPHeader->usDestinationPort = pxNetworkBuffer->usPort;
|
||||
pxUDPHeader->usSourcePort = pxNetworkBuffer->usBoundPort;
|
||||
pxUDPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) );
|
||||
pxUDPHeader->usLength = FreeRTOS_htons( pxUDPHeader->usLength );
|
||||
pxUDPHeader->usChecksum = 0u;
|
||||
}
|
||||
|
||||
/* memcpy() the constant parts of the header information into
|
||||
the correct location within the packet. This fills in:
|
||||
xEthernetHeader.xSourceAddress
|
||||
xEthernetHeader.usFrameType
|
||||
xIPHeader.ucVersionHeaderLength
|
||||
xIPHeader.ucDifferentiatedServicesCode
|
||||
xIPHeader.usLength
|
||||
xIPHeader.usIdentification
|
||||
xIPHeader.usFragmentOffset
|
||||
xIPHeader.ucTimeToLive
|
||||
xIPHeader.ucProtocol
|
||||
and
|
||||
xIPHeader.usHeaderChecksum
|
||||
*/
|
||||
/* Save options now, as they will be overwritten by memcpy */
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||
ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];
|
||||
#endif
|
||||
/*
|
||||
* Offset the memcpy by the size of a MAC address to start at the packet's
|
||||
* Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.
|
||||
*/
|
||||
char *pxUdpSrcAddrOffset = ( char *) pxUDPPacket + sizeof( MACAddress_t );
|
||||
memcpy( pxUdpSrcAddrOffset, xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
|
||||
|
||||
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
|
||||
if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
|
||||
{
|
||||
pxIPHeader->ucProtocol = ipPROTOCOL_ICMP;
|
||||
pxIPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( IPHeader_t ) );
|
||||
}
|
||||
else
|
||||
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
|
||||
{
|
||||
pxIPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );
|
||||
}
|
||||
|
||||
/* The total transmit size adds on the Ethernet header. */
|
||||
pxNetworkBuffer->xDataLength = pxIPHeader->usLength + sizeof( EthernetHeader_t );
|
||||
pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
|
||||
/* HT:endian: changed back to network endian */
|
||||
pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
{
|
||||
/* LLMNR messages are typically used on a LAN and they're
|
||||
* not supposed to cross routers */
|
||||
if( pxNetworkBuffer->ulIPAddress == ipLLMNR_IP_ADDR )
|
||||
{
|
||||
pxIPHeader->ucTimeToLive = 0x01;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||
{
|
||||
pxIPHeader->usHeaderChecksum = 0u;
|
||||
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
|
||||
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
|
||||
|
||||
if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0u )
|
||||
{
|
||||
usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
pxUDPPacket->xUDPHeader.usChecksum = 0u;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if( eReturned == eARPCacheMiss )
|
||||
{
|
||||
/* Add an entry to the ARP table with a null hardware address.
|
||||
This allows the ARP timer to know that an ARP reply is
|
||||
outstanding, and perform retransmissions if necessary. */
|
||||
vARPRefreshCacheEntry( NULL, ulIPAddress );
|
||||
|
||||
/* Generate an ARP for the required IP address. */
|
||||
iptracePACKET_DROPPED_TO_GENERATE_ARP( pxNetworkBuffer->ulIPAddress );
|
||||
pxNetworkBuffer->ulIPAddress = ulIPAddress;
|
||||
vARPGenerateRequestPacket( pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The lookup indicated that an ARP request has already been
|
||||
sent out for the queried IP address. */
|
||||
eReturned = eCantSendPacket;
|
||||
}
|
||||
}
|
||||
|
||||
if( eReturned != eCantSendPacket )
|
||||
{
|
||||
/* The network driver is responsible for freeing the network buffer
|
||||
after the packet has been sent. */
|
||||
|
||||
#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
||||
{
|
||||
if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
||||
{
|
||||
BaseType_t xIndex;
|
||||
|
||||
for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
|
||||
{
|
||||
pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
|
||||
}
|
||||
pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The packet can't be sent (DHCP not completed?). Just drop the
|
||||
packet. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort )
|
||||
{
|
||||
BaseType_t xReturn = pdPASS;
|
||||
FreeRTOS_Socket_t *pxSocket;
|
||||
|
||||
UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
|
||||
|
||||
/* Caller must check for minimum packet size. */
|
||||
pxSocket = pxUDPSocketLookup( usPort );
|
||||
|
||||
if( pxSocket )
|
||||
{
|
||||
|
||||
/* When refreshing the ARP cache with received UDP packets we must be
|
||||
careful; hundreds of broadcast messages may pass and if we're not
|
||||
handling them, no use to fill the ARP cache with those IP addresses. */
|
||||
vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS == 1 )
|
||||
{
|
||||
/* Did the owner of this socket register a reception handler ? */
|
||||
if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleReceive ) )
|
||||
{
|
||||
struct freertos_sockaddr xSourceAddress, destinationAddress;
|
||||
void *pcData = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
|
||||
FOnUDPReceive_t xHandler = ( FOnUDPReceive_t ) pxSocket->u.xUDP.pxHandleReceive;
|
||||
xSourceAddress.sin_port = pxNetworkBuffer->usPort;
|
||||
xSourceAddress.sin_addr = pxNetworkBuffer->ulIPAddress;
|
||||
destinationAddress.sin_port = usPort;
|
||||
destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
|
||||
|
||||
if( xHandler( ( Socket_t * ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
|
||||
&xSourceAddress, &destinationAddress ) )
|
||||
{
|
||||
xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_CALLBACKS */
|
||||
|
||||
#if( ipconfigUDP_MAX_RX_PACKETS > 0 )
|
||||
{
|
||||
if( xReturn == pdPASS )
|
||||
{
|
||||
if ( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) >= pxSocket->u.xUDP.uxMaxPackets )
|
||||
{
|
||||
FreeRTOS_debug_printf( ( "xProcessReceivedUDPPacket: buffer full %ld >= %ld port %u\n",
|
||||
listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ),
|
||||
pxSocket->u.xUDP.uxMaxPackets, pxSocket->usLocalPort ) );
|
||||
xReturn = pdFAIL; /* we did not consume or release the buffer */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( xReturn == pdPASS )
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
if( xReturn == pdPASS )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Add the network packet to the list of packets to be
|
||||
processed by the socket. */
|
||||
vListInsertEnd( &( pxSocket->u.xUDP.xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
xTaskResumeAll();
|
||||
|
||||
/* Set the socket's receive event */
|
||||
if( pxSocket->xEventGroup != NULL )
|
||||
{
|
||||
xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
|
||||
}
|
||||
|
||||
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
|
||||
{
|
||||
if( ( pxSocket->pxSocketSet != NULL ) && ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) )
|
||||
{
|
||||
xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, eSELECT_READ );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
|
||||
{
|
||||
if( pxSocket->pxUserSemaphore != NULL )
|
||||
{
|
||||
xSemaphoreGive( pxSocket->pxUserSemaphore );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_DHCP == 1 )
|
||||
{
|
||||
if( xIsDHCPSocket( pxSocket ) )
|
||||
{
|
||||
xSendEventToIPTask( eDHCPEvent );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is no socket listening to the target port, but still it might
|
||||
be for this node. */
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
/* a LLMNR request, check for the destination port. */
|
||||
if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
|
||||
( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )
|
||||
{
|
||||
vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
|
||||
#if( ipconfigUSE_NBNS == 1 )
|
||||
/* a NetBIOS request, check for the destination port */
|
||||
if( ( usPort == FreeRTOS_ntohs( ipNBNS_PORT ) ) ||
|
||||
( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipNBNS_PORT ) ) )
|
||||
{
|
||||
vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
xReturn = ( BaseType_t )ulNBNSHandlePacket( pxNetworkBuffer );
|
||||
}
|
||||
else
|
||||
#endif /* ipconfigUSE_NBNS */
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
187
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt
Executable file
187
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt
Executable file
@ -0,0 +1,187 @@
|
||||
Changes between 160919 and 180821 releases:
|
||||
|
||||
+ Multiple security improvements and fixes in packet parsing routines, DNS
|
||||
caching, and TCP sequence number and ID generation.
|
||||
+ Disable NBNS and LLMNR by default.
|
||||
+ Add TCP hang protection by default.
|
||||
|
||||
We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
|
||||
|
||||
+ Update FreeRTOS_gethostbyname() to allow an IP address to be passed in -
|
||||
in which case it is just returned as a uint32_t.
|
||||
+ Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK to FreeRTOS_Sockets.c to
|
||||
allow a user supposed callback function to be executed when socket events
|
||||
occur in the same way that the socket semaphore is currently used.
|
||||
+ Update xNetworkBuffersInitialise() to ensure the semaphore created by the
|
||||
function is not accessed until after the NULL check.
|
||||
+ Improve print messages output by the Win32 port layer version of
|
||||
prvPrintAvailableNetworkInterfaces().
|
||||
|
||||
Changes between 160908 and 160919 releases:
|
||||
|
||||
+ Add a NULL check before attempting to close the DHCP socket. [Prior to
|
||||
160823 the IP task closed the DHCP socket by calling a public API function
|
||||
- which checked for the socket being NULL. This was changed to call a
|
||||
local private function, which did not have a NULL check, in place of the
|
||||
public API function.]
|
||||
+ Various [internal only] naming changes to better comply with the FreeRTOS
|
||||
naming conventions.
|
||||
+ Improvements to the Zynq network driver. DMA transmission buffers now use
|
||||
a counting semaphore. When all TX-buffers are in-use, the IP-task will
|
||||
block momentarily until a TX-buffer becomes available.
|
||||
+ Experimental implementation of the TCP window scaling protocol. The
|
||||
scaling option will always be offered, at least with a factor 1. If the
|
||||
TCP sliding window size becomes more than 64KB, the factor will increase
|
||||
automatically.
|
||||
+ ipconfigETHERNET_MINIMUM_PACKET_BYTES is now applied for every protocol:
|
||||
TCP, UDP, and ARP.
|
||||
+ Updated the Zynq project to use BufferAllocation_1.c rather than
|
||||
BufferAllocation_2.c - which is a requirement with its current
|
||||
configuration (due to the alignment requirements on the combined cache and
|
||||
DMA configuration).
|
||||
|
||||
Changes between 160823 and 160908 releases:
|
||||
|
||||
+ Use ipconfigZERO_COPY_TX_DRIVER as the xReleaseAfterSend() parameter where
|
||||
prvTCPReturnPacket() is called in prvSendData() to prevent unnecessary
|
||||
copying of data.
|
||||
+ Remove the use of the uxGetRxEventCount variable, which was used to give
|
||||
priority to incoming messages, but could result in the IP task starving
|
||||
application tasks of processing time.
|
||||
|
||||
Changes between 160112 and 160823 releases
|
||||
|
||||
NOTE: The 160908 release is a maintenance release for the 160112 single
|
||||
interface labs release - not a release of the current development branch.
|
||||
|
||||
+ Various minor stability enhancements, including the ability to work with
|
||||
configTICK_RATE_HZ set to less than 1KHz, closing DHCP sockets directly
|
||||
rather than via FreeRTOS_closesocket(), and better handling of unknown
|
||||
TCP packets before an IP address has been assigned.
|
||||
+ ipBUFFER_PADDING is now configurable through the ipconfigBUFFER_PADDING
|
||||
constant to improve network buffer alignment handling capabilities (expert
|
||||
users/driver writers only).
|
||||
+ Multiple improvements to the FTP server, including to how read only and
|
||||
zero length files are handled.
|
||||
+ ipconfigFTP_HAS_USER_PROPERTIES_HOOK (to allow each user to have a
|
||||
different root directory and access rights) and
|
||||
ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK (to handle AJAX style data)
|
||||
introduced, although these are not yet fully tested and the constant names
|
||||
are likely to change.
|
||||
+ Introduce ipconfigHAS_TX_CRC_OFFLOADING.
|
||||
+ ipconfigUSE_DHCP_HOOK is now called ipconfigUSE_DHCP_HOOK, and the name
|
||||
of the callback function has also changed. See the web documentation for
|
||||
details.
|
||||
+ ipconfigTCP_RX_BUF_LEN is now ipconfigTCP_RX_BUFFER_LENGTH, and
|
||||
ipconfigTCP_TX_BUF_LEN is now ipconfigTCP_TX_BUFFER_LENGTH, which is
|
||||
actually how they have always been documented.
|
||||
+ Added example TFTP server capable of receiving (not sending) files.
|
||||
Intended for bootloader type functionality.
|
||||
+ Various variable name changes for consistency (mainly ensuring UDP, TCP,
|
||||
DNS, etc. always use the same case letters, and type prefixes are correct).
|
||||
+ Various minor edits to improve types used by internal variables.
|
||||
+ Simplified mapping of standard library functions to their Visual Studio
|
||||
equivalents.
|
||||
+ Improve robustness of network drivers.
|
||||
+ Introduce pxResizeNetworkBufferWithDescriptor().
|
||||
+ Removed obsolete FreeRTOSIPConfig.h constants from
|
||||
FreeRTOSIPConfigDefaults.h.
|
||||
+ Added additional asserts() - predominantly to catch incorrect structure
|
||||
packing.
|
||||
|
||||
Changes between 160112 and 160111 releases
|
||||
|
||||
+ Updated the STM32 network driver so checksums are calculated by the
|
||||
hardware.
|
||||
+ Implemented a simple "quit" command in the TCP command console.
|
||||
|
||||
Changes between 150825 and 160111 releases
|
||||
|
||||
+ New device support: Demo applications and example drivers are provided
|
||||
for Atmel SAM4E and ST STM32F4 microcontrollers.
|
||||
+ Various updates to improve compliance with the FreeRTOS coding standard.
|
||||
+ Added a command console example that uses TCP/IP for input and output (the
|
||||
pre-existing command console example uses UDP/IP).
|
||||
+ Updated the UDP logging example so it will send log messages to the local
|
||||
UDP broadcast address if a specific IP address is not provided. This
|
||||
simplifies configuration, but note not all switches and routers will pass
|
||||
broadcast messages.
|
||||
+ Add TCP echo client and TCP echo server examples to the Zynq demo.
|
||||
+ Minor updates to the Zynq network driver.
|
||||
+ Update the Zynq project to use version 2015.4 of the Xilinx SDK.
|
||||
+ Introduce FreeRTOS_SignalSocket(), which can be used to interrupt a task
|
||||
that is blocked while reading from a socket ( FreeRTOS_recv[from] ).
|
||||
+ Make use of FreeRTOS_SignalSocket() in the FTP and HTTP servers.
|
||||
+ Major updates to the NTP client, although this is not included in any of
|
||||
the pre-configured demo applications yet.
|
||||
+ Added support for DHCP zero pad option.
|
||||
+ Added uxGetMinimumIPQueueSpace(), a function to monitor the minimum amount
|
||||
of space on the message queue.
|
||||
+ Better handling of zero length files in the FTP server.
|
||||
+ Fixed a bug reported by Andrey Ivanov from swissEmbedded that affects
|
||||
users of 'ipconfigZERO_COPY_TX_DRIVER'.
|
||||
|
||||
|
||||
Changes between 150825 150825 (?)
|
||||
|
||||
+ Added xApplicationDHCPUserHook() so a user defined hook will be
|
||||
called at certain points in the DHCP process if
|
||||
ipconfigDHCP_USES_USER_HOOK is set to 1.
|
||||
+ Added FreeRTOS_get_tx_head() to improve TCP zero copy behaviour - for
|
||||
expert use only.
|
||||
+ RST is no longer sent if only the ACK flag is set.
|
||||
+ Previously, an immediate ACK was only sent when buffer space was
|
||||
exhausted. Now, to improve performance, it is possible to send an
|
||||
immediate ACK earlier - dependent on the ipconfigTCP_ACK_EARLIER_PACKET
|
||||
setting.
|
||||
+ LLMNR and NBNS requests can now be sent to locate other devices -
|
||||
previously these protocols would only be replied to, not generated.
|
||||
+ Added Auto-IP functionality (still in test) in case DHCP fails. Dependent
|
||||
on the ipconfigDHCP_FALL_BACK_LINK_LAYER_ADDRESS and
|
||||
ipconfigARP_USE_CLASH_DETECTION settings.
|
||||
+ Added NTP code and demo.
|
||||
+ FTP can now STOR and RETR zero-length files.
|
||||
+ Added LLMNR demo to Win32 demo - so now the Win32 responds to
|
||||
"ping RTOSDemo".
|
||||
|
||||
Changes between 141019 and 150825
|
||||
|
||||
+ Added FTP server, which uses the new FreeRTOS+FAT component.
|
||||
+ Added basic HTTP server, which uses the new FreeRTOS+FAT component.
|
||||
+ Multiple definitions that are now common with FreeRTOS+FAT have been moved
|
||||
into FreeRTOS's ProjDefs.h header file, and so prefixed with 'pd'.
|
||||
+ Introduced ipconfigZERO_COPY_TX_DRIVER, which defines who is responsible
|
||||
for freeing a buffer sent to to the MAC driver for transmission, and
|
||||
facilitates the development of zero copy drivers.
|
||||
+ Introduced the FREERTOS_MSG_DONTWAIT flag. The flag can be used as a
|
||||
simpler and faster alternative to using FreeRTOS_setsockopt() to set the
|
||||
send or receive timeout to 0.
|
||||
+ A few functions that were previously all lower case are now mixed case, as
|
||||
lower case function names are only used when they are equivalent to a
|
||||
a Berkeley sockets API function of the same name.
|
||||
+ Introduced uxGetMinimumFreeNetworkBuffers() to return the minimum number
|
||||
of network buffers that have ever existed since the application started
|
||||
executing.
|
||||
+ Introduce ipconfigETHERNET_MINIMUM_PACKET_BYTES to allow the application
|
||||
writer to set their own minimum buffer size should the hardware not be
|
||||
capable of padding under-sized Ethernet frames.
|
||||
+ vNetworkBufferRelease() renamed vReleaseNetworkBuffer() - just for
|
||||
consistency with the names of other functions in the same file.
|
||||
+ Grouped DHCP status data into a structure.
|
||||
+ DHCP is now tried both with and without the broadcast flag.
|
||||
+ Replaced occurrences of configASSERT_VOID() with configASSERT().
|
||||
+ ipconfigDNS_USE_CALLBACKS introduced to allow FreeRTOS_gethostbyname() to
|
||||
be used without blocking.
|
||||
+ Fix: LLMNR and NBNS behaviour when the reply is in a larger buffer than the
|
||||
request, and BufferAllocation_2 was used.
|
||||
+ Introduced ipMAX_IP_TASK_SLEEP_TIME to allow the application writer to
|
||||
override the default value of 10 seconds.
|
||||
+ Fix: Correct error in *pxUDPPayloadBuffer_to_NetworkBuffer().
|
||||
+ FreeRTOS_recv() now recognises the FREERTOS_ZERO_COPY flag, which, when
|
||||
set, the void *pvBuffer parameter is interpreted as void **pvBuffer.
|
||||
+ FreeRTOS_listen() now returns an error code. Previously it always
|
||||
returned 0.
|
||||
+ Fix: Previously if a listening socket was reused, and a connection
|
||||
failed, the TCP/IP stack closed the socket, now the socket is correctly
|
||||
left unclosed as it is owned by the application.
|
||||
+ Various other formatting and minor fix alterations.
|
19
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/LICENSE_INFORMATION.txt
Executable file
19
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/LICENSE_INFORMATION.txt
Executable file
@ -0,0 +1,19 @@
|
||||
FreeRTOS+TCP is released under the following MIT license.
|
||||
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
5
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url
Executable file
5
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url
Executable file
@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
||||
[InternetShortcut]
|
||||
URL=http://www.freertos.org/tcp
|
||||
IDList=
|
560
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
Executable file
560
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
Executable file
@ -0,0 +1,560 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_DEFAULT_IP_CONFIG_H
|
||||
#define FREERTOS_DEFAULT_IP_CONFIG_H
|
||||
|
||||
/* The error numbers defined in this file will be moved to the core FreeRTOS
|
||||
code in future versions of FreeRTOS - at which time the following header file
|
||||
will be removed. */
|
||||
#include "FreeRTOS_errno_TCP.h"
|
||||
|
||||
/* This file provides default values for configuration options that are missing
|
||||
from the FreeRTOSIPConfig.h configuration header file. */
|
||||
|
||||
|
||||
/* Ensure defined configuration constants are using the most up to date naming. */
|
||||
#ifdef tcpconfigIP_TIME_TO_LIVE
|
||||
#error now called: ipconfigTCP_TIME_TO_LIVE
|
||||
#endif
|
||||
|
||||
#ifdef updconfigIP_TIME_TO_LIVE
|
||||
#error now called: ipconfigUDP_TIME_TO_LIVE
|
||||
#endif
|
||||
|
||||
#ifdef ipFILLER_SIZE
|
||||
#error now called: ipconfigPACKET_FILLER_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef dnsMAX_REQUEST_ATTEMPTS
|
||||
#error now called: ipconfigDNS_REQUEST_ATTEMPTS
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigUDP_TASK_PRIORITY
|
||||
#error now called: ipconfigIP_TASK_PRIORITY
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigUDP_TASK_STACK_SIZE_WORDS
|
||||
#error now called: ipconfigIP_TASK_STACK_SIZE_WORDS
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigDRIVER_INCLUDED_RX_IP_FILTERING
|
||||
#error now called: ipconfigETHERNET_DRIVER_FILTERS_PACKETS
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigMAX_SEND_BLOCK_TIME_TICKS
|
||||
#error now called: ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigUSE_RECEIVE_CONNECT_CALLBACKS
|
||||
#error now called: ipconfigUSE_CALLBACKS
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigNUM_NETWORK_BUFFERS
|
||||
#error now called: ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigTCP_HANG_PROT
|
||||
#error now called: ipconfigTCP_HANG_PROTECTION
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigTCP_HANG_PROT_TIME
|
||||
#error now called: ipconfigTCP_HANG_PROTECTION_TIME
|
||||
#endif
|
||||
|
||||
#ifdef FreeRTOS_lprintf
|
||||
#error now called: FreeRTOS_debug_printf
|
||||
#endif
|
||||
|
||||
#if ( ipconfigEVENT_QUEUE_LENGTH < ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) )
|
||||
#error The ipconfigEVENT_QUEUE_LENGTH parameter must be at least ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5
|
||||
#endif
|
||||
|
||||
#if ( ipconfigNETWORK_MTU < 46 )
|
||||
#error ipconfigNETWORK_MTU must be at least 46.
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigBUFFER_ALLOC_FIXED_SIZE
|
||||
#error ipconfigBUFFER_ALLOC_FIXED_SIZE was dropped and replaced by a const value, declared in BufferAllocation[12].c
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigNIC_SEND_PASSES_DMA
|
||||
#error now called: ipconfigZERO_COPY_TX_DRIVER
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TX_CRC_OFFLOADING
|
||||
/* _HT_ As these macro names have changed, throw an error
|
||||
if they're still defined. */
|
||||
#error now called: ipconfigHAS_TX_CRC_OFFLOADING
|
||||
#endif
|
||||
|
||||
#ifdef HAS_RX_CRC_OFFLOADING
|
||||
#error now called: ipconfigHAS_RX_CRC_OFFLOADING
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigTCP_RX_BUF_LEN
|
||||
#error ipconfigTCP_RX_BUF_LEN is now called ipconfigTCP_RX_BUFFER_LENGTH
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigTCP_TX_BUF_LEN
|
||||
#error ipconfigTCP_TX_BUF_LEN is now called ipconfigTCP_TX_BUFFER_LENGTH
|
||||
#endif
|
||||
|
||||
#ifdef ipconfigDHCP_USES_USER_HOOK
|
||||
#error ipconfigDHCP_USES_USER_HOOK and its associated callback have been superceeded - see http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html#ipconfigUSE_DHCP_HOOK
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_TCP
|
||||
#define ipconfigUSE_TCP ( 1 )
|
||||
#endif
|
||||
|
||||
#if ipconfigUSE_TCP
|
||||
|
||||
/* Include support for TCP scaling windows */
|
||||
#ifndef ipconfigUSE_TCP_WIN
|
||||
#define ipconfigUSE_TCP_WIN ( 1 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_WIN_SEG_COUNT
|
||||
#define ipconfigTCP_WIN_SEG_COUNT ( 256 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigIGNORE_UNKNOWN_PACKETS
|
||||
/* When non-zero, TCP will not send RST packets in reply to
|
||||
TCP packets which are unknown, or out-of-order. */
|
||||
#define ipconfigIGNORE_UNKNOWN_PACKETS ( 0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For debuging/logging: check if the port number is used for telnet
|
||||
* Some events will not be logged for telnet connections
|
||||
* because it would produce logging about the transmission of the logging...
|
||||
* This macro will only be used if FreeRTOS_debug_printf() is defined for logging
|
||||
*/
|
||||
#ifndef ipconfigTCP_MAY_LOG_PORT
|
||||
#define ipconfigTCP_MAY_LOG_PORT(xPort) ( ( xPort ) != 23u )
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME
|
||||
#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME portMAX_DELAY
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME
|
||||
#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME portMAX_DELAY
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FreeRTOS debug logging routine (proposal)
|
||||
* The macro will be called in the printf() style. Users can define
|
||||
* their own logging routine as:
|
||||
*
|
||||
* #define FreeRTOS_debug_printf( MSG ) my_printf MSG
|
||||
*
|
||||
* The FreeRTOS_debug_printf() must be thread-safe but does not have to be
|
||||
* interrupt-safe.
|
||||
*/
|
||||
#ifdef ipconfigHAS_DEBUG_PRINTF
|
||||
#if( ipconfigHAS_DEBUG_PRINTF == 0 )
|
||||
#ifdef FreeRTOS_debug_printf
|
||||
#error Do not define FreeRTOS_debug_print if ipconfigHAS_DEBUG_PRINTF is set to 0
|
||||
#endif /* ifdef FreeRTOS_debug_printf */
|
||||
#endif /* ( ipconfigHAS_DEBUG_PRINTF == 0 ) */
|
||||
#endif /* ifdef ipconfigHAS_DEBUG_PRINTF */
|
||||
|
||||
#ifndef FreeRTOS_debug_printf
|
||||
#define FreeRTOS_debug_printf( MSG ) do{} while(0)
|
||||
#define ipconfigHAS_DEBUG_PRINTF 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FreeRTOS general logging routine (proposal)
|
||||
* Used in some utility functions such as FreeRTOS_netstat() and FreeRTOS_PrintARPCache()
|
||||
*
|
||||
* #define FreeRTOS_printf( MSG ) my_printf MSG
|
||||
*
|
||||
* The FreeRTOS_printf() must be thread-safe but does not have to be interrupt-safe
|
||||
*/
|
||||
#ifdef ipconfigHAS_PRINTF
|
||||
#if( ipconfigHAS_PRINTF == 0 )
|
||||
#ifdef FreeRTOS_printf
|
||||
#error Do not define FreeRTOS_print if ipconfigHAS_PRINTF is set to 0
|
||||
#endif /* ifdef FreeRTOS_debug_printf */
|
||||
#endif /* ( ipconfigHAS_PRINTF == 0 ) */
|
||||
#endif /* ifdef ipconfigHAS_PRINTF */
|
||||
|
||||
#ifndef FreeRTOS_printf
|
||||
#define FreeRTOS_printf( MSG ) do{} while(0)
|
||||
#define ipconfigHAS_PRINTF 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In cases where a lot of logging is produced, FreeRTOS_flush_logging( )
|
||||
* will be called to give the logging module a chance to flush the data
|
||||
* An example of this is the netstat command, which produces many lines of logging
|
||||
*/
|
||||
#ifndef FreeRTOS_flush_logging
|
||||
#define FreeRTOS_flush_logging( ) do{} while(0)
|
||||
#endif
|
||||
|
||||
/* Malloc functions. Within most applications of FreeRTOS, the couple
|
||||
* pvPortMalloc()/vPortFree() will be used.
|
||||
* If there is also SDRAM, the user may decide to use a different memory
|
||||
* allocator:
|
||||
* MallocLarge is used to allocate large TCP buffers (for Rx/Tx)
|
||||
* MallocSocket is used to allocate the space for the sockets
|
||||
*/
|
||||
#ifndef pvPortMallocLarge
|
||||
#define pvPortMallocLarge( x ) pvPortMalloc( x )
|
||||
#endif
|
||||
|
||||
#ifndef vPortFreeLarge
|
||||
#define vPortFreeLarge(ptr) vPortFree(ptr)
|
||||
#endif
|
||||
|
||||
#ifndef pvPortMallocSocket
|
||||
#define pvPortMallocSocket( x ) pvPortMalloc( x )
|
||||
#endif
|
||||
|
||||
#ifndef vPortFreeSocket
|
||||
#define vPortFreeSocket(ptr) vPortFree(ptr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* At several places within the library, random numbers are needed:
|
||||
* - DHCP: For creating a DHCP transaction number
|
||||
* - TCP: Set the Initial Sequence Number: this is the value of the first outgoing
|
||||
* sequence number being used when connecting to a peer.
|
||||
* Having a well randomised ISN is important to avoid spoofing
|
||||
* - UDP/TCP: for setting the first port number to be used, in case a socket
|
||||
* uses a 'random' or anonymous port number
|
||||
*/
|
||||
#ifndef ipconfigRAND32
|
||||
#define ipconfigRAND32() rand()
|
||||
#endif
|
||||
/* --------------------------------------------------------
|
||||
* End of: HT Added some macro defaults for the PLUS-UDP project
|
||||
* -------------------------------------------------------- */
|
||||
|
||||
#ifndef ipconfigUSE_NETWORK_EVENT_HOOK
|
||||
#define ipconfigUSE_NETWORK_EVENT_HOOK 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS
|
||||
#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( pdMS_TO_TICKS( 20 ) )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigARP_CACHE_ENTRIES
|
||||
#define ipconfigARP_CACHE_ENTRIES 10
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigMAX_ARP_RETRANSMISSIONS
|
||||
#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5u )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigMAX_ARP_AGE
|
||||
#define ipconfigMAX_ARP_AGE 150u
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_ARP_REVERSED_LOOKUP
|
||||
#define ipconfigUSE_ARP_REVERSED_LOOKUP 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_ARP_REMOVE_ENTRY
|
||||
#define ipconfigUSE_ARP_REMOVE_ENTRY 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigINCLUDE_FULL_INET_ADDR
|
||||
#define ipconfigINCLUDE_FULL_INET_ADDR 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
|
||||
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 45
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigEVENT_QUEUE_LENGTH
|
||||
#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND
|
||||
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUDP_TIME_TO_LIVE
|
||||
#define ipconfigUDP_TIME_TO_LIVE 128
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_TIME_TO_LIVE
|
||||
#define ipconfigTCP_TIME_TO_LIVE 128
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUDP_MAX_RX_PACKETS
|
||||
/* Make postive to define the maximum number of packets which will be buffered
|
||||
* for each UDP socket.
|
||||
* Can be overridden with the socket option FREERTOS_SO_UDP_MAX_RX_PACKETS
|
||||
*/
|
||||
#define ipconfigUDP_MAX_RX_PACKETS 0u
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_DHCP
|
||||
#define ipconfigUSE_DHCP 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_DHCP_HOOK
|
||||
#define ipconfigUSE_DHCP_HOOK 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDHCP_FALL_BACK_AUTO_IP
|
||||
/*
|
||||
* Only applicable when DHCP is in use:
|
||||
* If no DHCP server responds, use "Auto-IP" : the
|
||||
* device will allocate a random LinkLayer IP address.
|
||||
*/
|
||||
#define ipconfigDHCP_FALL_BACK_AUTO_IP ( 0 )
|
||||
#endif
|
||||
|
||||
#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
|
||||
#define ipconfigARP_USE_CLASH_DETECTION 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigARP_USE_CLASH_DETECTION
|
||||
#define ipconfigARP_USE_CLASH_DETECTION 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigNETWORK_MTU
|
||||
#define ipconfigNETWORK_MTU 1500
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_MSS
|
||||
#define ipconfigTCP_MSS ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER - ipSIZE_OF_TCP_HEADER )
|
||||
#endif
|
||||
|
||||
/* Each TCP socket has circular stream buffers for Rx and Tx, which
|
||||
* have a fixed maximum size.
|
||||
* The defaults for these size are defined here, although
|
||||
* they can be overridden at runtime by using the setsockopt() call */
|
||||
#ifndef ipconfigTCP_RX_BUFFER_LENGTH
|
||||
#define ipconfigTCP_RX_BUFFER_LENGTH ( 4u * ipconfigTCP_MSS ) /* defaults to 5840 bytes */
|
||||
#endif
|
||||
|
||||
/* Define the size of Tx stream buffer for TCP sockets */
|
||||
#ifndef ipconfigTCP_TX_BUFFER_LENGTH
|
||||
# define ipconfigTCP_TX_BUFFER_LENGTH ( 4u * ipconfigTCP_MSS ) /* defaults to 5840 bytes */
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigMAXIMUM_DISCOVER_TX_PERIOD
|
||||
#ifdef _WINDOWS_
|
||||
#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 999 ) )
|
||||
#else
|
||||
#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 30000 ) )
|
||||
#endif /* _WINDOWS_ */
|
||||
#endif /* ipconfigMAXIMUM_DISCOVER_TX_PERIOD */
|
||||
|
||||
#ifndef ipconfigUSE_DNS
|
||||
#define ipconfigUSE_DNS 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDNS_REQUEST_ATTEMPTS
|
||||
#define ipconfigDNS_REQUEST_ATTEMPTS 5
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_DNS_CACHE
|
||||
#define ipconfigUSE_DNS_CACHE 0
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE != 0 )
|
||||
#ifndef ipconfigDNS_CACHE_NAME_LENGTH
|
||||
/* Per https://tools.ietf.org/html/rfc1035, 253 is the maximum string length
|
||||
of a DNS name. The following default accounts for a null terminator. */
|
||||
#define ipconfigDNS_CACHE_NAME_LENGTH 254
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDNS_CACHE_ENTRIES
|
||||
#define ipconfigDNS_CACHE_ENTRIES 1
|
||||
#endif
|
||||
#endif /* ipconfigUSE_DNS_CACHE != 0 */
|
||||
|
||||
#ifndef ipconfigCHECK_IP_QUEUE_SPACE
|
||||
#define ipconfigCHECK_IP_QUEUE_SPACE 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_LLMNR
|
||||
/* Include support for LLMNR: Link-local Multicast Name Resolution (non-Microsoft) */
|
||||
#define ipconfigUSE_LLMNR ( 0 )
|
||||
#endif
|
||||
|
||||
#if( !defined( ipconfigUSE_DNS ) )
|
||||
#if( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) )
|
||||
/* LLMNR and NBNS depend on DNS because those protocols share a lot of code. */
|
||||
#error When either LLMNR or NBNS is used, ipconfigUSE_DNS must be defined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigREPLY_TO_INCOMING_PINGS
|
||||
#define ipconfigREPLY_TO_INCOMING_PINGS 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSUPPORT_OUTGOING_PINGS
|
||||
#define ipconfigSUPPORT_OUTGOING_PINGS 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES
|
||||
#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES
|
||||
#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
|
||||
#endif
|
||||
|
||||
#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
|
||||
#define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS 0
|
||||
#else
|
||||
#define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS configINCLUDE_TRACE_RELATED_CLI_COMMANDS
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
|
||||
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM ( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigETHERNET_DRIVER_FILTERS_PACKETS
|
||||
#define ipconfigETHERNET_DRIVER_FILTERS_PACKETS ( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigWATCHDOG_TIMER
|
||||
/* This macro will be called in every loop the IP-task makes. It may be
|
||||
replaced by user-code that triggers a watchdog */
|
||||
#define ipconfigWATCHDOG_TIMER()
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_CALLBACKS
|
||||
#define ipconfigUSE_CALLBACKS ( 0 )
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_CALLBACKS != 0 )
|
||||
#ifndef ipconfigIS_VALID_PROG_ADDRESS
|
||||
/* Replace this macro with a test returning non-zero if the memory pointer to by x
|
||||
* is valid memory which can contain executable code
|
||||
* In fact this is an extra safety measure: if a handler points to invalid memory,
|
||||
* it will not be called
|
||||
*/
|
||||
#define ipconfigIS_VALID_PROG_ADDRESS(x) ( ( x ) != NULL )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigHAS_INLINE_FUNCTIONS
|
||||
#define ipconfigHAS_INLINE_FUNCTIONS ( 1 )
|
||||
#endif
|
||||
|
||||
#ifndef portINLINE
|
||||
#define portINLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigZERO_COPY_TX_DRIVER
|
||||
/* When non-zero, the buffers passed to the SEND routine may be passed
|
||||
to DMA. As soon as sending is ready, the buffers must be released by
|
||||
calling vReleaseNetworkBufferAndDescriptor(), */
|
||||
#define ipconfigZERO_COPY_TX_DRIVER ( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigZERO_COPY_RX_DRIVER
|
||||
/* This define doesn't mean much to the driver, except that it makes
|
||||
sure that pxPacketBuffer_to_NetworkBuffer() will be included. */
|
||||
#define ipconfigZERO_COPY_RX_DRIVER ( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM
|
||||
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
|
||||
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDHCP_REGISTER_HOSTNAME
|
||||
#define ipconfigDHCP_REGISTER_HOSTNAME 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSOCKET_HAS_USER_SEMAPHORE
|
||||
#define ipconfigSOCKET_HAS_USER_SEMAPHORE 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSOCKET_HAS_USER_WAKE_CALLBACK
|
||||
#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSUPPORT_SELECT_FUNCTION
|
||||
#define ipconfigSUPPORT_SELECT_FUNCTION 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_KEEP_ALIVE
|
||||
#define ipconfigTCP_KEEP_ALIVE 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigDNS_USE_CALLBACKS
|
||||
#define ipconfigDNS_USE_CALLBACKS 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSUPPORT_SIGNALS
|
||||
#define ipconfigSUPPORT_SIGNALS 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigUSE_NBNS
|
||||
#define ipconfigUSE_NBNS 0
|
||||
#endif
|
||||
|
||||
/* As an attack surface reduction for ports that listen for inbound
|
||||
connections, hang protection can help reduce the impact of SYN floods. */
|
||||
#ifndef ipconfigTCP_HANG_PROTECTION
|
||||
#define ipconfigTCP_HANG_PROTECTION 1
|
||||
#endif
|
||||
|
||||
/* Non-activity timeout is expressed in seconds. */
|
||||
#ifndef ipconfigTCP_HANG_PROTECTION_TIME
|
||||
#define ipconfigTCP_HANG_PROTECTION_TIME 30
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigTCP_IP_SANITY
|
||||
#define ipconfigTCP_IP_SANITY 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigARP_STORES_REMOTE_ADDRESSES
|
||||
#define ipconfigARP_STORES_REMOTE_ADDRESSES 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigBUFFER_PADDING
|
||||
/* Expert option: define a value for 'ipBUFFER_PADDING'.
|
||||
When 'ipconfigBUFFER_PADDING' equals 0,
|
||||
'ipBUFFER_PADDING' will get a default value of 8 + 2 bytes. */
|
||||
#define ipconfigBUFFER_PADDING 0
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigPACKET_FILLER_SIZE
|
||||
#define ipconfigPACKET_FILLER_SIZE 2
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_DEFAULT_IP_CONFIG_H */
|
141
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h
Executable file
141
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h
Executable file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_ARP_H
|
||||
#define FREERTOS_ARP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "FreeRTOSIPConfigDefaults.h"
|
||||
#include "IPTraceMacroDefaults.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* Miscellaneous structure and definitions. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
typedef struct xARP_CACHE_TABLE_ROW
|
||||
{
|
||||
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
|
||||
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
|
||||
uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
|
||||
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
|
||||
} ARPCacheRow_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eARPCacheMiss = 0, /* 0 An ARP table lookup did not find a valid entry. */
|
||||
eARPCacheHit, /* 1 An ARP table lookup found a valid entry. */
|
||||
eCantSendPacket /* 2 There is no IP address, or an ARP is still in progress, so the packet cannot be sent. */
|
||||
} eARPLookupResult_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eNotFragment = 0, /* The IP packet being sent is not part of a fragment. */
|
||||
eFirstFragment, /* The IP packet being sent is the first in a set of fragmented packets. */
|
||||
eFollowingFragment /* The IP packet being sent is part of a set of fragmented packets. */
|
||||
} eIPFragmentStatus_t;
|
||||
|
||||
/*
|
||||
* If ulIPAddress is already in the ARP cache table then reset the age of the
|
||||
* entry back to its maximum value. If ulIPAddress is not already in the ARP
|
||||
* cache table then add it - replacing the oldest current entry if there is not
|
||||
* a free space available.
|
||||
*/
|
||||
void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress );
|
||||
|
||||
#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
||||
/* Becomes non-zero if another device responded to a gratuitos ARP message. */
|
||||
extern BaseType_t xARPHadIPClash;
|
||||
/* MAC-address of the other device containing the same IP-address. */
|
||||
extern MACAddress_t xARPClashMacAddress;
|
||||
#endif /* ipconfigARP_USE_CLASH_DETECTION */
|
||||
|
||||
#if( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
|
||||
|
||||
/*
|
||||
* In some rare cases, it might be useful to remove a ARP cache entry of a
|
||||
* known MAC address to make sure it gets refreshed.
|
||||
*/
|
||||
uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress );
|
||||
|
||||
#endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
|
||||
|
||||
/*
|
||||
* Look for ulIPAddress in the ARP cache. If the IP address exists, copy the
|
||||
* associated MAC address into pxMACAddress, refresh the ARP cache entry's
|
||||
* age, and return eARPCacheHit. If the IP address does not exist in the ARP
|
||||
* cache return eARPCacheMiss. If the packet cannot be sent for any reason
|
||||
* (maybe DHCP is still in process, or the addressing needs a gateway but there
|
||||
* isn't a gateway defined) then return eCantSendPacket.
|
||||
*/
|
||||
eARPLookupResult_t eARPGetCacheEntry( uint32_t *pulIPAddress, MACAddress_t * const pxMACAddress );
|
||||
|
||||
#if( ipconfigUSE_ARP_REVERSED_LOOKUP != 0 )
|
||||
|
||||
/* Lookup an IP-address if only the MAC-address is known */
|
||||
eARPLookupResult_t eARPGetCacheEntryByMac( MACAddress_t * const pxMACAddress, uint32_t *pulIPAddress );
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Reduce the age count in each entry within the ARP cache. An entry is no
|
||||
* longer considered valid and is deleted if its age reaches zero.
|
||||
*/
|
||||
void vARPAgeCache( void );
|
||||
|
||||
/*
|
||||
* Send out an ARP request for the IP address contained in pxNetworkBuffer, and
|
||||
* add an entry into the ARP table that indicates that an ARP reply is
|
||||
* outstanding so re-transmissions can be generated.
|
||||
*/
|
||||
void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
||||
|
||||
/*
|
||||
* After DHCP is ready and when changing IP address, force a quick send of our new IP
|
||||
* address
|
||||
*/
|
||||
void vARPSendGratuitous( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_ARP_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
87
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h
Executable file
87
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h
Executable file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_DHCP_H
|
||||
#define FREERTOS_DHCP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "IPTraceMacroDefaults.h"
|
||||
|
||||
/* Used in the DHCP callback if ipconfigUSE_DHCP_HOOK is set to 1. */
|
||||
typedef enum eDHCP_PHASE
|
||||
{
|
||||
eDHCPPhasePreDiscover, /* Driver is about to send a DHCP discovery. */
|
||||
eDHCPPhasePreRequest, /* Driver is about to request DHCP an IP address. */
|
||||
#if( ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP != 0 )
|
||||
eDHCPPhasePreLLA, /* Driver is about to try get an LLA address */
|
||||
#endif /* ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP */
|
||||
} eDHCPCallbackPhase_t;
|
||||
|
||||
/* Used in the DHCP callback if ipconfigUSE_DHCP_HOOK is set to 1. */
|
||||
typedef enum eDHCP_ANSWERS
|
||||
{
|
||||
eDHCPContinue, /* Continue the DHCP process */
|
||||
eDHCPUseDefaults, /* Stop DHCP and use the static defaults. */
|
||||
eDHCPStopNoChanges, /* Stop DHCP and continue with current settings. */
|
||||
} eDHCPCallbackAnswer_t;
|
||||
|
||||
/*
|
||||
* NOT A PUBLIC API FUNCTION.
|
||||
*/
|
||||
void vDHCPProcess( BaseType_t xReset );
|
||||
|
||||
/* Internal call: returns true if socket is the current DHCP socket */
|
||||
BaseType_t xIsDHCPSocket( Socket_t xSocket );
|
||||
|
||||
/* Prototype of the hook (or callback) function that must be provided by the
|
||||
application if ipconfigUSE_DHCP_HOOK is set to 1. See the following URL for
|
||||
usage information:
|
||||
http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html#ipconfigUSE_DHCP_HOOK
|
||||
*/
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_DHCP_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
133
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h
Executable file
133
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h
Executable file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_DNS_H
|
||||
#define FREERTOS_DNS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "IPTraceMacroDefaults.h"
|
||||
|
||||
|
||||
/* The Link-local Multicast Name Resolution (LLMNR)
|
||||
* is included.
|
||||
* Note that a special MAC address is required in addition to the NIC's actual
|
||||
* MAC address: 01:00:5E:00:00:FC
|
||||
*
|
||||
* The target IP address will be 224.0.0.252
|
||||
*/
|
||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
|
||||
#define ipLLMNR_IP_ADDR 0xE00000FC
|
||||
#else
|
||||
#define ipLLMNR_IP_ADDR 0xFC0000E0
|
||||
#endif /* ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN */
|
||||
|
||||
#define ipLLMNR_PORT 5355 /* Standard LLMNR port. */
|
||||
#define ipDNS_PORT 53 /* Standard DNS port. */
|
||||
#define ipDHCP_CLIENT 67
|
||||
#define ipDHCP_SERVER 68
|
||||
#define ipNBNS_PORT 137 /* NetBIOS Name Service. */
|
||||
#define ipNBDGM_PORT 138 /* Datagram Service, not included. */
|
||||
|
||||
/*
|
||||
* The following function should be provided by the user and return true if it
|
||||
* matches the domain name.
|
||||
*/
|
||||
extern BaseType_t xApplicationDNSQueryHook( const char *pcName );
|
||||
|
||||
/*
|
||||
* LLMNR is very similar to DNS, so is handled by the DNS routines.
|
||||
*/
|
||||
uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
extern const MACAddress_t xLLMNR_MacAdress;
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
|
||||
#if( ipconfigUSE_NBNS != 0 )
|
||||
|
||||
/*
|
||||
* Inspect a NetBIOS Names-Service message. If the name matches with ours
|
||||
* (xApplicationDNSQueryHook returns true) an answer will be sent back.
|
||||
* Note that LLMNR is a better protocol for name services on a LAN as it is
|
||||
* less polluted
|
||||
*/
|
||||
uint32_t ulNBNSHandlePacket (NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||
|
||||
#endif /* ipconfigUSE_NBNS */
|
||||
|
||||
#if( ipconfigUSE_DNS_CACHE != 0 )
|
||||
|
||||
uint32_t FreeRTOS_dnslookup( const char *pcHostName );
|
||||
|
||||
#endif /* ipconfigUSE_DNS_CACHE != 0 */
|
||||
|
||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||
|
||||
/*
|
||||
* Users may define this type of function as a callback.
|
||||
* It will be called when a DNS reply is received or when a timeout has been reached.
|
||||
*/
|
||||
typedef void (* FOnDNSEvent ) ( const char * /* pcName */, void * /* pvSearchID */, uint32_t /* ulIPAddress */ );
|
||||
|
||||
/*
|
||||
* Asynchronous version of gethostbyname()
|
||||
* xTimeout is in units of ms.
|
||||
*/
|
||||
uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName, FOnDNSEvent pCallback, void *pvSearchID, TickType_t xTimeout );
|
||||
void FreeRTOS_gethostbyname_cancel( void *pvSearchID );
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
|
||||
* FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
|
||||
* _TBD_ Add URL
|
||||
*/
|
||||
uint32_t FreeRTOS_gethostbyname( const char *pcHostName );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_DNS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
328
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
Executable file
328
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
Executable file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_IP_H
|
||||
#define FREERTOS_IP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "FreeRTOSIPConfigDefaults.h"
|
||||
#include "IPTraceMacroDefaults.h"
|
||||
|
||||
/* Some constants defining the sizes of several parts of a packet */
|
||||
#define ipSIZE_OF_ETH_HEADER 14u
|
||||
#define ipSIZE_OF_IPv4_HEADER 20u
|
||||
#define ipSIZE_OF_IGMP_HEADER 8u
|
||||
#define ipSIZE_OF_ICMP_HEADER 8u
|
||||
#define ipSIZE_OF_UDP_HEADER 8u
|
||||
#define ipSIZE_OF_TCP_HEADER 20u
|
||||
|
||||
|
||||
/* The number of octets in the MAC and IP addresses respectively. */
|
||||
#define ipMAC_ADDRESS_LENGTH_BYTES ( 6 )
|
||||
#define ipIP_ADDRESS_LENGTH_BYTES ( 4 )
|
||||
|
||||
/* IP protocol definitions. */
|
||||
#define ipPROTOCOL_ICMP ( 1 )
|
||||
#define ipPROTOCOL_IGMP ( 2 )
|
||||
#define ipPROTOCOL_TCP ( 6 )
|
||||
#define ipPROTOCOL_UDP ( 17 )
|
||||
|
||||
/* Dimensions the buffers that are filled by received Ethernet frames. */
|
||||
#define ipSIZE_OF_ETH_CRC_BYTES ( 4UL )
|
||||
#define ipSIZE_OF_ETH_OPTIONAL_802_1Q_TAG_BYTES ( 4UL )
|
||||
#define ipTOTAL_ETHERNET_FRAME_SIZE ( ( ( uint32_t ) ipconfigNETWORK_MTU ) + ( ( uint32_t ) ipSIZE_OF_ETH_HEADER ) + ipSIZE_OF_ETH_CRC_BYTES + ipSIZE_OF_ETH_OPTIONAL_802_1Q_TAG_BYTES )
|
||||
|
||||
/*_RB_ Comment may need updating. */
|
||||
/* Space left at the beginning of a network buffer storage area to store a
|
||||
pointer back to the network buffer. Should be a multiple of 8 to ensure 8 byte
|
||||
alignment is maintained on architectures that require it.
|
||||
|
||||
In order to get a 32-bit alignment of network packets, an offset of 2 bytes
|
||||
would be desirable, as defined by ipconfigPACKET_FILLER_SIZE. So the malloc'd
|
||||
buffer will have the following contents:
|
||||
uint32_t pointer; // word-aligned
|
||||
uchar_8 filler[6];
|
||||
<< ETH-header >> // half-word-aligned
|
||||
uchar_8 dest[6]; // start of pucEthernetBuffer
|
||||
uchar_8 dest[6];
|
||||
uchar16_t type;
|
||||
<< IP-header >> // word-aligned
|
||||
uint8_t ucVersionHeaderLength;
|
||||
etc
|
||||
*/
|
||||
#if( ipconfigBUFFER_PADDING != 0 )
|
||||
#define ipBUFFER_PADDING ipconfigBUFFER_PADDING
|
||||
#else
|
||||
#define ipBUFFER_PADDING ( 8u + ipconfigPACKET_FILLER_SIZE )
|
||||
#endif
|
||||
|
||||
/* The structure used to store buffers and pass them around the network stack.
|
||||
Buffers can be in use by the stack, in use by the network interface hardware
|
||||
driver, or free (not in use). */
|
||||
typedef struct xNETWORK_BUFFER
|
||||
{
|
||||
ListItem_t xBufferListItem; /* Used to reference the buffer form the free buffer list or a socket. */
|
||||
uint32_t ulIPAddress; /* Source or destination IP address, depending on usage scenario. */
|
||||
uint8_t *pucEthernetBuffer; /* Pointer to the start of the Ethernet frame. */
|
||||
size_t xDataLength; /* Starts by holding the total Ethernet frame length, then the UDP/TCP payload length. */
|
||||
uint16_t usPort; /* Source or destination port, depending on usage scenario. */
|
||||
uint16_t usBoundPort; /* The port to which a transmitting socket is bound. */
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
struct xNETWORK_BUFFER *pxNextBuffer; /* Possible optimisation for expert users - requires network driver support. */
|
||||
#endif
|
||||
} NetworkBufferDescriptor_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xMAC_ADDRESS
|
||||
{
|
||||
uint8_t ucBytes[ ipMAC_ADDRESS_LENGTH_BYTES ];
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
|
||||
typedef struct xMAC_ADDRESS MACAddress_t;
|
||||
|
||||
typedef enum eNETWORK_EVENTS
|
||||
{
|
||||
eNetworkUp, /* The network is configured. */
|
||||
eNetworkDown /* The network connection has been lost. */
|
||||
} eIPCallbackEvent_t;
|
||||
|
||||
typedef enum ePING_REPLY_STATUS
|
||||
{
|
||||
eSuccess = 0, /* A correct reply has been received for an outgoing ping. */
|
||||
eInvalidChecksum, /* A reply was received for an outgoing ping but the checksum of the reply was incorrect. */
|
||||
eInvalidData /* A reply was received to an outgoing ping but the payload of the reply was not correct. */
|
||||
} ePingReplyStatus_t;
|
||||
|
||||
typedef enum eNETWORK_ADDRESS_TYPE
|
||||
{
|
||||
eNetWorkAddressTypeIPV4,
|
||||
eNetWorkAddressTypeIPV6,
|
||||
eNetWorkAddressTypeHostName
|
||||
} eNetWorkAddressType_t;
|
||||
|
||||
/* Endian related definitions. */
|
||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
||||
|
||||
/* FreeRTOS_htons / FreeRTOS_htonl: some platforms might have built-in versions
|
||||
using a single instruction so allow these versions to be overridden. */
|
||||
#ifndef FreeRTOS_htons
|
||||
#define FreeRTOS_htons( usIn ) ( (uint16_t) ( ( ( usIn ) << 8U ) | ( ( usIn ) >> 8U ) ) )
|
||||
#endif
|
||||
|
||||
#ifndef FreeRTOS_htonl
|
||||
#define FreeRTOS_htonl( ulIn ) \
|
||||
( \
|
||||
( uint32_t ) \
|
||||
( \
|
||||
( ( ( ( uint32_t ) ( ulIn ) ) ) << 24 ) | \
|
||||
( ( ( ( uint32_t ) ( ulIn ) ) & 0x0000ff00UL ) << 8 ) | \
|
||||
( ( ( ( uint32_t ) ( ulIn ) ) & 0x00ff0000UL ) >> 8 ) | \
|
||||
( ( ( ( uint32_t ) ( ulIn ) ) ) >> 24 ) \
|
||||
) \
|
||||
)
|
||||
#endif
|
||||
|
||||
#else /* ipconfigBYTE_ORDER */
|
||||
|
||||
#define FreeRTOS_htons( x ) ( ( uint16_t ) ( x ) )
|
||||
#define FreeRTOS_htonl( x ) ( ( uint32_t ) ( x ) )
|
||||
|
||||
#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */
|
||||
|
||||
#define FreeRTOS_ntohs( x ) FreeRTOS_htons( x )
|
||||
#define FreeRTOS_ntohl( x ) FreeRTOS_htonl( x )
|
||||
|
||||
#if( ipconfigHAS_INLINE_FUNCTIONS == 1 )
|
||||
|
||||
static portINLINE int32_t FreeRTOS_max_int32 (int32_t a, int32_t b);
|
||||
static portINLINE uint32_t FreeRTOS_max_uint32 (uint32_t a, uint32_t b);
|
||||
static portINLINE int32_t FreeRTOS_min_int32 (int32_t a, int32_t b);
|
||||
static portINLINE uint32_t FreeRTOS_min_uint32 (uint32_t a, uint32_t b);
|
||||
static portINLINE uint32_t FreeRTOS_round_up (uint32_t a, uint32_t d);
|
||||
static portINLINE uint32_t FreeRTOS_round_down (uint32_t a, uint32_t d);
|
||||
static portINLINE BaseType_t FreeRTOS_min_BaseType (BaseType_t a, BaseType_t b);
|
||||
static portINLINE BaseType_t FreeRTOS_max_BaseType (BaseType_t a, BaseType_t b);
|
||||
static portINLINE UBaseType_t FreeRTOS_max_UBaseType (UBaseType_t a, UBaseType_t b);
|
||||
static portINLINE UBaseType_t FreeRTOS_min_UBaseType (UBaseType_t a, UBaseType_t b);
|
||||
|
||||
|
||||
static portINLINE int32_t FreeRTOS_max_int32 (int32_t a, int32_t b) { return a >= b ? a : b; }
|
||||
static portINLINE uint32_t FreeRTOS_max_uint32 (uint32_t a, uint32_t b) { return a >= b ? a : b; }
|
||||
static portINLINE int32_t FreeRTOS_min_int32 (int32_t a, int32_t b) { return a <= b ? a : b; }
|
||||
static portINLINE uint32_t FreeRTOS_min_uint32 (uint32_t a, uint32_t b) { return a <= b ? a : b; }
|
||||
static portINLINE uint32_t FreeRTOS_round_up (uint32_t a, uint32_t d) { return d * ( ( a + d - 1u ) / d ); }
|
||||
static portINLINE uint32_t FreeRTOS_round_down (uint32_t a, uint32_t d) { return d * ( a / d ); }
|
||||
|
||||
static portINLINE BaseType_t FreeRTOS_max_BaseType (BaseType_t a, BaseType_t b) { return a >= b ? a : b; }
|
||||
static portINLINE UBaseType_t FreeRTOS_max_UBaseType (UBaseType_t a, UBaseType_t b) { return a >= b ? a : b; }
|
||||
static portINLINE BaseType_t FreeRTOS_min_BaseType (BaseType_t a, BaseType_t b) { return a <= b ? a : b; }
|
||||
static portINLINE UBaseType_t FreeRTOS_min_UBaseType (UBaseType_t a, UBaseType_t b) { return a <= b ? a : b; }
|
||||
|
||||
#else
|
||||
|
||||
#define FreeRTOS_max_int32(a,b) ( ( ( int32_t ) ( a ) ) >= ( ( int32_t ) ( b ) ) ? ( ( int32_t ) ( a ) ) : ( ( int32_t ) ( b ) ) )
|
||||
#define FreeRTOS_max_uint32(a,b) ( ( ( uint32_t ) ( a ) ) >= ( ( uint32_t ) ( b ) ) ? ( ( uint32_t ) ( a ) ) : ( ( uint32_t ) ( b ) ) )
|
||||
|
||||
#define FreeRTOS_min_int32(a,b) ( ( ( int32_t ) a ) <= ( ( int32_t ) b ) ? ( ( int32_t ) a ) : ( ( int32_t ) b ) )
|
||||
#define FreeRTOS_min_uint32(a,b) ( ( ( uint32_t ) a ) <= ( ( uint32_t ) b ) ? ( ( uint32_t ) a ) : ( ( uint32_t ) b ) )
|
||||
|
||||
/* Round-up: a = d * ( ( a + d - 1 ) / d ) */
|
||||
#define FreeRTOS_round_up(a,d) ( ( ( uint32_t ) ( d ) ) * ( ( ( ( uint32_t ) ( a ) ) + ( ( uint32_t ) ( d ) ) - 1UL ) / ( ( uint32_t ) ( d ) ) ) )
|
||||
#define FreeRTOS_round_down(a,d) ( ( ( uint32_t ) ( d ) ) * ( ( ( uint32_t ) ( a ) ) / ( ( uint32_t ) ( d ) ) ) )
|
||||
|
||||
#define FreeRTOS_ms_to_tick(ms) ( ( ms * configTICK_RATE_HZ + 500 ) / 1000 )
|
||||
|
||||
#define FreeRTOS_max_BaseType(a, b) ( ( ( BaseType_t ) ( a ) ) >= ( ( BaseType_t ) ( b ) ) ? ( ( BaseType_t ) ( a ) ) : ( ( BaseType_t ) ( b ) ) )
|
||||
#define FreeRTOS_max_UBaseType(a, b) ( ( ( UBaseType_t ) ( a ) ) >= ( ( UBaseType_t ) ( b ) ) ? ( ( UBaseType_t ) ( a ) ) : ( ( UBaseType_t ) ( b ) ) )
|
||||
#define FreeRTOS_min_BaseType(a, b) ( ( ( BaseType_t ) ( a ) ) <= ( ( BaseType_t ) ( b ) ) ? ( ( BaseType_t ) ( a ) ) : ( ( BaseType_t ) ( b ) ) )
|
||||
#define FreeRTOS_min_UBaseType(a, b) ( ( ( UBaseType_t ) ( a ) ) <= ( ( UBaseType_t ) ( b ) ) ? ( ( UBaseType_t ) ( a ) ) : ( ( UBaseType_t ) ( b ) ) )
|
||||
|
||||
#endif /* ipconfigHAS_INLINE_FUNCTIONS */
|
||||
|
||||
#define pdMS_TO_MIN_TICKS( xTimeInMs ) ( pdMS_TO_TICKS( ( xTimeInMs ) ) < ( ( TickType_t ) 1 ) ? ( ( TickType_t ) 1 ) : pdMS_TO_TICKS( ( xTimeInMs ) ) )
|
||||
|
||||
#ifndef pdTRUE_SIGNED
|
||||
/* Temporary solution: eventually the defines below will appear in 'Source\include\projdefs.h' */
|
||||
#define pdTRUE_SIGNED pdTRUE
|
||||
#define pdFALSE_SIGNED pdFALSE
|
||||
#define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1u )
|
||||
#define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0u )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
|
||||
* FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html
|
||||
*/
|
||||
BaseType_t FreeRTOS_IPInit( const uint8_t ucIPAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
|
||||
const uint8_t ucNetMask[ ipIP_ADDRESS_LENGTH_BYTES ],
|
||||
const uint8_t ucGatewayAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
|
||||
const uint8_t ucDNSServerAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
|
||||
const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] );
|
||||
|
||||
void * FreeRTOS_GetUDPPayloadBuffer( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks );
|
||||
void FreeRTOS_GetAddressConfiguration( uint32_t *pulIPAddress, uint32_t *pulNetMask, uint32_t *pulGatewayAddress, uint32_t *pulDNSServerAddress );
|
||||
void FreeRTOS_SetAddressConfiguration( const uint32_t *pulIPAddress, const uint32_t *pulNetMask, const uint32_t *pulGatewayAddress, const uint32_t *pulDNSServerAddress );
|
||||
BaseType_t FreeRTOS_SendPingRequest( uint32_t ulIPAddress, size_t xNumberOfBytesToSend, TickType_t xBlockTimeTicks );
|
||||
void FreeRTOS_ReleaseUDPPayloadBuffer( void *pvBuffer );
|
||||
const uint8_t * FreeRTOS_GetMACAddress( void );
|
||||
void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] );
|
||||
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent );
|
||||
void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier );
|
||||
uint32_t FreeRTOS_GetIPAddress( void );
|
||||
void FreeRTOS_SetIPAddress( uint32_t ulIPAddress );
|
||||
void FreeRTOS_SetNetmask( uint32_t ulNetmask );
|
||||
void FreeRTOS_SetGatewayAddress( uint32_t ulGatewayAddress );
|
||||
uint32_t FreeRTOS_GetGatewayAddress( void );
|
||||
uint32_t FreeRTOS_GetDNSServerAddress( void );
|
||||
uint32_t FreeRTOS_GetNetmask( void );
|
||||
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress );
|
||||
BaseType_t FreeRTOS_IsNetworkUp( void );
|
||||
|
||||
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
|
||||
UBaseType_t uxGetMinimumIPQueueSpace( void );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Defined in FreeRTOS_Sockets.c
|
||||
* //_RB_ Don't think this comment is correct. If this is for internal use only it should appear after all the public API functions and not start with FreeRTOS_.
|
||||
* Socket has had activity, reset the timer so it will not be closed
|
||||
* because of inactivity
|
||||
*/
|
||||
const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState);
|
||||
|
||||
/* _HT_ Temporary: show all valid ARP entries
|
||||
*/
|
||||
void FreeRTOS_PrintARPCache( void );
|
||||
void FreeRTOS_ClearARP( void );
|
||||
|
||||
#if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
|
||||
|
||||
/* DHCP has an option for clients to register their hostname. It doesn't
|
||||
have much use, except that a device can be found in a router along with its
|
||||
name. If this option is used the callback below must be provided by the
|
||||
application writer to return a const string, denoting the device's name. */
|
||||
const char *pcApplicationHostnameHook( void );
|
||||
|
||||
#endif /* ipconfigDHCP_REGISTER_HOSTNAME */
|
||||
|
||||
|
||||
/* For backward compatibility define old structure names to the newer equivalent
|
||||
structure name. */
|
||||
#ifndef ipconfigENABLE_BACKWARD_COMPATIBILITY
|
||||
#define ipconfigENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#endif
|
||||
|
||||
#if( ipconfigENABLE_BACKWARD_COMPATIBILITY == 1 )
|
||||
#define xIPStackEvent_t IPStackEvent_t
|
||||
#define xNetworkBufferDescriptor_t NetworkBufferDescriptor_t
|
||||
#define xMACAddress_t MACAddress_t
|
||||
#define xWinProperties_t WinProperties_t
|
||||
#define xSocket_t Socket_t
|
||||
#define xSocketSet_t SocketSet_t
|
||||
#define ipSIZE_OF_IP_HEADER ipSIZE_OF_IPv4_HEADER
|
||||
|
||||
/* Since August 2016, the public types and fields below have changed name:
|
||||
abbreviations TCP/UDP are now written in capitals, and type names now end with "_t". */
|
||||
#define FOnConnected FOnConnected_t
|
||||
#define FOnTcpReceive FOnTCPReceive_t
|
||||
#define FOnTcpSent FOnTCPSent_t
|
||||
#define FOnUdpReceive FOnUDPReceive_t
|
||||
#define FOnUdpSent FOnUDPSent_t
|
||||
|
||||
#define pOnTcpConnected pxOnTCPConnected
|
||||
#define pOnTcpReceive pxOnTCPReceive
|
||||
#define pOnTcpSent pxOnTCPSent
|
||||
#define pOnUdpReceive pxOnUDPReceive
|
||||
#define pOnUdpSent pxOnUDPSent
|
||||
|
||||
#define FOnUdpSent FOnUDPSent_t
|
||||
#define FOnTcpSent FOnTCPSent_t
|
||||
#endif /* ipconfigENABLE_BACKWARD_COMPATIBILITY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_IP_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
827
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h
Executable file
827
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h
Executable file
@ -0,0 +1,827 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_IP_PRIVATE_H
|
||||
#define FREERTOS_IP_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "FreeRTOSIPConfigDefaults.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "IPTraceMacroDefaults.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
#include "FreeRTOS_TCP_WIN.h"
|
||||
#include "FreeRTOS_TCP_IP.h"
|
||||
#endif
|
||||
|
||||
#include "event_groups.h"
|
||||
|
||||
typedef struct xNetworkAddressingParameters
|
||||
{
|
||||
uint32_t ulDefaultIPAddress;
|
||||
uint32_t ulNetMask;
|
||||
uint32_t ulGatewayAddress;
|
||||
uint32_t ulDNSServerAddress;
|
||||
uint32_t ulBroadcastAddress;
|
||||
} NetworkAddressingParameters_t;
|
||||
|
||||
extern BaseType_t xTCPWindowLoggingLevel;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* Protocol headers. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xETH_HEADER
|
||||
{
|
||||
MACAddress_t xDestinationAddress; /* 0 + 6 = 6 */
|
||||
MACAddress_t xSourceAddress; /* 6 + 6 = 12 */
|
||||
uint16_t usFrameType; /* 12 + 2 = 14 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xETH_HEADER EthernetHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xARP_HEADER
|
||||
{
|
||||
uint16_t usHardwareType; /* 0 + 2 = 2 */
|
||||
uint16_t usProtocolType; /* 2 + 2 = 4 */
|
||||
uint8_t ucHardwareAddressLength; /* 4 + 1 = 5 */
|
||||
uint8_t ucProtocolAddressLength; /* 5 + 1 = 6 */
|
||||
uint16_t usOperation; /* 6 + 2 = 8 */
|
||||
MACAddress_t xSenderHardwareAddress; /* 8 + 6 = 14 */
|
||||
uint8_t ucSenderProtocolAddress[ 4 ]; /* 14 + 4 = 18 */
|
||||
MACAddress_t xTargetHardwareAddress; /* 18 + 6 = 24 */
|
||||
uint32_t ulTargetProtocolAddress; /* 24 + 4 = 28 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xARP_HEADER ARPHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xIP_HEADER
|
||||
{
|
||||
uint8_t ucVersionHeaderLength; /* 0 + 1 = 1 */
|
||||
uint8_t ucDifferentiatedServicesCode; /* 1 + 1 = 2 */
|
||||
uint16_t usLength; /* 2 + 2 = 4 */
|
||||
uint16_t usIdentification; /* 4 + 2 = 6 */
|
||||
uint16_t usFragmentOffset; /* 6 + 2 = 8 */
|
||||
uint8_t ucTimeToLive; /* 8 + 1 = 9 */
|
||||
uint8_t ucProtocol; /* 9 + 1 = 10 */
|
||||
uint16_t usHeaderChecksum; /* 10 + 2 = 12 */
|
||||
uint32_t ulSourceIPAddress; /* 12 + 4 = 16 */
|
||||
uint32_t ulDestinationIPAddress; /* 16 + 4 = 20 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xIP_HEADER IPHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xIGMP_HEADER
|
||||
{
|
||||
uint8_t ucVersionType; /* 0 + 1 = 1 */
|
||||
uint8_t ucMaxResponseTime; /* 1 + 1 = 2 */
|
||||
uint16_t usChecksum; /* 2 + 2 = 4 */
|
||||
uint32_t usGroupAddress; /* 4 + 4 = 8 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xIGMP_HEADER IGMPHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xICMP_HEADER
|
||||
{
|
||||
uint8_t ucTypeOfMessage; /* 0 + 1 = 1 */
|
||||
uint8_t ucTypeOfService; /* 1 + 1 = 2 */
|
||||
uint16_t usChecksum; /* 2 + 2 = 4 */
|
||||
uint16_t usIdentifier; /* 4 + 2 = 6 */
|
||||
uint16_t usSequenceNumber; /* 6 + 2 = 8 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xICMP_HEADER ICMPHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xUDP_HEADER
|
||||
{
|
||||
uint16_t usSourcePort; /* 0 + 2 = 2 */
|
||||
uint16_t usDestinationPort; /* 2 + 2 = 4 */
|
||||
uint16_t usLength; /* 4 + 2 = 6 */
|
||||
uint16_t usChecksum; /* 6 + 2 = 8 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xUDP_HEADER UDPHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xTCP_HEADER
|
||||
{
|
||||
uint16_t usSourcePort; /* + 2 = 2 */
|
||||
uint16_t usDestinationPort; /* + 2 = 4 */
|
||||
uint32_t ulSequenceNumber; /* + 4 = 8 */
|
||||
uint32_t ulAckNr; /* + 4 = 12 */
|
||||
uint8_t ucTCPOffset; /* + 1 = 13 */
|
||||
uint8_t ucTCPFlags; /* + 1 = 14 */
|
||||
uint16_t usWindow; /* + 2 = 15 */
|
||||
uint16_t usChecksum; /* + 2 = 18 */
|
||||
uint16_t usUrgent; /* + 2 = 20 */
|
||||
#if ipconfigUSE_TCP == 1
|
||||
/* the option data is not a part of the TCP header */
|
||||
uint8_t ucOptdata[ipSIZE_TCP_OPTIONS]; /* + 12 = 32 */
|
||||
#endif
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xTCP_HEADER TCPHeader_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xPSEUDO_HEADER
|
||||
{
|
||||
uint32_t ulSourceAddress;
|
||||
uint32_t ulDestinationAddress;
|
||||
uint8_t ucZeros;
|
||||
uint8_t ucProtocol;
|
||||
uint16_t usUDPLength;
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xPSEUDO_HEADER PseudoHeader_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* Nested protocol packets. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xARP_PACKET
|
||||
{
|
||||
EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
|
||||
ARPHeader_t xARPHeader; /* 14 + 28 = 42 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xARP_PACKET ARPPacket_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xIP_PACKET
|
||||
{
|
||||
EthernetHeader_t xEthernetHeader;
|
||||
IPHeader_t xIPHeader;
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xIP_PACKET IPPacket_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xICMP_PACKET
|
||||
{
|
||||
EthernetHeader_t xEthernetHeader;
|
||||
IPHeader_t xIPHeader;
|
||||
ICMPHeader_t xICMPHeader;
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xICMP_PACKET ICMPPacket_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xUDP_PACKET
|
||||
{
|
||||
EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
|
||||
IPHeader_t xIPHeader; /* 14 + 20 = 34 */
|
||||
UDPHeader_t xUDPHeader; /* 34 + 8 = 42 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xUDP_PACKET UDPPacket_t;
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xTCP_PACKET
|
||||
{
|
||||
EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
|
||||
IPHeader_t xIPHeader; /* 14 + 20 = 34 */
|
||||
TCPHeader_t xTCPHeader; /* 34 + 32 = 66 */
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xTCP_PACKET TCPPacket_t;
|
||||
|
||||
typedef union XPROT_PACKET
|
||||
{
|
||||
ARPPacket_t xARPPacket;
|
||||
TCPPacket_t xTCPPacket;
|
||||
UDPPacket_t xUDPPacket;
|
||||
ICMPPacket_t xICMPPacket;
|
||||
} ProtocolPacket_t;
|
||||
|
||||
|
||||
/* The maximum UDP payload length. */
|
||||
#define ipMAX_UDP_PAYLOAD_LENGTH ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER )
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eReleaseBuffer = 0, /* Processing the frame did not find anything to do - just release the buffer. */
|
||||
eProcessBuffer, /* An Ethernet frame has a valid address - continue process its contents. */
|
||||
eReturnEthernetFrame, /* The Ethernet frame contains an ARP or ICMP packet that can be returned to its source. */
|
||||
eFrameConsumed /* Processing the Ethernet packet contents resulted in the payload being sent to the stack. */
|
||||
} eFrameProcessingResult_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eNoEvent = -1,
|
||||
eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */
|
||||
eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */
|
||||
eARPTimerEvent, /* 2: The ARP timer expired. */
|
||||
eStackTxEvent, /* 3: The software stack has queued a packet to transmit. */
|
||||
eDHCPEvent, /* 4: Process the DHCP state machine. */
|
||||
eTCPTimerEvent, /* 5: See if any TCP socket needs attention. */
|
||||
eTCPAcceptEvent, /* 6: Client API FreeRTOS_accept() waiting for client connections. */
|
||||
eTCPNetStat, /* 7: IP-task is asked to produce a netstat listing. */
|
||||
eSocketBindEvent, /* 8: Send a message to the IP-task to bind a socket to a port. */
|
||||
eSocketCloseEvent, /* 9: Send a message to the IP-task to close a socket. */
|
||||
eSocketSelectEvent, /*10: Send a message to the IP-task for select(). */
|
||||
eSocketSignalEvent, /*11: A socket must be signalled. */
|
||||
} eIPEvent_t;
|
||||
|
||||
typedef struct IP_TASK_COMMANDS
|
||||
{
|
||||
eIPEvent_t eEventType;
|
||||
void *pvData;
|
||||
} IPStackEvent_t;
|
||||
|
||||
#define ipBROADCAST_IP_ADDRESS 0xffffffffUL
|
||||
|
||||
/* Offset into the Ethernet frame that is used to temporarily store information
|
||||
on the fragmentation status of the packet being sent. The value is important,
|
||||
as it is past the location into which the destination address will get placed. */
|
||||
#define ipFRAGMENTATION_PARAMETERS_OFFSET ( 6 )
|
||||
#define ipSOCKET_OPTIONS_OFFSET ( 6 )
|
||||
|
||||
/* Only used when outgoing fragmentation is being used (FreeRTOSIPConfig.h
|
||||
setting. */
|
||||
#define ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset ) ( ( ( usFragmentOffset ) == 0 ) ? ipUDP_PAYLOAD_OFFSET_IPv4 : ipIP_PAYLOAD_OFFSET )
|
||||
|
||||
/* The offset into a UDP packet at which the UDP data (payload) starts. */
|
||||
#define ipUDP_PAYLOAD_OFFSET_IPv4 ( sizeof( UDPPacket_t ) )
|
||||
|
||||
/* The offset into an IP packet into which the IP data (payload) starts. */
|
||||
#define ipIP_PAYLOAD_OFFSET ( sizeof( IPPacket_t ) )
|
||||
|
||||
#include "pack_struct_start.h"
|
||||
struct xUDP_IP_FRAGMENT_PARAMETERS
|
||||
{
|
||||
uint8_t ucSocketOptions;
|
||||
uint8_t ucPadFor16BitAlignment;
|
||||
uint16_t usFragmentedPacketOffset;
|
||||
uint16_t usFragmentLength;
|
||||
uint16_t usPayloadChecksum;
|
||||
}
|
||||
#include "pack_struct_end.h"
|
||||
typedef struct xUDP_IP_FRAGMENT_PARAMETERS IPFragmentParameters_t;
|
||||
|
||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
||||
|
||||
/* Ethernet frame types. */
|
||||
#define ipARP_FRAME_TYPE ( 0x0608U )
|
||||
#define ipIPv4_FRAME_TYPE ( 0x0008U )
|
||||
|
||||
/* ARP related definitions. */
|
||||
#define ipARP_PROTOCOL_TYPE ( 0x0008U )
|
||||
#define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0100U )
|
||||
#define ipARP_REQUEST ( 0x0100U )
|
||||
#define ipARP_REPLY ( 0x0200U )
|
||||
|
||||
#else
|
||||
|
||||
/* Ethernet frame types. */
|
||||
#define ipARP_FRAME_TYPE ( 0x0806U )
|
||||
#define ipIPv4_FRAME_TYPE ( 0x0800U )
|
||||
|
||||
/* ARP related definitions. */
|
||||
#define ipARP_PROTOCOL_TYPE ( 0x0800U )
|
||||
#define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0001U )
|
||||
#define ipARP_REQUEST ( 0x0001 )
|
||||
#define ipARP_REPLY ( 0x0002 )
|
||||
|
||||
#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */
|
||||
|
||||
|
||||
/* For convenience, a MAC address of all zeros and another of all 0xffs are
|
||||
defined const for quick reference. */
|
||||
extern const MACAddress_t xBroadcastMACAddress; /* all 0xff's */
|
||||
extern uint16_t usPacketIdentifier;
|
||||
|
||||
/* Define a default UDP packet header (declared in FreeRTOS_UDP_IP.c) */
|
||||
typedef union xUDPPacketHeader
|
||||
{
|
||||
uint8_t ucBytes[24];
|
||||
uint32_t ulWords[6];
|
||||
} UDPPacketHeader_t;
|
||||
extern UDPPacketHeader_t xDefaultPartUDPPacketHeader;
|
||||
|
||||
/* Structure that stores the netmask, gateway address and DNS server addresses. */
|
||||
extern NetworkAddressingParameters_t xNetworkAddressing;
|
||||
|
||||
/* Structure that stores the defaults for netmask, gateway address and DNS.
|
||||
These values will be copied to 'xNetworkAddressing' in case DHCP is not used,
|
||||
and also in case DHCP does not lead to a confirmed request. */
|
||||
extern NetworkAddressingParameters_t xDefaultAddressing;
|
||||
|
||||
/* True when BufferAllocation_1.c was included, false for BufferAllocation_2.c */
|
||||
extern const BaseType_t xBufferAllocFixedSize;
|
||||
|
||||
/* Defined in FreeRTOS_Sockets.c */
|
||||
#if ( ipconfigUSE_TCP == 1 )
|
||||
extern List_t xBoundTCPSocketsList;
|
||||
#endif
|
||||
|
||||
/* The local IP address is accessed from within xDefaultPartUDPPacketHeader,
|
||||
rather than duplicated in its own variable. */
|
||||
#define ipLOCAL_IP_ADDRESS_POINTER ( ( uint32_t * ) &( xDefaultPartUDPPacketHeader.ulWords[ 20u / sizeof(uint32_t) ] ) )
|
||||
|
||||
/* The local MAC address is accessed from within xDefaultPartUDPPacketHeader,
|
||||
rather than duplicated in its own variable. */
|
||||
#define ipLOCAL_MAC_ADDRESS ( &xDefaultPartUDPPacketHeader.ucBytes[0] )
|
||||
|
||||
/* ICMP packets are sent using the same function as UDP packets. The port
|
||||
number is used to distinguish between the two, as 0 is an invalid UDP port. */
|
||||
#define ipPACKET_CONTAINS_ICMP_DATA ( 0 )
|
||||
|
||||
/* For now, the lower 8 bits in 'xEventBits' will be reserved for the above
|
||||
socket events. */
|
||||
#define SOCKET_EVENT_BIT_COUNT 8
|
||||
|
||||
#define vSetField16( pxBase, xType, xField, usValue ) \
|
||||
{ \
|
||||
( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( usValue ) >> 8 ); \
|
||||
( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( usValue ) & 0xff ); \
|
||||
}
|
||||
|
||||
#define vSetField32( pxBase, xType, xField, ulValue ) \
|
||||
{ \
|
||||
( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( ulValue ) >> 24 ); \
|
||||
( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( ( ulValue ) >> 16 ) & 0xff ); \
|
||||
( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 2 ] = ( uint8_t ) ( ( ( ulValue ) >> 8 ) & 0xff ); \
|
||||
( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 3 ] = ( uint8_t ) ( ( ulValue ) & 0xff ); \
|
||||
}
|
||||
|
||||
#define vFlip_16( left, right ) \
|
||||
do { \
|
||||
uint16_t tmp = (left); \
|
||||
(left) = (right); \
|
||||
(right) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define vFlip_32( left, right ) \
|
||||
do { \
|
||||
uint32_t tmp = (left); \
|
||||
(left) = (right); \
|
||||
(right) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (BaseType_t)(sizeof(x)/sizeof(x)[0])
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A version of FreeRTOS_GetReleaseNetworkBuffer() that can be called from an
|
||||
* interrupt. If a non zero value is returned, then the calling ISR should
|
||||
* perform a context switch before exiting the ISR.
|
||||
*/
|
||||
BaseType_t FreeRTOS_ReleaseFreeNetworkBufferFromISR( void );
|
||||
|
||||
/*
|
||||
* Create a message that contains a command to initialise the network interface.
|
||||
* This is used during initialisation, and at any time the network interface
|
||||
* goes down thereafter. The network interface hardware driver is responsible
|
||||
* for sending the message that contains the network interface down command/
|
||||
* event.
|
||||
*
|
||||
* Only use the FreeRTOS_NetworkDownFromISR() version if the function is to be
|
||||
* called from an interrupt service routine. If FreeRTOS_NetworkDownFromISR()
|
||||
* returns a non-zero value then a context switch should be performed ebfore
|
||||
* the interrupt is exited.
|
||||
*/
|
||||
void FreeRTOS_NetworkDown( void );
|
||||
BaseType_t FreeRTOS_NetworkDownFromISR( void );
|
||||
|
||||
/*
|
||||
* Processes incoming ARP packets.
|
||||
*/
|
||||
eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame );
|
||||
|
||||
/*
|
||||
* Inspect an Ethernet frame to see if it contains data that the stack needs to
|
||||
* process. eProcessBuffer is returned if the frame should be processed by the
|
||||
* stack. eReleaseBuffer is returned if the frame should be discarded.
|
||||
*/
|
||||
eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer );
|
||||
|
||||
/*
|
||||
* Return the checksum generated over xDataLengthBytes from pucNextData.
|
||||
*/
|
||||
uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes );
|
||||
|
||||
/* Socket related private functions. */
|
||||
|
||||
/*
|
||||
* The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
|
||||
* payload size (excluding packet headers) and that the packet in pucEthernetBuffer
|
||||
* is at least the size of UDPPacket_t.
|
||||
*/
|
||||
BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort );
|
||||
|
||||
/*
|
||||
* Initialize the socket list data structures for TCP and UDP.
|
||||
*/
|
||||
BaseType_t vNetworkSocketsInit( void );
|
||||
|
||||
/*
|
||||
* Returns pdTRUE if the IP task has been created and is initialised. Otherwise
|
||||
* returns pdFALSE.
|
||||
*/
|
||||
BaseType_t xIPIsNetworkTaskReady( void );
|
||||
|
||||
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
|
||||
struct XSOCKET;
|
||||
typedef void (*SocketWakeupCallback_t)( struct XSOCKET * pxSocket );
|
||||
#endif
|
||||
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
|
||||
/*
|
||||
* Actually a user thing, but because xBoundTCPSocketsList, let it do by the
|
||||
* IP-task
|
||||
*/
|
||||
void vTCPNetStat( void );
|
||||
|
||||
/*
|
||||
* At least one socket needs to check for timeouts
|
||||
*/
|
||||
TickType_t xTCPTimerCheck( BaseType_t xWillSleep );
|
||||
|
||||
/* Every TCP socket has a buffer space just big enough to store
|
||||
the last TCP header received.
|
||||
As a reference of this field may be passed to DMA, force the
|
||||
alignment to 8 bytes. */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/* Increase the alignment of this union by adding a 64-bit variable. */
|
||||
uint64_t ullAlignmentWord;
|
||||
} a;
|
||||
struct
|
||||
{
|
||||
/* The next field only serves to give 'ucLastPacket' a correct
|
||||
alignment of 8 + 2. See comments in FreeRTOS_IP.h */
|
||||
uint8_t ucFillPacket[ ipconfigPACKET_FILLER_SIZE ];
|
||||
uint8_t ucLastPacket[ sizeof( TCPPacket_t ) ];
|
||||
} u;
|
||||
} LastTCPPacket_t;
|
||||
|
||||
/*
|
||||
* Note that the values of all short and long integers in these structs
|
||||
* are being stored in the native-endian way
|
||||
* Translation should take place when accessing any structure which defines
|
||||
* network packets, such as IPHeader_t and TCPHeader_t
|
||||
*/
|
||||
typedef struct TCPSOCKET
|
||||
{
|
||||
uint32_t ulRemoteIP; /* IP address of remote machine */
|
||||
uint16_t usRemotePort; /* Port on remote machine */
|
||||
struct {
|
||||
/* Most compilers do like bit-flags */
|
||||
uint32_t
|
||||
bMssChange : 1, /* This socket has seen a change in MSS */
|
||||
bPassAccept : 1, /* when true, this socket may be returned in a call to accept() */
|
||||
bPassQueued : 1, /* when true, this socket is an orphan until it gets connected
|
||||
* Why an orphan? Because it may not be returned in a accept() call until it
|
||||
* gets the state eESTABLISHED */
|
||||
bReuseSocket : 1, /* When a listening socket gets a connection, do not create a new instance but keep on using it */
|
||||
bCloseAfterSend : 1,/* As soon as the last byte has been transmitted, finalise the connection
|
||||
* Useful in e.g. FTP connections, where the last data bytes are sent along with the FIN flag */
|
||||
bUserShutdown : 1, /* User requesting a graceful shutdown */
|
||||
bCloseRequested : 1,/* Request to finalise the connection */
|
||||
bLowWater : 1, /* high-water level has been reached. Cleared as soon as 'rx-count < lo-water' */
|
||||
bWinChange : 1, /* The value of bLowWater has changed, must send a window update */
|
||||
bSendKeepAlive : 1, /* When this flag is true, a TCP keep-alive message must be send */
|
||||
bWaitKeepAlive : 1, /* When this flag is true, a TCP keep-alive reply is expected */
|
||||
bConnPrepared : 1, /* Connecting socket: Message has been prepared */
|
||||
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
|
||||
bConnPassed : 1, /* Connecting socket: Socket has been passed in a successful select() */
|
||||
#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
|
||||
bFinAccepted : 1, /* This socket has received (or sent) a FIN and accepted it */
|
||||
bFinSent : 1, /* We've sent out a FIN */
|
||||
bFinRecv : 1, /* We've received a FIN from our peer */
|
||||
bFinAcked : 1, /* Our FIN packet has been acked */
|
||||
bFinLast : 1, /* The last ACK (after FIN and FIN+ACK) has been sent or will be sent by the peer */
|
||||
bRxStopped : 1, /* Application asked to temporarily stop reception */
|
||||
bMallocError : 1, /* There was an error allocating a stream */
|
||||
bWinScaling : 1; /* A TCP-Window Scaling option was offered and accepted in the SYN phase. */
|
||||
} bits;
|
||||
uint32_t ulHighestRxAllowed;
|
||||
/* The highest sequence number that we can receive at any moment */
|
||||
uint16_t usTimeout; /* Time (in ticks) after which this socket needs attention */
|
||||
uint16_t usCurMSS; /* Current Maximum Segment Size */
|
||||
uint16_t usInitMSS; /* Initial maximum segment Size */
|
||||
uint16_t usChildCount; /* In case of a listening socket: number of connections on this port number */
|
||||
uint16_t usBacklog; /* In case of a listening socket: maximum number of concurrent connections on this port number */
|
||||
uint8_t ucRepCount; /* Send repeat count, for retransmissions
|
||||
* This counter is separate from the xmitCount in the
|
||||
* TCP win segments */
|
||||
uint8_t ucTCPState; /* TCP state: see eTCP_STATE */
|
||||
struct XSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */
|
||||
#if( ipconfigTCP_KEEP_ALIVE == 1 )
|
||||
uint8_t ucKeepRepCount;
|
||||
TickType_t xLastAliveTime;
|
||||
#endif /* ipconfigTCP_KEEP_ALIVE */
|
||||
#if( ipconfigTCP_HANG_PROTECTION == 1 )
|
||||
TickType_t xLastActTime;
|
||||
#endif /* ipconfigTCP_HANG_PROTECTION */
|
||||
size_t uxLittleSpace;
|
||||
size_t uxEnoughSpace;
|
||||
size_t uxRxStreamSize;
|
||||
size_t uxTxStreamSize;
|
||||
StreamBuffer_t *rxStream;
|
||||
StreamBuffer_t *txStream;
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
NetworkBufferDescriptor_t *pxAckMessage;
|
||||
#endif /* ipconfigUSE_TCP_WIN */
|
||||
/* Buffer space to store the last TCP header received. */
|
||||
LastTCPPacket_t xPacket;
|
||||
uint8_t tcpflags; /* TCP flags */
|
||||
#if( ipconfigUSE_TCP_WIN != 0 )
|
||||
uint8_t ucMyWinScaleFactor;
|
||||
uint8_t ucPeerWinScaleFactor;
|
||||
#endif
|
||||
#if( ipconfigUSE_CALLBACKS == 1 )
|
||||
FOnTCPReceive_t pxHandleReceive; /*
|
||||
* In case of a TCP socket:
|
||||
* typedef void (* FOnTCPReceive_t) (Socket_t xSocket, void *pData, size_t xLength );
|
||||
*/
|
||||
FOnTCPSent_t pxHandleSent;
|
||||
FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
|
||||
#endif /* ipconfigUSE_CALLBACKS */
|
||||
uint32_t ulWindowSize; /* Current Window size advertised by peer */
|
||||
uint32_t ulRxCurWinSize; /* Constantly changing: this is the current size available for data reception */
|
||||
size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */
|
||||
size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */
|
||||
|
||||
TCPWindow_t xTCPWindow;
|
||||
} IPTCPSocket_t;
|
||||
|
||||
#endif /* ipconfigUSE_TCP */
|
||||
|
||||
typedef struct UDPSOCKET
|
||||
{
|
||||
List_t xWaitingPacketsList; /* Incoming packets */
|
||||
#if( ipconfigUDP_MAX_RX_PACKETS > 0 )
|
||||
UBaseType_t uxMaxPackets; /* Protection: limits the number of packets buffered per socket */
|
||||
#endif /* ipconfigUDP_MAX_RX_PACKETS */
|
||||
#if( ipconfigUSE_CALLBACKS == 1 )
|
||||
FOnUDPReceive_t pxHandleReceive; /*
|
||||
* In case of a UDP socket:
|
||||
* typedef void (* FOnUDPReceive_t) (Socket_t xSocket, void *pData, size_t xLength, struct freertos_sockaddr *pxAddr );
|
||||
*/
|
||||
FOnUDPSent_t pxHandleSent;
|
||||
#endif /* ipconfigUSE_CALLBACKS */
|
||||
} IPUDPSocket_t;
|
||||
|
||||
typedef enum eSOCKET_EVENT {
|
||||
eSOCKET_RECEIVE = 0x0001,
|
||||
eSOCKET_SEND = 0x0002,
|
||||
eSOCKET_ACCEPT = 0x0004,
|
||||
eSOCKET_CONNECT = 0x0008,
|
||||
eSOCKET_BOUND = 0x0010,
|
||||
eSOCKET_CLOSED = 0x0020,
|
||||
eSOCKET_INTR = 0x0040,
|
||||
eSOCKET_ALL = 0x007F,
|
||||
} eSocketEvent_t;
|
||||
|
||||
typedef struct XSOCKET
|
||||
{
|
||||
EventBits_t xEventBits;
|
||||
EventGroupHandle_t xEventGroup;
|
||||
|
||||
ListItem_t xBoundSocketListItem; /* Used to reference the socket from a bound sockets list. */
|
||||
TickType_t xReceiveBlockTime; /* if recv[to] is called while no data is available, wait this amount of time. Unit in clock-ticks */
|
||||
TickType_t xSendBlockTime; /* if send[to] is called while there is not enough space to send, wait this amount of time. Unit in clock-ticks */
|
||||
|
||||
uint16_t usLocalPort; /* Local port on this machine */
|
||||
uint8_t ucSocketOptions;
|
||||
uint8_t ucProtocol; /* choice of FREERTOS_IPPROTO_UDP/TCP */
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
|
||||
SemaphoreHandle_t pxUserSemaphore;
|
||||
#endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
|
||||
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
|
||||
SocketWakeupCallback_t pxUserWakeCallback;
|
||||
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
|
||||
|
||||
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
|
||||
struct xSOCKET_SET *pxSocketSet;
|
||||
/* User may indicate which bits are interesting for this socket. */
|
||||
EventBits_t xSelectBits;
|
||||
/* These bits indicate the events which have actually occurred.
|
||||
They are maintained by the IP-task */
|
||||
EventBits_t xSocketBits;
|
||||
#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
|
||||
/* TCP/UDP specific fields: */
|
||||
/* Before accessing any member of this structure, it should be confirmed */
|
||||
/* that the protocol corresponds with the type of structure */
|
||||
|
||||
union
|
||||
{
|
||||
IPUDPSocket_t xUDP;
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
IPTCPSocket_t xTCP;
|
||||
/* Make sure that xTCP is 8-bytes aligned by
|
||||
declaring a 64-bit variable in the same union */
|
||||
uint64_t ullTCPAlignment;
|
||||
#endif /* ipconfigUSE_TCP */
|
||||
} u;
|
||||
} FreeRTOS_Socket_t;
|
||||
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
/*
|
||||
* Lookup a TCP socket, using a multiple matching: both port numbers and
|
||||
* return IP address.
|
||||
*/
|
||||
FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort );
|
||||
|
||||
#endif /* ipconfigUSE_TCP */
|
||||
|
||||
/*
|
||||
* Look up a local socket by finding a match with the local port.
|
||||
*/
|
||||
FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort );
|
||||
|
||||
/*
|
||||
* Called when the application has generated a UDP packet to send.
|
||||
*/
|
||||
void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
||||
|
||||
/*
|
||||
* Calculate the upper-layer checksum
|
||||
* Works both for UDP, ICMP and TCP packages
|
||||
* bOut = true: checksum will be set in outgoing packets
|
||||
* bOut = false: checksum will be calculated for incoming packets
|
||||
* returning 0xffff means: checksum was correct
|
||||
*/
|
||||
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket );
|
||||
|
||||
/*
|
||||
* An Ethernet frame has been updated (maybe it was an ARP request or a PING
|
||||
* request?) and is to be sent back to its source.
|
||||
*/
|
||||
void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend );
|
||||
|
||||
/*
|
||||
* The internal version of bind()
|
||||
* If 'ulInternal' is true, it is called by the driver
|
||||
* The TCP driver needs to bind a socket at the moment a listening socket
|
||||
* creates a new connected socket
|
||||
*/
|
||||
BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal );
|
||||
|
||||
/*
|
||||
* Internal function to add streaming data to a TCP socket. If ulIn == true,
|
||||
* data will be added to the rxStream, otherwise to the tXStream. Normally data
|
||||
* will be written with ulOffset == 0, meaning: at the end of the FIFO. When
|
||||
* packet come in out-of-order, an offset will be used to put it in front and
|
||||
* the head will not change yet.
|
||||
*/
|
||||
int32_t lTCPAddRxdata(FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount);
|
||||
|
||||
/*
|
||||
* Currently called for any important event.
|
||||
*/
|
||||
void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket );
|
||||
|
||||
/*
|
||||
* Some helping function, their meaning should be clear
|
||||
*/
|
||||
static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr);
|
||||
static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr)
|
||||
{
|
||||
return ( ( ( uint32_t )apChr[0] ) << 24) |
|
||||
( ( ( uint32_t )apChr[1] ) << 16) |
|
||||
( ( ( uint32_t )apChr[2] ) << 8) |
|
||||
( ( ( uint32_t )apChr[3] ) );
|
||||
}
|
||||
|
||||
static portINLINE uint16_t usChar2u16 (const uint8_t *apChr);
|
||||
static portINLINE uint16_t usChar2u16 (const uint8_t *apChr)
|
||||
{
|
||||
return ( uint16_t )
|
||||
( ( ( ( uint32_t )apChr[0] ) << 8) |
|
||||
( ( ( uint32_t )apChr[1] ) ) );
|
||||
}
|
||||
|
||||
/* Check a single socket for retransmissions and timeouts */
|
||||
BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket );
|
||||
|
||||
BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket );
|
||||
|
||||
/* Defined in FreeRTOS_Sockets.c
|
||||
* Close a socket
|
||||
*/
|
||||
void *vSocketClose( FreeRTOS_Socket_t *pxSocket );
|
||||
|
||||
/*
|
||||
* Send the event eEvent to the IP task event queue, using a block time of
|
||||
* zero. Return pdPASS if the message was sent successfully, otherwise return
|
||||
* pdFALSE.
|
||||
*/
|
||||
BaseType_t xSendEventToIPTask( eIPEvent_t eEvent );
|
||||
|
||||
/*
|
||||
* The same as above, but a struct as a parameter, containing:
|
||||
* eIPEvent_t eEventType;
|
||||
* void *pvData;
|
||||
*/
|
||||
BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout );
|
||||
|
||||
/*
|
||||
* Returns a pointer to the original NetworkBuffer from a pointer to a UDP
|
||||
* payload buffer.
|
||||
*/
|
||||
NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer );
|
||||
|
||||
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
|
||||
/*
|
||||
* For the case where the network driver passes a buffer directly to a DMA
|
||||
* descriptor, this function can be used to translate a 'network buffer' to
|
||||
* a 'network buffer descriptor'.
|
||||
*/
|
||||
NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal: Sets a new state for a TCP socket and performs the necessary
|
||||
* actions like calling a OnConnected handler to notify the socket owner.
|
||||
*/
|
||||
#if( ipconfigUSE_TCP == 1 )
|
||||
void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState );
|
||||
#endif /* ipconfigUSE_TCP */
|
||||
|
||||
/*_RB_ Should this be part of the public API? */
|
||||
void FreeRTOS_netstat( void );
|
||||
|
||||
/* Returns pdTRUE is this function is called from the IP-task */
|
||||
BaseType_t xIsCallingFromIPTask( void );
|
||||
|
||||
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
|
||||
|
||||
typedef struct xSOCKET_SET
|
||||
{
|
||||
EventGroupHandle_t xSelectGroup;
|
||||
BaseType_t bApiCalled; /* True if the API was calling the private vSocketSelect */
|
||||
FreeRTOS_Socket_t *pxSocket;
|
||||
} SocketSelect_t;
|
||||
|
||||
extern void vSocketSelect( SocketSelect_t *pxSocketSelect );
|
||||
|
||||
#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
|
||||
|
||||
void vIPSetDHCPTimerEnableState( BaseType_t xEnableState );
|
||||
void vIPReloadDHCPTimer( uint32_t ulLeaseTime );
|
||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||
void vIPReloadDNSTimer( uint32_t ulCheckTime );
|
||||
void vIPSetDnsTimerEnableState( BaseType_t xEnableState );
|
||||
#endif
|
||||
|
||||
/* Send the network-up event and start the ARP timer. */
|
||||
void vIPNetworkUpCalls( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_IP_PRIVATE_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
393
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h
Executable file
393
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h
Executable file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_SOCKETS_H
|
||||
#define FREERTOS_SOCKETS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
|
||||
#ifndef FREERTOS_IP_CONFIG_H
|
||||
#error FreeRTOSIPConfig.h has not been included yet
|
||||
#endif
|
||||
|
||||
/* Event bit definitions are required by the select functions. */
|
||||
#include "event_groups.h"
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error FreeRTOS.h must be included before FreeRTOS_Sockets.h.
|
||||
#endif
|
||||
|
||||
#ifndef INC_TASK_H
|
||||
#ifndef TASK_H /* For compatibility with older FreeRTOS versions. */
|
||||
#error The FreeRTOS header file task.h must be included before FreeRTOS_Sockets.h.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Assigned to an Socket_t variable when the socket is not valid, probably
|
||||
because it could not be created. */
|
||||
#define FREERTOS_INVALID_SOCKET ( ( void * ) ~0U )
|
||||
|
||||
/* API function error values. As errno is supported, the FreeRTOS sockets
|
||||
functions return error codes rather than just a pass or fail indication. */
|
||||
/* HT: Extended the number of error codes, gave them positive values and if possible
|
||||
the corresponding found in errno.h
|
||||
In case of an error, API's will still return negative numbers, e.g.
|
||||
return -pdFREERTOS_ERRNO_EWOULDBLOCK;
|
||||
in case an operation would block */
|
||||
|
||||
/* The following defines are obsolete, please use -pdFREERTOS_ERRNO_Exxx */
|
||||
|
||||
#define FREERTOS_SOCKET_ERROR ( -1 )
|
||||
#define FREERTOS_EWOULDBLOCK ( - pdFREERTOS_ERRNO_EWOULDBLOCK )
|
||||
#define FREERTOS_EINVAL ( - pdFREERTOS_ERRNO_EINVAL )
|
||||
#define FREERTOS_EADDRNOTAVAIL ( - pdFREERTOS_ERRNO_EADDRNOTAVAIL )
|
||||
#define FREERTOS_EADDRINUSE ( - pdFREERTOS_ERRNO_EADDRINUSE )
|
||||
#define FREERTOS_ENOBUFS ( - pdFREERTOS_ERRNO_ENOBUFS )
|
||||
#define FREERTOS_ENOPROTOOPT ( - pdFREERTOS_ERRNO_ENOPROTOOPT )
|
||||
#define FREERTOS_ECLOSED ( - pdFREERTOS_ERRNO_ENOTCONN )
|
||||
|
||||
/* Values for the parameters to FreeRTOS_socket(), inline with the Berkeley
|
||||
standard. See the documentation of FreeRTOS_socket() for more information. */
|
||||
#define FREERTOS_AF_INET ( 2 )
|
||||
#define FREERTOS_AF_INET6 ( 10 )
|
||||
#define FREERTOS_SOCK_DGRAM ( 2 )
|
||||
#define FREERTOS_IPPROTO_UDP ( 17 )
|
||||
|
||||
#define FREERTOS_SOCK_STREAM ( 1 )
|
||||
#define FREERTOS_IPPROTO_TCP ( 6 )
|
||||
/* IP packet of type "Any local network"
|
||||
* can be used in stead of TCP for testing with sockets in raw mode
|
||||
*/
|
||||
#define FREERTOS_IPPROTO_USR_LAN ( 63 )
|
||||
|
||||
/* A bit value that can be passed into the FreeRTOS_sendto() function as part of
|
||||
the flags parameter. Setting the FREERTOS_ZERO_COPY in the flags parameter
|
||||
indicates that the zero copy interface is being used. See the documentation for
|
||||
FreeRTOS_sockets() for more information. */
|
||||
#define FREERTOS_ZERO_COPY ( 1 )
|
||||
|
||||
/* Values that can be passed in the option name parameter of calls to
|
||||
FreeRTOS_setsockopt(). */
|
||||
#define FREERTOS_SO_RCVTIMEO ( 0 ) /* Used to set the receive time out. */
|
||||
#define FREERTOS_SO_SNDTIMEO ( 1 ) /* Used to set the send time out. */
|
||||
#define FREERTOS_SO_UDPCKSUM_OUT ( 2 ) /* Used to turn the use of the UDP checksum by a socket on or off. This also doubles as part of an 8-bit bitwise socket option. */
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
|
||||
#define FREERTOS_SO_SET_SEMAPHORE ( 3 ) /* Used to set a user's semaphore */
|
||||
#endif
|
||||
#define FREERTOS_SO_SNDBUF ( 4 ) /* Set the size of the send buffer (TCP only) */
|
||||
#define FREERTOS_SO_RCVBUF ( 5 ) /* Set the size of the receive buffer (TCP only) */
|
||||
|
||||
#if ipconfigUSE_CALLBACKS == 1
|
||||
#define FREERTOS_SO_TCP_CONN_HANDLER ( 6 ) /* Install a callback for (dis) connection events. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
|
||||
#define FREERTOS_SO_TCP_RECV_HANDLER ( 7 ) /* Install a callback for receiving TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
|
||||
#define FREERTOS_SO_TCP_SENT_HANDLER ( 8 ) /* Install a callback for sending TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
|
||||
#define FREERTOS_SO_UDP_RECV_HANDLER ( 9 ) /* Install a callback for receiving UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
|
||||
#define FREERTOS_SO_UDP_SENT_HANDLER ( 10 ) /* Install a callback for sending UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
|
||||
#endif /* ipconfigUSE_CALLBACKS */
|
||||
|
||||
#define FREERTOS_SO_REUSE_LISTEN_SOCKET ( 11 ) /* When a listening socket gets connected, do not create a new one but re-use it */
|
||||
#define FREERTOS_SO_CLOSE_AFTER_SEND ( 12 ) /* As soon as the last byte has been transmitted, finalise the connection */
|
||||
#define FREERTOS_SO_WIN_PROPERTIES ( 13 ) /* Set all buffer and window properties in one call, parameter is pointer to WinProperties_t */
|
||||
#define FREERTOS_SO_SET_FULL_SIZE ( 14 ) /* Refuse to send packets smaller than MSS */
|
||||
|
||||
#define FREERTOS_SO_STOP_RX ( 15 ) /* Temporarily hold up reception, used by streaming client */
|
||||
|
||||
#if( ipconfigUDP_MAX_RX_PACKETS > 0 )
|
||||
#define FREERTOS_SO_UDP_MAX_RX_PACKETS ( 16 ) /* This option helps to limit the maximum number of packets a UDP socket will buffer */
|
||||
#endif
|
||||
|
||||
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
|
||||
#define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
|
||||
#endif
|
||||
|
||||
|
||||
#define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) /* For internal use only, but also part of an 8-bit bitwise value. */
|
||||
#define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) /* For internal use only, but also part of an 8-bit bitwise value. */
|
||||
|
||||
/* Values for flag for FreeRTOS_shutdown(). */
|
||||
#define FREERTOS_SHUT_RD ( 0 ) /* Not really at this moment, just for compatibility of the interface */
|
||||
#define FREERTOS_SHUT_WR ( 1 )
|
||||
#define FREERTOS_SHUT_RDWR ( 2 )
|
||||
|
||||
/* Values for flag for FreeRTOS_recv(). */
|
||||
#define FREERTOS_MSG_OOB ( 2 ) /* process out-of-band data */
|
||||
#define FREERTOS_MSG_PEEK ( 4 ) /* peek at incoming message */
|
||||
#define FREERTOS_MSG_DONTROUTE ( 8 ) /* send without using routing tables */
|
||||
#define FREERTOS_MSG_DONTWAIT ( 16 ) /* Can be used with recvfrom(), sendto(), recv(), and send(). */
|
||||
|
||||
typedef struct xWIN_PROPS {
|
||||
/* Properties of the Tx buffer and Tx window */
|
||||
int32_t lTxBufSize; /* Unit: bytes */
|
||||
int32_t lTxWinSize; /* Unit: MSS */
|
||||
|
||||
/* Properties of the Rx buffer and Rx window */
|
||||
int32_t lRxBufSize; /* Unit: bytes */
|
||||
int32_t lRxWinSize; /* Unit: MSS */
|
||||
} WinProperties_t;
|
||||
|
||||
/* For compatibility with the expected Berkeley sockets naming. */
|
||||
#define socklen_t uint32_t
|
||||
|
||||
/* For this limited implementation, only two members are required in the
|
||||
Berkeley style sockaddr structure. */
|
||||
struct freertos_sockaddr
|
||||
{
|
||||
/* _HT_ On 32- and 64-bit architectures, the addition of the two uint8_t
|
||||
fields doesn't make the structure bigger, due to alignment.
|
||||
The fields are inserted as a preparation for IPv6. */
|
||||
|
||||
/* sin_len and sin_family not used in the IPv4-only release. */
|
||||
uint8_t sin_len; /* length of this structure. */
|
||||
uint8_t sin_family; /* FREERTOS_AF_INET. */
|
||||
uint16_t sin_port;
|
||||
uint32_t sin_addr;
|
||||
};
|
||||
|
||||
#if ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN
|
||||
|
||||
#define FreeRTOS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \
|
||||
( ( ( ( uint32_t ) ( ucOctet3 ) ) << 24UL ) | \
|
||||
( ( ( uint32_t ) ( ucOctet2 ) ) << 16UL ) | \
|
||||
( ( ( uint32_t ) ( ucOctet1 ) ) << 8UL ) | \
|
||||
( ( uint32_t ) ( ucOctet0 ) ) )
|
||||
|
||||
#define FreeRTOS_inet_ntoa( ulIPAddress, pucBuffer ) \
|
||||
sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u", \
|
||||
( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ), \
|
||||
( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ), \
|
||||
( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ),\
|
||||
( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ) )
|
||||
|
||||
#else /* ipconfigBYTE_ORDER */
|
||||
|
||||
#define FreeRTOS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \
|
||||
( ( ( ( uint32_t ) ( ucOctet0 ) ) << 24UL ) | \
|
||||
( ( ( uint32_t ) ( ucOctet1 ) ) << 16UL ) | \
|
||||
( ( ( uint32_t ) ( ucOctet2 ) ) << 8UL ) | \
|
||||
( ( uint32_t ) ( ucOctet3 ) ) )
|
||||
|
||||
#define FreeRTOS_inet_ntoa( ulIPAddress, pucBuffer ) \
|
||||
sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u", \
|
||||
( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ), \
|
||||
( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ),\
|
||||
( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ), \
|
||||
( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ) )
|
||||
|
||||
#endif /* ipconfigBYTE_ORDER */
|
||||
|
||||
/* The socket type itself. */
|
||||
typedef void *Socket_t;
|
||||
|
||||
/* The SocketSet_t type is the equivalent to the fd_set type used by the
|
||||
Berkeley API. */
|
||||
typedef void *SocketSet_t;
|
||||
|
||||
/**
|
||||
* FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
|
||||
* FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html
|
||||
*/
|
||||
Socket_t FreeRTOS_socket( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol );
|
||||
int32_t FreeRTOS_recvfrom( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength );
|
||||
int32_t FreeRTOS_sendto( Socket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, BaseType_t xFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength );
|
||||
BaseType_t FreeRTOS_bind( Socket_t xSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength );
|
||||
|
||||
/* function to get the local address and IP port */
|
||||
size_t FreeRTOS_GetLocalAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress );
|
||||
|
||||
/* Made available when ipconfigETHERNET_DRIVER_FILTERS_PACKETS is set to 1. */
|
||||
BaseType_t xPortHasUDPSocket( uint16_t usPortNr );
|
||||
|
||||
#if ipconfigUSE_TCP == 1
|
||||
|
||||
BaseType_t FreeRTOS_connect( Socket_t xClientSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength );
|
||||
BaseType_t FreeRTOS_listen( Socket_t xSocket, BaseType_t xBacklog );
|
||||
BaseType_t FreeRTOS_recv( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags );
|
||||
BaseType_t FreeRTOS_send( Socket_t xSocket, const void *pvBuffer, size_t uxDataLength, BaseType_t xFlags );
|
||||
Socket_t FreeRTOS_accept( Socket_t xServerSocket, struct freertos_sockaddr *pxAddress, socklen_t *pxAddressLength );
|
||||
BaseType_t FreeRTOS_shutdown (Socket_t xSocket, BaseType_t xHow);
|
||||
|
||||
#if( ipconfigSUPPORT_SIGNALS != 0 )
|
||||
/* Send a signal to the task which is waiting for a given socket. */
|
||||
BaseType_t FreeRTOS_SignalSocket( Socket_t xSocket );
|
||||
|
||||
/* Send a signal to the task which reads from this socket (FromISR
|
||||
version). */
|
||||
BaseType_t FreeRTOS_SignalSocketFromISR( Socket_t xSocket, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
#endif /* ipconfigSUPPORT_SIGNALS */
|
||||
|
||||
/* Return the remote address and IP port. */
|
||||
BaseType_t FreeRTOS_GetRemoteAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress );
|
||||
|
||||
/* returns pdTRUE if TCP socket is connected */
|
||||
BaseType_t FreeRTOS_issocketconnected( Socket_t xSocket );
|
||||
|
||||
/* returns the actual size of MSS being used */
|
||||
BaseType_t FreeRTOS_mss( Socket_t xSocket );
|
||||
|
||||
/* for internal use only: return the connection status */
|
||||
BaseType_t FreeRTOS_connstatus( Socket_t xSocket );
|
||||
|
||||
/* Returns the number of bytes that may be added to txStream */
|
||||
BaseType_t FreeRTOS_maywrite( Socket_t xSocket );
|
||||
|
||||
/*
|
||||
* Two helper functions, mostly for testing
|
||||
* rx_size returns the number of bytes available in the Rx buffer
|
||||
* tx_space returns the free space in the Tx buffer
|
||||
*/
|
||||
BaseType_t FreeRTOS_rx_size( Socket_t xSocket );
|
||||
BaseType_t FreeRTOS_tx_space( Socket_t xSocket );
|
||||
BaseType_t FreeRTOS_tx_size( Socket_t xSocket );
|
||||
|
||||
/* Returns the number of outstanding bytes in txStream. */
|
||||
/* The function FreeRTOS_outstanding() was already implemented
|
||||
FreeRTOS_tx_size(). */
|
||||
#define FreeRTOS_outstanding( xSocket ) FreeRTOS_tx_size( xSocket )
|
||||
|
||||
/* Returns the number of bytes in the socket's rxStream. */
|
||||
/* The function FreeRTOS_recvcount() was already implemented
|
||||
FreeRTOS_rx_size(). */
|
||||
#define FreeRTOS_recvcount( xSocket ) FreeRTOS_rx_size( xSocket )
|
||||
|
||||
/*
|
||||
* For advanced applications only:
|
||||
* Get a direct pointer to the circular transmit buffer.
|
||||
* '*pxLength' will contain the number of bytes that may be written.
|
||||
*/
|
||||
uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength );
|
||||
|
||||
#endif /* ipconfigUSE_TCP */
|
||||
|
||||
/*
|
||||
* Connect / disconnect handler for a TCP socket
|
||||
* For example:
|
||||
* static void vMyConnectHandler (Socket_t xSocket, BaseType_t ulConnected)
|
||||
* {
|
||||
* }
|
||||
* F_TCP_UDP_Handler_t xHnd = { vMyConnectHandler };
|
||||
* FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_CONN_HANDLER, ( void * ) &xHnd, sizeof( xHnd ) );
|
||||
*/
|
||||
|
||||
typedef void (* FOnConnected_t )( Socket_t /* xSocket */, BaseType_t /* ulConnected */ );
|
||||
|
||||
/*
|
||||
* Reception handler for a TCP socket
|
||||
* A user-proved function will be called on reception of a message
|
||||
* If the handler returns a positive number, the messages will not be stored
|
||||
* For example:
|
||||
* static BaseType_t xOnTCPReceive( Socket_t xSocket, void * pData, size_t xLength )
|
||||
* {
|
||||
* // handle the message
|
||||
* return 1;
|
||||
* }
|
||||
* F_TCP_UDP_Handler_t xHand = { xOnTCPReceive };
|
||||
* FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_RECV_HANDLER, ( void * ) &xHand, sizeof( xHand ) );
|
||||
*/
|
||||
typedef BaseType_t (* FOnTCPReceive_t )( Socket_t /* xSocket */, void * /* pData */, size_t /* xLength */ );
|
||||
typedef void (* FOnTCPSent_t )( Socket_t /* xSocket */, size_t /* xLength */ );
|
||||
|
||||
/*
|
||||
* Reception handler for a UDP socket
|
||||
* A user-proved function will be called on reception of a message
|
||||
* If the handler returns a positive number, the messages will not be stored
|
||||
*/
|
||||
typedef BaseType_t (* FOnUDPReceive_t ) (Socket_t /* xSocket */, void * /* pData */, size_t /* xLength */,
|
||||
const struct freertos_sockaddr * /* pxFrom */, const struct freertos_sockaddr * /* pxDest */ );
|
||||
typedef void (* FOnUDPSent_t )( Socket_t /* xSocket */, size_t /* xLength */ );
|
||||
|
||||
|
||||
typedef union xTCP_UDP_HANDLER
|
||||
{
|
||||
FOnConnected_t pxOnTCPConnected; /* FREERTOS_SO_TCP_CONN_HANDLER */
|
||||
FOnTCPReceive_t pxOnTCPReceive; /* FREERTOS_SO_TCP_RECV_HANDLER */
|
||||
FOnTCPSent_t pxOnTCPSent; /* FREERTOS_SO_TCP_SENT_HANDLER */
|
||||
FOnUDPReceive_t pxOnUDPReceive; /* FREERTOS_SO_UDP_RECV_HANDLER */
|
||||
FOnUDPSent_t pxOnUDPSent; /* FREERTOS_SO_UDP_SENT_HANDLER */
|
||||
} F_TCP_UDP_Handler_t;
|
||||
|
||||
BaseType_t FreeRTOS_setsockopt( Socket_t xSocket, int32_t lLevel, int32_t lOptionName, const void *pvOptionValue, size_t xOptionLength );
|
||||
BaseType_t FreeRTOS_closesocket( Socket_t xSocket );
|
||||
uint32_t FreeRTOS_gethostbyname( const char *pcHostName );
|
||||
uint32_t FreeRTOS_inet_addr( const char * pcIPAddress );
|
||||
|
||||
/*
|
||||
* For the web server: borrow the circular Rx buffer for inspection
|
||||
* HTML driver wants to see if a sequence of 13/10/13/10 is available
|
||||
*/
|
||||
const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket );
|
||||
|
||||
void FreeRTOS_netstat( void );
|
||||
|
||||
#if ipconfigSUPPORT_SELECT_FUNCTION == 1
|
||||
|
||||
/* For FD_SET and FD_CLR, a combination of the following bits can be used: */
|
||||
|
||||
typedef enum eSELECT_EVENT {
|
||||
eSELECT_READ = 0x0001,
|
||||
eSELECT_WRITE = 0x0002,
|
||||
eSELECT_EXCEPT = 0x0004,
|
||||
eSELECT_INTR = 0x0008,
|
||||
eSELECT_ALL = 0x000F,
|
||||
/* Reserved for internal use: */
|
||||
eSELECT_CALL_IP = 0x0010,
|
||||
/* end */
|
||||
} eSelectEvent_t;
|
||||
|
||||
SocketSet_t FreeRTOS_CreateSocketSet( void );
|
||||
void FreeRTOS_DeleteSocketSet( SocketSet_t xSocketSet );
|
||||
void FreeRTOS_FD_SET( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xBitsToSet );
|
||||
void FreeRTOS_FD_CLR( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xBitsToClear );
|
||||
EventBits_t FreeRTOS_FD_ISSET( Socket_t xSocket, SocketSet_t xSocketSet );
|
||||
BaseType_t FreeRTOS_select( SocketSet_t xSocketSet, TickType_t xBlockTimeTicks );
|
||||
|
||||
#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_SOCKETS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
256
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
Executable file
256
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
Executable file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* FreeRTOS_Stream_Buffer.h
|
||||
*
|
||||
* A cicular character buffer
|
||||
* An implementation of a circular buffer without a length field
|
||||
* If LENGTH defines the size of the buffer, a maximum of (LENGT-1) bytes can be stored
|
||||
* In order to add or read data from the buffer, memcpy() will be called at most 2 times
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_STREAM_BUFFER_H
|
||||
#define FREERTOS_STREAM_BUFFER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct xSTREAM_BUFFER {
|
||||
volatile size_t uxTail; /* next item to read */
|
||||
volatile size_t uxMid; /* iterator within the valid items */
|
||||
volatile size_t uxHead; /* next position store a new item */
|
||||
volatile size_t uxFront; /* iterator within the free space */
|
||||
size_t LENGTH; /* const value: number of reserved elements */
|
||||
uint8_t ucArray[ sizeof( size_t ) ];
|
||||
} StreamBuffer_t;
|
||||
|
||||
static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer );
|
||||
static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
/* Make the circular buffer empty */
|
||||
pxBuffer->uxHead = 0u;
|
||||
pxBuffer->uxTail = 0u;
|
||||
pxBuffer->uxFront = 0u;
|
||||
pxBuffer->uxMid = 0u;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );
|
||||
static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )
|
||||
{
|
||||
/* Returns the space between uxLower and uxUpper, which equals to the distance minus 1 */
|
||||
size_t uxCount;
|
||||
|
||||
uxCount = pxBuffer->LENGTH + uxUpper - uxLower - 1u;
|
||||
if( uxCount >= pxBuffer->LENGTH )
|
||||
{
|
||||
uxCount -= pxBuffer->LENGTH;
|
||||
}
|
||||
|
||||
return uxCount;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );
|
||||
static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )
|
||||
{
|
||||
/* Returns the distance between uxLower and uxUpper */
|
||||
size_t uxCount;
|
||||
|
||||
uxCount = pxBuffer->LENGTH + uxUpper - uxLower;
|
||||
if ( uxCount >= pxBuffer->LENGTH )
|
||||
{
|
||||
uxCount -= pxBuffer->LENGTH;
|
||||
}
|
||||
|
||||
return uxCount;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer );
|
||||
static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
/* Returns the number of items which can still be added to uxHead
|
||||
before hitting on uxTail */
|
||||
size_t uxHead = pxBuffer->uxHead;
|
||||
size_t uxTail = pxBuffer->uxTail;
|
||||
|
||||
return uxStreamBufferSpace( pxBuffer, uxHead, uxTail );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer );
|
||||
static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
/* Distance between uxFront and uxTail
|
||||
or the number of items which can still be added to uxFront,
|
||||
before hitting on uxTail */
|
||||
|
||||
size_t uxFront = pxBuffer->uxFront;
|
||||
size_t uxTail = pxBuffer->uxTail;
|
||||
|
||||
return uxStreamBufferSpace( pxBuffer, uxFront, uxTail );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer );
|
||||
static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
/* Returns the number of items which can be read from uxTail
|
||||
before reaching uxHead */
|
||||
size_t uxHead = pxBuffer->uxHead;
|
||||
size_t uxTail = pxBuffer->uxTail;
|
||||
|
||||
return uxStreamBufferDistance( pxBuffer, uxTail, uxHead );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer );
|
||||
static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
/* Returns the distance between uxHead and uxMid */
|
||||
size_t uxHead = pxBuffer->uxHead;
|
||||
size_t uxMid = pxBuffer->uxMid;
|
||||
|
||||
return uxStreamBufferDistance( pxBuffer, uxMid, uxHead );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount );
|
||||
static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount )
|
||||
{
|
||||
/* Increment uxMid, but no further than uxHead */
|
||||
size_t uxSize = uxStreamBufferMidSpace( pxBuffer );
|
||||
|
||||
if( uxCount > uxSize )
|
||||
{
|
||||
uxCount = uxSize;
|
||||
}
|
||||
pxBuffer->uxMid += uxCount;
|
||||
if( pxBuffer->uxMid >= pxBuffer->LENGTH )
|
||||
{
|
||||
pxBuffer->uxMid -= pxBuffer->LENGTH;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer );
|
||||
static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* True if no item is available */
|
||||
if( pxBuffer->uxHead == pxBuffer->uxTail )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer );
|
||||
static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer )
|
||||
{
|
||||
/* True if the available space equals zero. */
|
||||
return ( BaseType_t ) ( uxStreamBufferGetSpace( pxBuffer ) == 0u );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );
|
||||
static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
size_t uxTail = pxBuffer->uxTail;
|
||||
|
||||
/* Returns true if ( uxLeft < uxRight ) */
|
||||
if( ( uxLeft < uxTail ) ^ ( uxRight < uxTail ) )
|
||||
{
|
||||
if( uxRight < uxTail )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( uxLeft <= uxRight )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
}
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData );
|
||||
static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData )
|
||||
{
|
||||
size_t uxNextTail = pxBuffer->uxTail;
|
||||
size_t uxSize = uxStreamBufferGetSize( pxBuffer );
|
||||
|
||||
*ppucData = pxBuffer->ucArray + uxNextTail;
|
||||
|
||||
return FreeRTOS_min_uint32( uxSize, pxBuffer->LENGTH - uxNextTail );
|
||||
}
|
||||
|
||||
/*
|
||||
* Add bytes to a stream buffer.
|
||||
*
|
||||
* pxBuffer - The buffer to which the bytes will be added.
|
||||
* uxOffset - If uxOffset > 0, data will be written at an offset from uxHead
|
||||
* while uxHead will not be moved yet.
|
||||
* pucData - A pointer to the data to be added.
|
||||
* uxCount - The number of bytes to add.
|
||||
*/
|
||||
size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount );
|
||||
|
||||
/*
|
||||
* Read bytes from a stream buffer.
|
||||
*
|
||||
* pxBuffer - The buffer from which the bytes will be read.
|
||||
* uxOffset - Can be used to read data located at a certain offset from 'uxTail'.
|
||||
* pucData - A pointer to the buffer into which data will be read.
|
||||
* uxMaxCount - The number of bytes to read.
|
||||
* xPeek - If set to pdTRUE the data will remain in the buffer.
|
||||
*/
|
||||
size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* !defined( FREERTOS_STREAM_BUFFER_H ) */
|
80
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h
Executable file
80
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h
Executable file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TCP_IP_H
|
||||
#define FREERTOS_TCP_IP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||
|
||||
typedef enum eTCP_STATE {
|
||||
/* Comments about the TCP states are borrowed from the very useful
|
||||
* Wiki page:
|
||||
* http://en.wikipedia.org/wiki/Transmission_Control_Protocol */
|
||||
eCLOSED = 0u, /* 0 (server + client) no connection state at all. */
|
||||
eTCP_LISTEN, /* 1 (server) waiting for a connection request
|
||||
from any remote TCP and port. */
|
||||
eCONNECT_SYN, /* 2 (client) internal state: socket wants to send
|
||||
a connect */
|
||||
eSYN_FIRST, /* 3 (server) Just created, must ACK the SYN request. */
|
||||
eSYN_RECEIVED, /* 4 (server) waiting for a confirming connection request
|
||||
acknowledgement after having both received and sent a connection request. */
|
||||
eESTABLISHED, /* 5 (server + client) an open connection, data received can be
|
||||
delivered to the user. The normal state for the data transfer phase of the connection. */
|
||||
eFIN_WAIT_1, /* 6 (server + client) waiting for a connection termination request from the remote TCP,
|
||||
or an acknowledgement of the connection termination request previously sent. */
|
||||
eFIN_WAIT_2, /* 7 (server + client) waiting for a connection termination request from the remote TCP. */
|
||||
eCLOSE_WAIT, /* 8 (server + client) waiting for a connection termination request from the local user. */
|
||||
eCLOSING, /* (server + client) waiting for a connection termination request acknowledgement from the remote TCP. */
|
||||
eLAST_ACK, /* 9 (server + client) waiting for an acknowledgement of the connection termination request
|
||||
previously sent to the remote TCP
|
||||
(which includes an acknowledgement of its connection termination request). */
|
||||
eTIME_WAIT, /* 10 (either server or client) waiting for enough time to pass to be sure the remote TCP received the
|
||||
acknowledgement of its connection termination request. [According to RFC 793 a connection can
|
||||
stay in TIME-WAIT for a maximum of four minutes known as a MSL (maximum segment lifetime).] */
|
||||
} eIPTCPState_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_TCP_IP_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
210
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h
Executable file
210
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h
Executable file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* FreeRTOS_TCP_WIN.c
|
||||
* Module which handles the TCP windowing schemes for FreeRTOS-PLUS-TCP
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TCP_WIN_H
|
||||
#define FREERTOS_TCP_WIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern BaseType_t xTCPWindowLoggingLevel;
|
||||
|
||||
typedef struct xTCPTimer
|
||||
{
|
||||
uint32_t ulBorn;
|
||||
} TCPTimer_t;
|
||||
|
||||
typedef struct xTCP_SEGMENT
|
||||
{
|
||||
uint32_t ulSequenceNumber; /* The sequence number of the first byte in this packet */
|
||||
int32_t lMaxLength; /* Maximum space, number of bytes which can be stored in this segment */
|
||||
int32_t lDataLength; /* Actual number of bytes */
|
||||
int32_t lStreamPos; /* reference to the [t|r]xStream of the socket */
|
||||
TCPTimer_t xTransmitTimer; /* saves a timestamp at the moment this segment gets transmitted (TX only) */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t
|
||||
ucTransmitCount : 8,/* Number of times the segment has been transmitted, used to calculate the RTT */
|
||||
ucDupAckCount : 8, /* Counts the number of times that a higher segment was ACK'd. After 3 times a Fast Retransmission takes place */
|
||||
bOutstanding : 1, /* It the peer's turn, we're just waiting for an ACK */
|
||||
bAcked : 1, /* This segment has been acknowledged */
|
||||
bIsForRx : 1; /* pdTRUE if segment is used for reception */
|
||||
} bits;
|
||||
uint32_t ulFlags;
|
||||
} u;
|
||||
#if( ipconfigUSE_TCP_WIN != 0 )
|
||||
struct xLIST_ITEM xQueueItem; /* TX only: segments can be linked in one of three queues: xPriorityQueue, xTxQueue, and xWaitQueue */
|
||||
struct xLIST_ITEM xListItem; /* With this item the segment can be connected to a list, depending on who is owning it */
|
||||
#endif
|
||||
} TCPSegment_t;
|
||||
|
||||
typedef struct xTCP_WINSIZE
|
||||
{
|
||||
uint32_t ulRxWindowLength;
|
||||
uint32_t ulTxWindowLength;
|
||||
} TCPWinSize_t;
|
||||
|
||||
/*
|
||||
* If TCP time-stamps are being used, they will occupy 12 bytes in
|
||||
* each packet, and thus the message space will become smaller
|
||||
*/
|
||||
/* Keep this as a multiple of 4 */
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
#define ipSIZE_TCP_OPTIONS 16u
|
||||
#else
|
||||
#define ipSIZE_TCP_OPTIONS 12u
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Every TCP connection owns a TCP window for the administration of all packets
|
||||
* It owns two sets of segment descriptors, incoming and outgoing
|
||||
*/
|
||||
typedef struct xTCP_WINDOW
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t
|
||||
bHasInit : 1, /* The window structure has been initialised */
|
||||
bSendFullSize : 1, /* May only send packets with a size equal to MSS (for optimisation) */
|
||||
bTimeStamps : 1; /* Socket is supposed to use TCP time-stamps. This depends on the */
|
||||
} bits; /* party which opens the connection */
|
||||
uint32_t ulFlags;
|
||||
} u;
|
||||
TCPWinSize_t xSize;
|
||||
struct
|
||||
{
|
||||
uint32_t ulFirstSequenceNumber; /* Logging & debug: the first segment received/sent in this connection
|
||||
* for Tx: initial send sequence number (ISS)
|
||||
* for Rx: initial receive sequence number (IRS) */
|
||||
uint32_t ulCurrentSequenceNumber;/* Tx/Rx: the oldest sequence number not yet confirmed, also SND.UNA / RCV.NXT
|
||||
* In other words: the sequence number of the left side of the sliding window */
|
||||
uint32_t ulFINSequenceNumber; /* The sequence number which carried the FIN flag */
|
||||
uint32_t ulHighestSequenceNumber;/* Sequence number of the right-most byte + 1 */
|
||||
} rx, tx;
|
||||
uint32_t ulOurSequenceNumber; /* The SEQ number we're sending out */
|
||||
uint32_t ulUserDataLength; /* Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
|
||||
uint32_t ulNextTxSequenceNumber; /* The sequence number given to the next byte to be added for transmission */
|
||||
int32_t lSRTT; /* Smoothed Round Trip Time, it may increment quickly and it decrements slower */
|
||||
uint8_t ucOptionLength; /* Number of valid bytes in ulOptionsData[] */
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
List_t xPriorityQueue; /* Priority queue: segments which must be sent immediately */
|
||||
List_t xTxQueue; /* Transmit queue: segments queued for transmission */
|
||||
List_t xWaitQueue; /* Waiting queue: outstanding segments */
|
||||
TCPSegment_t *pxHeadSegment; /* points to a segment which has not been transmitted and it's size is still growing (user data being added) */
|
||||
uint32_t ulOptionsData[ipSIZE_TCP_OPTIONS/sizeof(uint32_t)]; /* Contains the options we send out */
|
||||
List_t xTxSegments; /* A linked list of all transmission segments, sorted on sequence number */
|
||||
List_t xRxSegments; /* A linked list of reception segments, order depends on sequence of arrival */
|
||||
#else
|
||||
/* For tiny TCP, there is only 1 outstanding TX segment */
|
||||
TCPSegment_t xTxSegment; /* Priority queue */
|
||||
#endif
|
||||
uint16_t usOurPortNumber; /* Mostly for debugging/logging: our TCP port number */
|
||||
uint16_t usPeerPortNumber; /* debugging/logging: the peer's TCP port number */
|
||||
uint16_t usMSS; /* Current accepted MSS */
|
||||
uint16_t usMSSInit; /* MSS as configured by the socket owner */
|
||||
} TCPWindow_t;
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
*
|
||||
* Creation and destruction
|
||||
*
|
||||
*=============================================================================*/
|
||||
|
||||
/* Create and initialize a window */
|
||||
void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
|
||||
uint32_t ulTxWindowLength, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
|
||||
|
||||
/* Destroy a window (always returns NULL)
|
||||
* It will free some resources: a collection of segments */
|
||||
void vTCPWindowDestroy( TCPWindow_t *pxWindow );
|
||||
|
||||
/* Initialize a window */
|
||||
void vTCPWindowInit( TCPWindow_t *pxWindow, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
|
||||
|
||||
/*=============================================================================
|
||||
*
|
||||
* Rx functions
|
||||
*
|
||||
*=============================================================================*/
|
||||
|
||||
/* if true may be passed directly to user (segment expected and window is empty)
|
||||
* But pxWindow->ackno should always be used to set "BUF->ackno" */
|
||||
int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace );
|
||||
|
||||
/* When lTCPWindowRxCheck returned false, please call store for this unexpected data */
|
||||
BaseType_t xTCPWindowRxStore( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength );
|
||||
|
||||
/* This function will be called as soon as a FIN is received. It will return true
|
||||
* if there are no 'open' reception segments */
|
||||
BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow );
|
||||
|
||||
/* _HT_ Temporary function for testing/debugging
|
||||
* Not used at this moment */
|
||||
void vTCPWinShowSegments( TCPWindow_t *pxWindow, BaseType_t bForRx );
|
||||
|
||||
/*=============================================================================
|
||||
*
|
||||
* Tx functions
|
||||
*
|
||||
*=============================================================================*/
|
||||
|
||||
/* Adds data to the Tx-window */
|
||||
int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax );
|
||||
|
||||
/* Check data to be sent and calculate the time period we may sleep */
|
||||
BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay );
|
||||
|
||||
/* See if anything is left to be sent
|
||||
* Function will be called when a FIN has been received. Only when the TX window is clean,
|
||||
* it will return pdTRUE */
|
||||
BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow );
|
||||
|
||||
/* Fetches data to be sent.
|
||||
* apPos will point to a location with the circular data buffer: txStream */
|
||||
uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition );
|
||||
|
||||
/* Receive a normal ACK */
|
||||
uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber );
|
||||
|
||||
/* Receive a SACK option */
|
||||
uint32_t ulTCPWindowTxSack( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_TCP_WIN_H */
|
56
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h
Executable file
56
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h
Executable file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_UDP_IP_H
|
||||
#define FREERTOS_UDP_IP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Application level configuration options. */
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "FreeRTOSIPConfigDefaults.h"
|
||||
#include "IPTraceMacroDefaults.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_UDP_IP_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
90
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h
Executable file
90
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h
Executable file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_ERRNO_TCP
|
||||
#define FREERTOS_ERRNO_TCP
|
||||
|
||||
/* The following definitions will be included in the core FreeRTOS code in
|
||||
future versions of FreeRTOS - hence the 'pd' (ProjDefs) prefix - at which time
|
||||
this file will be removed. */
|
||||
|
||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
|
||||
/* For future compatibility (see comment above), check the definitions have not
|
||||
already been made. */
|
||||
#ifndef pdFREERTOS_ERRNO_NONE
|
||||
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
||||
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
||||
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
||||
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
|
||||
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
|
||||
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
|
||||
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
|
||||
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
|
||||
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
|
||||
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
|
||||
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
|
||||
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
|
||||
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
|
||||
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
|
||||
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
|
||||
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
|
||||
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
|
||||
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
|
||||
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
|
||||
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
|
||||
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
|
||||
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
|
||||
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
||||
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
|
||||
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
|
||||
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
||||
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
||||
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
|
||||
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
|
||||
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
|
||||
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
|
||||
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
|
||||
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
|
||||
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
|
||||
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
|
||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||
|
||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||
#define pdFREERTOS_BIG_ENDIAN 1
|
||||
|
||||
#endif /* pdFREERTOS_ERRNO_NONE */
|
||||
|
||||
#endif /* FREERTOS_ERRNO_TCP */
|
||||
|
||||
|
||||
|
193
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h
Executable file
193
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h
Executable file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* This file provides default (empty) implementations for any IP trace macros
|
||||
that are not defined by the user. See
|
||||
http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Trace.html */
|
||||
|
||||
#ifndef UDP_TRACE_MACRO_DEFAULTS_H
|
||||
#define UDP_TRACE_MACRO_DEFAULTS_H
|
||||
|
||||
#ifndef iptraceNETWORK_DOWN
|
||||
#define iptraceNETWORK_DOWN()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNETWORK_BUFFER_RELEASED
|
||||
#define iptraceNETWORK_BUFFER_RELEASED( pxBufferAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNETWORK_BUFFER_OBTAINED
|
||||
#define iptraceNETWORK_BUFFER_OBTAINED( pxBufferAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR
|
||||
#define iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxBufferAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER
|
||||
#define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR
|
||||
#define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceCREATING_ARP_REQUEST
|
||||
#define iptraceCREATING_ARP_REQUEST( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceARP_TABLE_ENTRY_WILL_EXPIRE
|
||||
#define iptraceARP_TABLE_ENTRY_WILL_EXPIRE( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceARP_TABLE_ENTRY_EXPIRED
|
||||
#define iptraceARP_TABLE_ENTRY_EXPIRED( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceARP_TABLE_ENTRY_CREATED
|
||||
#define iptraceARP_TABLE_ENTRY_CREATED( ulIPAddress, ucMACAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDING_UDP_PACKET
|
||||
#define iptraceSENDING_UDP_PACKET( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptracePACKET_DROPPED_TO_GENERATE_ARP
|
||||
#define iptracePACKET_DROPPED_TO_GENERATE_ARP( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceICMP_PACKET_RECEIVED
|
||||
#define iptraceICMP_PACKET_RECEIVED()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDING_PING_REPLY
|
||||
#define iptraceSENDING_PING_REPLY( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef traceARP_PACKET_RECEIVED
|
||||
#define traceARP_PACKET_RECEIVED()
|
||||
#endif
|
||||
|
||||
#ifndef iptracePROCESSING_RECEIVED_ARP_REPLY
|
||||
#define iptracePROCESSING_RECEIVED_ARP_REPLY( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDING_ARP_REPLY
|
||||
#define iptraceSENDING_ARP_REPLY( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceFAILED_TO_CREATE_SOCKET
|
||||
#define iptraceFAILED_TO_CREATE_SOCKET()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceFAILED_TO_CREATE_EVENT_GROUP
|
||||
#define iptraceFAILED_TO_CREATE_EVENT_GROUP()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceRECVFROM_DISCARDING_BYTES
|
||||
#define iptraceRECVFROM_DISCARDING_BYTES( xNumberOfBytesDiscarded )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceETHERNET_RX_EVENT_LOST
|
||||
#define iptraceETHERNET_RX_EVENT_LOST()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSTACK_TX_EVENT_LOST
|
||||
#define iptraceSTACK_TX_EVENT_LOST( xEvent )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNETWORK_EVENT_RECEIVED
|
||||
#define iptraceNETWORK_EVENT_RECEIVED( eEvent )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceBIND_FAILED
|
||||
#define iptraceBIND_FAILED( xSocket, usPort )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS
|
||||
#define iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS( ulIPAddress )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDING_DHCP_DISCOVER
|
||||
#define iptraceSENDING_DHCP_DISCOVER()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDING_DHCP_REQUEST
|
||||
#define iptraceSENDING_DHCP_REQUEST()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceDHCP_SUCCEDEED
|
||||
#define iptraceDHCP_SUCCEDEED( address )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNETWORK_INTERFACE_TRANSMIT
|
||||
#define iptraceNETWORK_INTERFACE_TRANSMIT()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNETWORK_INTERFACE_RECEIVE
|
||||
#define iptraceNETWORK_INTERFACE_RECEIVE()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDING_DNS_REQUEST
|
||||
#define iptraceSENDING_DNS_REQUEST()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceWAITING_FOR_TX_DMA_DESCRIPTOR
|
||||
#define iptraceWAITING_FOR_TX_DMA_DESCRIPTOR()
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS
|
||||
#define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS 0
|
||||
#endif
|
||||
|
||||
#ifndef iptraceFAILED_TO_NOTIFY_SELECT_GROUP
|
||||
#define iptraceFAILED_TO_NOTIFY_SELECT_GROUP( xSocket )
|
||||
#endif
|
||||
|
||||
#ifndef pvPortMallocSocket
|
||||
#define pvPortMallocSocket(xSize) pvPortMalloc( ( xSize ) )
|
||||
#endif
|
||||
|
||||
#ifndef iptraceRECVFROM_TIMEOUT
|
||||
#define iptraceRECVFROM_TIMEOUT()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceRECVFROM_INTERRUPTED
|
||||
#define iptraceRECVFROM_INTERRUPTED()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceNO_BUFFER_FOR_SENDTO
|
||||
#define iptraceNO_BUFFER_FOR_SENDTO()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDTO_SOCKET_NOT_BOUND
|
||||
#define iptraceSENDTO_SOCKET_NOT_BOUND()
|
||||
#endif
|
||||
|
||||
#ifndef iptraceSENDTO_DATA_TOO_LONG
|
||||
#define iptraceSENDTO_DATA_TOO_LONG()
|
||||
#endif
|
||||
|
||||
#endif /* UDP_TRACE_MACRO_DEFAULTS_H */
|
70
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h
Executable file
70
FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h
Executable file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V2.0.7
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef NETWORK_BUFFER_MANAGEMENT_H
|
||||
#define NETWORK_BUFFER_MANAGEMENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* NOTE PUBLIC API FUNCTIONS. */
|
||||
BaseType_t xNetworkBuffersInitialise( void );
|
||||
NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks );
|
||||
NetworkBufferDescriptor_t *pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes );
|
||||
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
||||
BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
||||
uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes );
|
||||
void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer );
|
||||
|
||||
/* Get the current number of free network buffers. */
|
||||
UBaseType_t uxGetNumberOfFreeNetworkBuffers( void );
|
||||
|
||||
/* Get the lowest number of free network buffers. */
|
||||
UBaseType_t uxGetMinimumFreeNetworkBuffers( void );
|
||||
|
||||
/* Copy a network buffer into a bigger buffer. */
|
||||
NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
|
||||
BaseType_t xNewLength);
|
||||
|
||||
/* Increase the size of a Network Buffer.
|
||||
In case BufferAllocation_2.c is used, the new space must be allocated. */
|
||||
NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
|
||||
size_t xNewSizeBytes );
|
||||
|
||||
#if ipconfigTCP_IP_SANITY
|
||||
/*
|
||||
* Check if an address is a valid pointer to a network descriptor
|
||||
* by looking it up in the array of network descriptors
|
||||
*/
|
||||
UBaseType_t bIsValidNetworkDescriptor (const NetworkBufferDescriptor_t * pxDesc);
|
||||
BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* NETWORK_BUFFER_MANAGEMENT_H */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user