POSIX code/demo update.

This was the version we loaded to freertos.org before 2019 Op1 meeting.
This version of the code has:
- updated POSIX internal data structure.
- updated util functions.
- new atomic.h
- POSIX code optimization with atomic.

This version also:
- fixed pthread_cond_timedwait() thread count underflow. https://sourceforge.net/p/freertos/bugs/197/
- pthread_cond_timedwait() mutex release and count semaphore take is not "atomic" in our implementation.
This commit is contained in:
Yuhui Zheng 2019-11-20 11:38:08 -08:00
parent 7fc9c915eb
commit 3a337a03c6
1189 changed files with 39244 additions and 305595 deletions

View File

@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2050
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOS_POSIX_Demo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -19,4 +19,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {18112148-F9F0-43E0-B713-B146289BDEF3}
EndGlobalSection
EndGlobal

View File

@ -13,7 +13,6 @@
<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">
@ -132,7 +131,6 @@
</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" />

View File

@ -90,9 +90,6 @@
<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>

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -35,7 +35,7 @@
/* FreeRTOS+POSIX platform-specific configuration headers. */
#include "FreeRTOS_POSIX_portable.h"
#include "portable/FreeRTOS_POSIX_portable_default.h"
#include "FreeRTOS_POSIX_portable_default.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -32,64 +32,98 @@
*/
/* Amazon FreeRTOS includes. */
#include "aws_doubly_linked_list.h"
#include "iot_doubly_linked_list.h"
/**
* @brief Mutex attribute object.
*/
typedef struct pthread_mutexattr_internal
{
int iType; /**< Mutex type. */
} pthread_mutexattr_internal_t;
#if posixconfigENABLE_PTHREAD_MUTEXATTR_T == 1
typedef struct pthread_mutexattr_internal
{
int iType; /**< Mutex type. */
} pthread_mutexattr_internal_t;
#endif
#if posixconfigENABLE_PTHREAD_MUTEX_T == 1
/**
* @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;
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 } \
} \
) \
#define FREERTOS_POSIX_MUTEX_INITIALIZER \
( ( ( pthread_mutex_internal_t ) \
{ \
.xIsInitialized = pdFALSE, \
.xMutex = { { 0 } }, \
.xTaskOwner = NULL, \
.xAttr = { .iType = 0 } \
} \
) \
)
#endif /* if posixconfigENABLE_PTHREAD_MUTEX_T == 1 */
#if posixconfigENABLE_PTHREAD_COND_T == 1
/**
* @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;
typedef struct pthread_cond_internal
{
BaseType_t xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */
StaticSemaphore_t xCondWaitSemaphore; /**< Threads block on this semaphore in pthread_cond_wait. */
unsigned 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 \
} \
) \
#define FREERTOS_POSIX_COND_INITIALIZER \
( ( ( pthread_cond_internal_t ) \
{ \
.xIsInitialized = pdFALSE, \
.xCondWaitSemaphore = { { 0 } }, \
.iWaitingThreads = 0 \
} \
) \
)
#endif /* if posixconfigENABLE_PTHREAD_COND_T == 1 */
#if posixconfigENABLE_SEM_T == 1
/**
* @brief Semaphore type.
*/
typedef struct
{
StaticSemaphore_t xSemaphore; /**< FreeRTOS semaphore. */
int value; /**< POSIX semaphore count. */
} sem_internal_t;
#endif /* if posixconfigENABLE_SEM_T == 1 */
#if posixconfigENABLE_PTHREAD_BARRIER_T == 1
/**
* @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 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;
#endif /* if posixconfigENABLE_PTHREAD_BARRIER_T == 1 */
#endif /* _FREERTOS_POSIX_INTERNAL_H_ */

View File

@ -0,0 +1,81 @@
/*
* Amazon FreeRTOS POSIX V1.1.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_TYPES_H_
#define _FREERTOS_POSIX_INTERNAL_TYPES_H_
#include "FreeRTOS_POSIX_internal.h"
/*
* sys/types.h defines a POSIX type when posixconfigENABLE_PTHREAD_<TYPE>_T
* is not defined AND when posixconfigENABLE_PTHREAD_<TYPE>_T is set to 1.
* FreeRTOS_POSIX_internal.h defines internal type ONLY when
* posixconfigENABLE_PTHREAD_<TYPE>_T is set to 1.
* #else part below is to have a type defined, so the code compiles, when
* posixconfigENABLE_PTHREAD_<TYPE>_T is not defined.
*/
#if posixconfigENABLE_PTHREAD_MUTEX_T == 1
typedef pthread_mutex_internal_t PthreadMutexType_t;
#else
typedef void * PthreadMutexType_t;
#endif
#if posixconfigENABLE_PTHREAD_COND_T == 1
typedef pthread_cond_internal_t PthreadCondType_t;
#else
typedef void * PthreadCondType_t;
#endif
#if posixconfigENABLE_SEM_T == 1
typedef sem_internal_t PosixSemType_t;
#else
typedef void * PosixSemType_t;
#endif
#if posixconfigENABLE_PTHREAD_MUTEXATTR_T == 1
typedef struct pthread_mutexattr
{
uint32_t ulpthreadMutexAttrStorage;
} PthreadMutexAttrType_t;
#else
typedef void * PthreadMutexAttrType_t;
#endif
#if posixconfigENABLE_PTHREAD_ATTR_T == 1
typedef struct pthread_attr
{
uint32_t ulpthreadAttrStorage;
} PthreadAttrType_t;
#else
typedef void * PthreadAttrType_t;
#endif
#if posixconfigENABLE_PTHREAD_BARRIER_T == 1
typedef pthread_barrier_internal_t PthreadBarrierType_t;
#else
typedef void * PthreadBarrierType_t;
#endif
#endif /* _FREERTOS_POSIX_INTERNAL_TYPES_H_ */

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -32,21 +32,25 @@
#define _FREERTOS_POSIX_PORTABLE_DEFAULT_H_
/**
* @brief The FreeRTOS task name given to pthreads.
* @name The FreeRTOS task name given to pthreads.
*/
/**@{ */
#ifndef posixconfigPTHREAD_TASK_NAME
#define posixconfigPTHREAD_TASK_NAME "pthread"
#define posixconfigPTHREAD_TASK_NAME "pthread" /**< Task name. */
#endif
/**@} */
/**
* @brief the FreeRTOS timer name given to POSIX timers.
* @name the FreeRTOS timer name given to POSIX timers.
*/
/**@{ */
#ifndef posixconfigTIMER_NAME
#define posixconfigTIMER_NAME "timer"
#define posixconfigTIMER_NAME "timer" /**< Timer name. */
#endif
/**@} */
/**
* @defgroup Defaults for POSIX message queue implementation.
* @name Defaults for POSIX message queue implementation.
*/
/**@{ */
#ifndef posixconfigMQ_MAX_MESSAGES
@ -59,7 +63,7 @@
/**@} */
/**
* @defgroup POSIX implementation-dependent constants usually defined in limits.h.
* @name POSIX implementation-dependent constants usually defined in limits.h.
*
* They are defined here to provide portability between platforms.
*/
@ -71,12 +75,12 @@
#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. */
#define SEM_VALUE_MAX 0x7FFFU /**< Maximum value of a sem_t. */
#endif
/**@} */
/**
* @defgroup Enable typedefs of POSIX types.
* @name 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.
@ -130,8 +134,11 @@
#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 */
#ifndef posixconfigENABLE_SEM_T
#define posixconfigENABLE_SEM_T 1 /**< struct sem_t in semaphore.h */
#endif
#ifndef posixconfigENABLE_PTHREAD_BARRIER_T
#define posixconfigENABLE_PTHREAD_BARRIER_T 1 /**< pthread_barrier_t in sys/types.h */
#endif
/**@} */

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS+POSIX V1.0.4
* 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
@ -42,12 +42,19 @@
#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. */
/* ESP-IDF already provides the header sched.h. Exclude FreeRTOS+POSIX sched.h by
* defining its double inclusion guard. */
#define _FREERTOS_POSIX_SCHED_H_
/* Use the FreeRTOS+POSIX time.h header instead of the ESP-IDF time.h. Disable
* ESP-IDF time.h by defining its double inclusion guard. */
#define _TIME_H_
/* Disable the timer_t type defined by ESP-IDF. */
#define __timer_t_defined
#include <sys/types.h>
#endif /* _FREERTOS_POSIX_PORTABLE_H_ */

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.1
* Amazon FreeRTOS+POSIX V1.0.4
* 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

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS+POSIX V1.0.4
* 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

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS+POSIX V1.0.4
* 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

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS+POSIX V1.0.4
* 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

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS+POSIX V1.0.4
* 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

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -31,7 +31,6 @@
/* C standard library includes. */
#include <stddef.h>
#include <string.h>
#include <stdio.h>
/* FreeRTOS+POSIX includes. */
#include "FreeRTOS_POSIX.h"
@ -39,13 +38,20 @@
#include "FreeRTOS_POSIX/time.h"
#include "FreeRTOS_POSIX/utils.h"
/* Declaration of snprintf. The header stdio.h is not included because it
* includes conflicting symbols on some platforms. */
extern int snprintf( char * s,
size_t n,
const char * format,
... );
/*-----------------------------------------------------------*/
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() );
/* This function is currently unsupported. It will always return -1. */
return ( clock_t ) -1;
}
/*-----------------------------------------------------------*/
@ -57,6 +63,7 @@ int clock_getcpuclockid( pid_t pid,
( void ) pid;
( void ) clock_id;
/* This function is currently unsupported. It will always return EPERM. */
return EPERM;
}
@ -84,7 +91,6 @@ 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
@ -94,24 +100,21 @@ int clock_gettime( clockid_t clock_id,
/* 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 );
/* 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 );
/* 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;
/* Add the current tick count. */
ullTickCount += xCurrentTime.xTimeOnEntering;
/* Convert ullTickCount to timespec. */
UTILS_NanosecondsToTimespec( ( int64_t ) ullTickCount * NANOSECONDS_PER_TICK, tp );
}
/* Convert ullTickCount to timespec. */
UTILS_NanosecondsToTimespec( ( int64_t ) ullTickCount * NANOSECONDS_PER_TICK, tp );
return iStatus;
return 0;
}
/*-----------------------------------------------------------*/
@ -123,6 +126,7 @@ int clock_nanosleep( clockid_t clock_id,
{
int iStatus = 0;
TickType_t xSleepTime = 0;
struct timespec xCurrentTime = { 0 };
/* Silence warnings about unused parameters. */
( void ) clock_id;
@ -135,13 +139,25 @@ int clock_nanosleep( clockid_t clock_id,
iStatus = EINVAL;
}
/* Get current time */
if( ( iStatus == 0 ) && ( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 ) )
{
iStatus = EINVAL;
}
if( iStatus == 0 )
{
/* Check for absolute time sleep. */
if( ( flags & TIMER_ABSTIME ) == TIMER_ABSTIME )
{
/* Get current time */
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
{
iStatus = EINVAL;
}
/* Get number of ticks until absolute time. */
if( UTILS_AbsoluteTimespecToTicks( rqtp, &xSleepTime ) == 0 )
if( ( iStatus == 0 ) && ( UTILS_AbsoluteTimespecToDeltaTicks( rqtp, &xCurrentTime, &xSleepTime ) == 0 ) )
{
/* Delay until absolute time if vTaskDelayUntil is available. */
#if ( INCLUDE_vTaskDelayUntil == 1 )
@ -193,32 +209,6 @@ int clock_settime( clockid_t clock_id,
/*-----------------------------------------------------------*/
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 )
{
@ -248,44 +238,3 @@ int nanosleep( const struct timespec * rqtp,
}
/*-----------------------------------------------------------*/
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;
}
/*-----------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -142,7 +142,7 @@ static BaseType_t prvValidateQueueName( const char * const pcName,
/**
* @brief Guards access to the list of message queues.
*/
static StaticSemaphore_t xQueueListMutex = { { 0 } };
static StaticSemaphore_t xQueueListMutex = { { 0 }, .u = { 0 } };
/**
* @brief Head of the linked list of queues.
@ -172,15 +172,23 @@ static int prvCalculateTickTimeout( long lMessageQueueFlags,
}
else
{
struct timespec xCurrentTime = { 0 };
/* Check that the given timespec is valid. */
if( UTILS_ValidateTimespec( pxAbsoluteTimeout ) == false )
{
iStatus = EINVAL;
}
/* Get current time */
if( ( iStatus == 0 ) && ( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 ) )
{
iStatus = EINVAL;
}
/* Convert absolute timespec to ticks. */
if( ( iStatus == 0 ) &&
( UTILS_AbsoluteTimespecToTicks( pxAbsoluteTimeout, pxTimeoutTicks ) != 0 ) )
( UTILS_AbsoluteTimespecToDeltaTicks( pxAbsoluteTimeout, &xCurrentTime, pxTimeoutTicks ) != 0 ) )
{
iStatus = ETIMEDOUT;
}
@ -404,7 +412,7 @@ int mq_close( mqd_t mqdes )
if( prvFindQueueInList( NULL, NULL, mqdes ) == pdTRUE )
{
/* Decrement the number of open descriptors. */
if(pxMessageQueue->xOpenDescriptors > 0)
if( pxMessageQueue->xOpenDescriptors > 0 )
{
pxMessageQueue->xOpenDescriptors--;
}
@ -494,7 +502,7 @@ mqd_t mq_open( const char * name,
/* Default mq_attr. */
struct mq_attr xQueueCreationAttr =
{
.mq_flags = 0,
.mq_flags = 0,
.mq_maxmsg = posixconfigMQ_MAX_MESSAGES,
.mq_msgsize = posixconfigMQ_MAX_SIZE,
.mq_curmsgs = 0
@ -514,7 +522,7 @@ mqd_t mq_open( const char * name,
xMessageQueue = ( mqd_t ) -1;
}
/* Check attributes, if O_CREATE is specified and attr is given. */
/* Check attributes, if given. */
if( xMessageQueue == NULL )
{
if( ( oflag & O_CREAT ) && ( attr != NULL ) && ( ( attr->mq_maxmsg <= 0 ) || ( attr->mq_msgsize <= 0 ) ) )

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -30,6 +30,7 @@
/* C standard library includes. */
#include <stddef.h>
#include <string.h>
/* FreeRTOS+POSIX includes. */
#include "FreeRTOS_POSIX.h"
@ -41,11 +42,16 @@
*/
typedef struct pthread_attr_internal
{
size_t xStackSize; /**< Stack size. */
int iDetachState; /**< Detach state: joinable or detached. */
struct sched_param xSchedParam; /**< Scheduler parameters. */
uint16_t usStackSize; /**< Stack size. */
uint16_t usSchedPriorityDetachState; /**< Schedule priority 15 bits (LSB) Detach state: 1 bits (MSB) */
} pthread_attr_internal_t;
#define pthreadDETACH_STATE_MASK 0x8000
#define pthreadSCHED_PRIORITY_MASK 0x7FFF
#define pthreadDETACH_STATE_SHIFT 15
#define pthreadGET_SCHED_PRIORITY( var ) ( ( var ) & ( pthreadSCHED_PRIORITY_MASK ) )
#define pthreadIS_JOINABLE( var ) ( ( ( var ) & ( pthreadDETACH_STATE_MASK ) ) == pthreadDETACH_STATE_MASK )
/**
* @brief Thread object.
*/
@ -85,9 +91,8 @@ static void prvRunThread( void * pxArg );
*/
static const pthread_attr_internal_t xDefaultThreadAttributes =
{
.xStackSize = PTHREAD_STACK_MIN,
.iDetachState = PTHREAD_CREATE_JOINABLE,
.xSchedParam = { .sched_priority = tskIDLE_PRIORITY }
.usStackSize = PTHREAD_STACK_MIN,
.usSchedPriorityDetachState = ( ( uint16_t ) tskIDLE_PRIORITY & pthreadSCHED_PRIORITY_MASK ) | ( PTHREAD_CREATE_JOINABLE << pthreadDETACH_STATE_SHIFT ),
};
/*-----------------------------------------------------------*/
@ -97,7 +102,7 @@ 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 )
if( pthreadIS_JOINABLE( pxThread->xAttr.usSchedPriorityDetachState ) )
{
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );
@ -130,9 +135,9 @@ static void prvRunThread( void * pxArg )
int pthread_attr_destroy( pthread_attr_t * attr )
{
int iStatus = 0;
vPortFree( *attr );
return iStatus;
( void ) attr;
return 0;
}
/*-----------------------------------------------------------*/
@ -140,9 +145,16 @@ int pthread_attr_destroy( pthread_attr_t * attr )
int pthread_attr_getdetachstate( const pthread_attr_t * attr,
int * detachstate )
{
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );
*detachstate = pxAttr->iDetachState;
if( pthreadIS_JOINABLE( pxAttr->usSchedPriorityDetachState ) )
{
*detachstate = PTHREAD_CREATE_JOINABLE;
}
else
{
*detachstate = PTHREAD_CREATE_DETACHED;
}
return 0;
}
@ -152,9 +164,9 @@ int pthread_attr_getdetachstate( const pthread_attr_t * attr,
int pthread_attr_getschedparam( const pthread_attr_t * attr,
struct sched_param * param )
{
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );
*param = pxAttr->xSchedParam;
param->sched_priority = ( int ) ( pthreadGET_SCHED_PRIORITY( pxAttr->usSchedPriorityDetachState ) );
return 0;
}
@ -164,9 +176,9 @@ int pthread_attr_getschedparam( const pthread_attr_t * attr,
int pthread_attr_getstacksize( const pthread_attr_t * attr,
size_t * stacksize )
{
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );
*stacksize = pxAttr->xStackSize;
*stacksize = ( size_t ) pxAttr->usStackSize;
return 0;
}
@ -175,24 +187,10 @@ int pthread_attr_getstacksize( const pthread_attr_t * attr,
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;
}
*( ( pthread_attr_internal_t * ) ( attr ) ) = xDefaultThreadAttributes;
return iStatus;
return 0;
}
/*-----------------------------------------------------------*/
@ -201,7 +199,7 @@ int pthread_attr_setdetachstate( pthread_attr_t * attr,
int detachstate )
{
int iStatus = 0;
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );
if( ( detachstate != PTHREAD_CREATE_DETACHED ) && ( detachstate != PTHREAD_CREATE_JOINABLE ) )
{
@ -209,7 +207,9 @@ int pthread_attr_setdetachstate( pthread_attr_t * attr,
}
else
{
pxAttr->iDetachState = detachstate;
/* clear and then set msb bit to detachstate) */
pxAttr->usSchedPriorityDetachState &= ~pthreadDETACH_STATE_MASK;
pxAttr->usSchedPriorityDetachState |= ( ( uint16_t ) detachstate << pthreadDETACH_STATE_SHIFT );
}
return iStatus;
@ -221,7 +221,7 @@ 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 );
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );
/* Check for NULL param. */
if( param == NULL )
@ -240,7 +240,9 @@ int pthread_attr_setschedparam( pthread_attr_t * attr,
/* Set the sched_param. */
if( iStatus == 0 )
{
pxAttr->xSchedParam = *param;
/* clear and then set 15 LSB to schedule priority) */
pxAttr->usSchedPriorityDetachState &= ~pthreadSCHED_PRIORITY_MASK;
pxAttr->usSchedPriorityDetachState |= ( ( uint16_t ) param->sched_priority );
}
return iStatus;
@ -248,11 +250,23 @@ int pthread_attr_setschedparam( pthread_attr_t * attr,
/*-----------------------------------------------------------*/
int pthread_attr_setschedpolicy( pthread_attr_t * attr,
int policy )
{
/* Silence warnings about unused parameters. */
( void ) attr;
( void ) policy;
return 0;
}
/*-----------------------------------------------------------*/
int pthread_attr_setstacksize( pthread_attr_t * attr,
size_t stacksize )
{
int iStatus = 0;
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( *attr );
pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );
if( stacksize < PTHREAD_STACK_MIN )
{
@ -260,7 +274,7 @@ int pthread_attr_setstacksize( pthread_attr_t * attr,
}
else
{
pxAttr->xStackSize = stacksize;
pxAttr->usStackSize = ( uint16_t ) stacksize;
}
return iStatus;
@ -275,6 +289,7 @@ int pthread_create( pthread_t * thread,
{
int iStatus = 0;
pthread_internal_t * pxThread = NULL;
struct sched_param xSchedParam = { .sched_priority = tskIDLE_PRIORITY };
/* Allocate memory for new thread object. */
pxThread = ( pthread_internal_t * ) pvPortMalloc( sizeof( pthread_internal_t ) );
@ -295,16 +310,20 @@ int pthread_create( pthread_t * thread,
/* Otherwise, use provided attributes. */
else
{
pxThread->xAttr = *( ( pthread_attr_internal_t * ) ( *attr ) );
pxThread->xAttr = *( ( pthread_attr_internal_t * ) ( attr ) );
}
/* Get priority from attributes */
xSchedParam.sched_priority = ( int ) pthreadGET_SCHED_PRIORITY( pxThread->xAttr.usSchedPriorityDetachState );
/* 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 )
if( pthreadIS_JOINABLE( pxThread->xAttr.usSchedPriorityDetachState ) )
{
/* These calls will not fail when their arguments aren't NULL. */
( void ) xSemaphoreCreateMutexStatic( &pxThread->xJoinMutex );
@ -321,9 +340,9 @@ int pthread_create( pthread_t * thread,
/* Create the FreeRTOS task that will run the pthread. */
if( xTaskCreate( prvRunThread,
posixconfigPTHREAD_TASK_NAME,
( uint16_t ) ( pxThread->xAttr.xStackSize / sizeof( StackType_t ) ),
( uint16_t ) ( pxThread->xAttr.usStackSize / sizeof( StackType_t ) ),
( void * ) pxThread,
pxThread->xAttr.xSchedParam.sched_priority,
xSchedParam.sched_priority,
&pxThread->xTaskHandle ) != pdPASS )
{
/* Task creation failed, no memory. */
@ -352,12 +371,13 @@ int pthread_getschedparam( pthread_t thread,
int * policy,
struct sched_param * param )
{
int iStatus = 0;
pthread_internal_t * pxThread = ( pthread_internal_t * ) thread;
*policy = SCHED_OTHER;
*param = pxThread->xAttr.xSchedParam;
param->sched_priority = ( int ) pthreadGET_SCHED_PRIORITY( pxThread->xAttr.usSchedPriorityDetachState );
return 0;
return iStatus;
}
/*-----------------------------------------------------------*/
@ -391,7 +411,7 @@ int pthread_join( pthread_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 )
if( !pthreadIS_JOINABLE( pxThread->xAttr.usSchedPriorityDetachState ) )
{
iStatus = EDEADLK;
}
@ -468,18 +488,23 @@ int pthread_setschedparam( pthread_t thread,
int policy,
const struct sched_param * param )
{
int iStatus = 0;
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;
/* Copy the given sched_param. */
iStatus = pthread_attr_setschedparam( ( pthread_attr_t * ) &pxThread->xAttr, param );
/* Change the priority of the FreeRTOS task. */
vTaskPrioritySet( pxThread->xTaskHandle, pxThread->xAttr.xSchedParam.sched_priority );
if( iStatus == 0 )
{
/* Change the priority of the FreeRTOS task. */
vTaskPrioritySet( pxThread->xTaskHandle, param->sched_priority );
}
return 0;
return iStatus;
}
/*-----------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -36,41 +36,32 @@
#include "FreeRTOS_POSIX/errno.h"
#include "FreeRTOS_POSIX/pthread.h"
#include "atomic.h"
/*
* @brief barrier max count
*
* 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 )
#define posixPTHREAD_BARRIER_MAX_COUNT ( 8 )
#else
#define posixPTHREAD_BARRIER_MAX_COUNT ( 24 )
#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 );
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;
}
@ -81,7 +72,7 @@ int pthread_barrier_init( pthread_barrier_t * barrier,
unsigned count )
{
int iStatus = 0;
pthread_barrier_internal_t * pxNewBarrier = NULL;
pthread_barrier_internal_t * pxNewBarrier = ( pthread_barrier_internal_t * ) ( barrier );
/* Silence warnings about unused parameters. */
( void ) attr;
@ -103,18 +94,6 @@ int pthread_barrier_init( pthread_barrier_t * barrier,
}
}
/* 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. */
@ -125,19 +104,12 @@ int pthread_barrier_init( pthread_barrier_t * barrier,
* 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;
@ -149,7 +121,7 @@ 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 );
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
@ -160,31 +132,20 @@ int pthread_barrier_wait( pthread_barrier_t * barrier )
*/
( 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 );
uThreadNumber = Atomic_Increment_u32( ( uint32_t * ) &pxBarrier->uThreadCount );
/* 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 << uThreadNumber, /* 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 )
if( uThreadNumber == 0 )
{
iStatus = PTHREAD_BARRIER_SERIAL_THREAD;

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -37,6 +37,8 @@
#include "FreeRTOS_POSIX/pthread.h"
#include "FreeRTOS_POSIX/utils.h"
#include "atomic.h"
/**
* @brief Initialize a PTHREAD_COND_INITIALIZER cond.
*
@ -67,7 +69,6 @@ static void prvInitializeStaticCond( pthread_cond_internal_t * pxCond )
/* 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;
}
@ -77,32 +78,61 @@ static void prvInitializeStaticCond( pthread_cond_internal_t * pxCond )
}
}
/**
* @brief Check "atomically" if iLocalWaitingThreads == pxCond->iWaitingThreads and decrement.
*/
static void prvTestAndDecrement( pthread_cond_t * pxCond,
unsigned iLocalWaitingThreads )
{
/* Test local copy of threads waiting is larger than zero. */
while( iLocalWaitingThreads > 0 )
{
/* Test-and-set. Atomically check whether the copy in memory has changed.
* And, if not decrease the copy of threads waiting in memory. */
if( ATOMIC_COMPARE_AND_SWAP_SUCCESS == Atomic_CompareAndSwap_u32( ( uint32_t * ) &pxCond->iWaitingThreads, ( uint32_t ) iLocalWaitingThreads - 1, ( uint32_t ) iLocalWaitingThreads ) )
{
/* Signal one succeeded. Break. */
break;
}
/* Local copy may be out dated. Reload, and retry. */
iLocalWaitingThreads = pxCond->iWaitingThreads;
}
}
/*-----------------------------------------------------------*/
int pthread_cond_broadcast( pthread_cond_t * cond )
{
int i = 0;
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( *cond );
unsigned 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 );
/* Local copy of number of threads waiting. */
unsigned iLocalWaitingThreads = pxCond->iWaitingThreads;
/* Unblock all threads waiting on this condition variable. */
for( i = 0; i < pxCond->iWaitingThreads; i++ )
/* Test local copy of threads waiting is larger than zero. */
while( iLocalWaitingThreads > 0 )
{
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore );
/* Test-and-set. Atomically check whether the copy in memory has changed.
* And, if not set the copy of threads waiting in memory to zero. */
if( ATOMIC_COMPARE_AND_SWAP_SUCCESS == Atomic_CompareAndSwap_u32( ( uint32_t * ) &pxCond->iWaitingThreads, 0, ( uint32_t ) iLocalWaitingThreads ) )
{
/* Unblock all. */
for( i = 0; i < iLocalWaitingThreads; i++ )
{
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore );
}
break;
}
/* Local copy is out dated. Reload, and retry. */
iLocalWaitingThreads = pxCond->iWaitingThreads;
}
/* All threads were unblocked, set waiting threads to 0. */
pxCond->iWaitingThreads = 0;
/* Release xCondMutex. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
return 0;
}
@ -110,12 +140,10 @@ int pthread_cond_broadcast( pthread_cond_t * cond )
int pthread_cond_destroy( pthread_cond_t * cond )
{
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_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;
}
@ -126,13 +154,11 @@ int pthread_cond_init( pthread_cond_t * cond,
const pthread_condattr_t * attr )
{
int iStatus = 0;
pthread_cond_internal_t * pxCond = NULL;
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) cond;
/* Silence warnings about unused parameters. */
( void ) attr;
pxCond = pvPortMalloc( sizeof( pthread_cond_internal_t ) );
if( pxCond == NULL )
{
iStatus = ENOMEM;
@ -143,12 +169,9 @@ int pthread_cond_init( pthread_cond_t * cond,
/* 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;
@ -158,30 +181,30 @@ int pthread_cond_init( pthread_cond_t * cond,
int pthread_cond_signal( pthread_cond_t * cond )
{
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_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 );
/* Local copy of number of threads waiting. */
unsigned iLocalWaitingThreads = pxCond->iWaitingThreads;
/* Check again that at least one thread is waiting for a signal after
* taking xCondMutex. If so, unblock it. */
if( pxCond->iWaitingThreads > 0 )
/* Test local copy of threads waiting is larger than zero. */
while( iLocalWaitingThreads > 0 )
{
/* Test-and-set. Atomically check whether the copy in memory has changed.
* And, if not decrease the copy of threads waiting in memory. */
if( ATOMIC_COMPARE_AND_SWAP_SUCCESS == Atomic_CompareAndSwap_u32( ( uint32_t * ) &pxCond->iWaitingThreads, ( uint32_t ) iLocalWaitingThreads - 1, ( uint32_t ) iLocalWaitingThreads ) )
{
/* Unblock one. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondWaitSemaphore );
/* Decrease the number of waiting threads. */
pxCond->iWaitingThreads--;
/* Signal one succeeded. Break. */
break;
}
/* Release xCondMutex. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
/* Local copy may be out dated. Reload, and retry. */
iLocalWaitingThreads = pxCond->iWaitingThreads;
}
return 0;
@ -193,8 +216,9 @@ int pthread_cond_timedwait( pthread_cond_t * cond,
pthread_mutex_t * mutex,
const struct timespec * abstime )
{
unsigned iLocalWaitingThreads;
int iStatus = 0;
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( *cond );
pthread_cond_internal_t * pxCond = ( pthread_cond_internal_t * ) ( cond );
TickType_t xDelay = portMAX_DELAY;
/* If the cond is uninitialized, perform initialization. */
@ -203,16 +227,26 @@ int pthread_cond_timedwait( pthread_cond_t * cond,
/* Convert abstime to a delay in TickType_t if provided. */
if( abstime != NULL )
{
iStatus = UTILS_AbsoluteTimespecToTicks( abstime, &xDelay );
struct timespec xCurrentTime = { 0 };
/* Get current time */
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
{
iStatus = EINVAL;
}
else
{
iStatus = UTILS_AbsoluteTimespecToDeltaTicks( abstime, &xCurrentTime, &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 );
/* Atomically increments thread waiting by 1, and
* stores number of threads waiting before increment. */
iLocalWaitingThreads = Atomic_Increment_u32( ( uint32_t * ) &pxCond->iWaitingThreads );
iStatus = pthread_mutex_unlock( mutex );
}
@ -232,11 +266,21 @@ int pthread_cond_timedwait( pthread_cond_t * cond,
iStatus = ETIMEDOUT;
( void ) pthread_mutex_lock( mutex );
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxCond->xCondMutex, portMAX_DELAY );
pxCond->iWaitingThreads--;
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxCond->xCondMutex );
/* Atomically decrements thread waiting by 1.
* If iLocalWaitingThreads is updated by other thread(s) in between,
* this implementation guarantees to decrement by 1 based on the
* value currently in pxCond->iWaitingThreads. */
prvTestAndDecrement( pxCond, iLocalWaitingThreads + 1 );
}
}
else
{
/* Atomically decrements thread waiting by 1.
* If iLocalWaitingThreads is updated by other thread(s) in between,
* this implementation guarantees to decrement by 1 based on the
* value currently in pxCond->iWaitingThreads. */
prvTestAndDecrement( pxCond, iLocalWaitingThreads + 1 );
}
return iStatus;
}
@ -247,4 +291,4 @@ int pthread_cond_wait( pthread_cond_t * cond,
pthread_mutex_t * mutex )
{
return pthread_cond_timedwait( cond, mutex, NULL );
}
}

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -30,7 +30,7 @@
/* C standard library includes. */
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
/* FreeRTOS+POSIX includes. */
#include "FreeRTOS_POSIX.h"
@ -96,13 +96,12 @@ static void prvInitializeStaticMutex( pthread_mutex_internal_t * pxMutex )
int pthread_mutex_destroy( pthread_mutex_t * mutex )
{
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_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;
@ -114,10 +113,7 @@ 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 ) );
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) mutex;
if( pxMutex == NULL )
{
@ -127,8 +123,7 @@ int pthread_mutex_init( pthread_mutex_t * mutex,
if( iStatus == 0 )
{
/* Clear the newly-allocated mutex. */
( void ) memset( pxMutex, 0x00, sizeof( pthread_mutex_internal_t ) );
*pxMutex = FREERTOS_POSIX_MUTEX_INITIALIZER;
/* No attributes given, use default attributes. */
if( attr == NULL )
@ -138,7 +133,7 @@ int pthread_mutex_init( pthread_mutex_t * mutex,
/* Otherwise, use provided attributes. */
else
{
pxMutex->xAttr = *( ( pthread_mutexattr_internal_t * ) ( *attr ) );
pxMutex->xAttr = *( ( pthread_mutexattr_internal_t * ) ( attr ) );
}
/* Call the correct FreeRTOS mutex creation function based on mutex type. */
@ -164,7 +159,6 @@ int pthread_mutex_init( pthread_mutex_t * mutex,
{
/* Mutex successfully created. */
pxMutex->xIsInitialized = pdTRUE;
*mutex = ( pthread_mutex_t ) pxMutex;
}
}
@ -184,7 +178,7 @@ 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 );
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) ( mutex );
TickType_t xDelay = portMAX_DELAY;
BaseType_t xFreeRTOSMutexTakeStatus = pdFALSE;
@ -197,7 +191,17 @@ int pthread_mutex_timedlock( pthread_mutex_t * mutex,
/* Convert abstime to a delay in TickType_t if provided. */
if( abstime != NULL )
{
iStatus = UTILS_AbsoluteTimespecToTicks( abstime, &xDelay );
struct timespec xCurrentTime = { 0 };
/* Get current time */
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
{
iStatus = EINVAL;
}
else
{
iStatus = UTILS_AbsoluteTimespecToDeltaTicks( abstime, &xCurrentTime, &xDelay );
}
/* If abstime was in the past, still attempt to lock the mutex without
* blocking, per POSIX spec. */
@ -272,7 +276,7 @@ int pthread_mutex_trylock( pthread_mutex_t * mutex )
int pthread_mutex_unlock( pthread_mutex_t * mutex )
{
int iStatus = 0;
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) ( *mutex );
pthread_mutex_internal_t * pxMutex = ( pthread_mutex_internal_t * ) ( mutex );
/* If mutex in uninitialized, perform initialization. */
prvInitializeStaticMutex( pxMutex );
@ -287,6 +291,10 @@ int pthread_mutex_unlock( pthread_mutex_t * mutex )
if( iStatus == 0 )
{
/* Suspend the scheduler so that
* mutex is unlocked AND owner is updated atomically */
vTaskSuspendAll();
/* Call the correct FreeRTOS mutex unlock function based on mutex type. */
if( pxMutex->xAttr.iType == PTHREAD_MUTEX_RECURSIVE )
{
@ -300,6 +308,9 @@ int pthread_mutex_unlock( pthread_mutex_t * mutex )
/* 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 );
/* Resume the scheduler */
( void ) xTaskResumeAll();
}
return iStatus;
@ -309,8 +320,7 @@ int pthread_mutex_unlock( pthread_mutex_t * mutex )
int pthread_mutexattr_destroy( pthread_mutexattr_t * attr )
{
/* Free mutex attributes object. */
vPortFree( *attr );
( void ) attr;
return 0;
}
@ -320,7 +330,7 @@ int pthread_mutexattr_destroy( pthread_mutexattr_t * attr )
int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr,
int * type )
{
pthread_mutexattr_internal_t * pxAttr = ( pthread_mutexattr_internal_t * ) ( *attr );
pthread_mutexattr_internal_t * pxAttr = ( pthread_mutexattr_internal_t * ) ( attr );
*type = pxAttr->iType;
@ -331,24 +341,9 @@ int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr,
int pthread_mutexattr_init( pthread_mutexattr_t * attr )
{
int iStatus = 0;
*( ( pthread_mutexattr_internal_t * ) ( attr ) ) = xDefaultMutexAttributes;
/* 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;
return 0;
}
/*-----------------------------------------------------------*/
@ -357,7 +352,7 @@ int pthread_mutexattr_settype( pthread_mutexattr_t * attr,
int type )
{
int iStatus = 0;
pthread_mutexattr_internal_t * pxAttr = ( pthread_mutexattr_internal_t * ) ( *attr );
pthread_mutexattr_internal_t * pxAttr = ( pthread_mutexattr_internal_t * ) ( attr );
switch( type )
{

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -44,9 +44,21 @@ int sched_get_priority_max( int policy )
/*-----------------------------------------------------------*/
int sched_get_priority_min( int policy )
{
/* Silence warnings about unused parameters. */
( void ) policy;
return tskIDLE_PRIORITY;
}
/*-----------------------------------------------------------*/
int sched_yield( void )
{
taskYIELD();
return 0;
}
/*-----------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -37,24 +37,17 @@
#include "FreeRTOS_POSIX/semaphore.h"
#include "FreeRTOS_POSIX/utils.h"
/**
* @brief Semaphore type.
*/
typedef struct
{
StaticSemaphore_t xSemaphore; /**< FreeRTOS semaphore. */
} sem_internal_t;
#include "atomic.h"
/*-----------------------------------------------------------*/
int sem_destroy( sem_t * sem )
{
sem_internal_t * pxSem = ( sem_internal_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;
}
@ -64,10 +57,14 @@ int sem_destroy( sem_t * sem )
int sem_getvalue( sem_t * sem,
int * sval )
{
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
sem_internal_t * pxSem = ( sem_internal_t * ) ( sem );
/* Get the semaphore count using the FreeRTOS API. */
*sval = ( int ) uxSemaphoreGetCount( ( SemaphoreHandle_t ) &pxSem->xSemaphore );
/* Get value does not need atomic operation, since -- Open Group
* states "the updated value represents an actual semaphore value that
* occurred at some unspecified time during the call, but it need not be the
* actual value of the semaphore when it is returned to the calling process."
*/
*sval = pxSem->value;
return 0;
}
@ -79,7 +76,7 @@ int sem_init( sem_t * sem,
unsigned value )
{
int iStatus = 0;
sem_internal_t * pxSem = NULL;
sem_internal_t * pxSem = ( sem_internal_t * ) ( sem );
/* Silence warnings about unused parameters. */
( void ) pshared;
@ -91,24 +88,17 @@ int sem_init( sem_t * sem,
iStatus = -1;
}
/* Allocate memory for a new semaphore. */
/* value is guaranteed to not exceed INT32_MAX, which is the default value of SEM_VALUE_MAX (0x7FFFU). */
pxSem->value = ( int ) value;
/* Create the FreeRTOS semaphore.
* This is only used to queue threads when no semaphore is available.
* Initializing with semaphore initial count zero.
* This call will not fail because the memory for the semaphore has already been allocated.
*/
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;
( void ) xSemaphoreCreateCountingStatic( SEM_VALUE_MAX, 0, &pxSem->xSemaphore );
}
return iStatus;
@ -118,10 +108,18 @@ int sem_init( sem_t * sem,
int sem_post( sem_t * sem )
{
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
sem_internal_t * pxSem = ( sem_internal_t * ) ( sem );
/* Give the semaphore using the FreeRTOS API. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxSem->xSemaphore );
int iPreviouValue = Atomic_Increment_u32( ( uint32_t * ) &pxSem->value );
/* If previous semaphore value is equal or larger than zero, there is no
* thread waiting for this semaphore. Otherwise (<0), call FreeRTOS interface
* to wake up a thread. */
if( iPreviouValue < 0 )
{
/* Give the semaphore using the FreeRTOS API. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxSem->xSemaphore );
}
return 0;
}
@ -132,7 +130,7 @@ int sem_timedwait( sem_t * sem,
const struct timespec * abstime )
{
int iStatus = 0;
sem_internal_t * pxSem = ( sem_internal_t * ) ( *sem );
sem_internal_t * pxSem = ( sem_internal_t * ) ( sem );
TickType_t xDelay = portMAX_DELAY;
if( abstime != NULL )
@ -146,7 +144,17 @@ int sem_timedwait( sem_t * sem,
}
else
{
iStatus = UTILS_AbsoluteTimespecToTicks( abstime, &xDelay );
struct timespec xCurrentTime = { 0 };
/* Get current time */
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
{
iStatus = EINVAL;
}
else
{
iStatus = UTILS_AbsoluteTimespecToDeltaTicks( abstime, &xCurrentTime, &xDelay );
}
/* If abstime was in the past, still attempt to take the semaphore without
* blocking, per POSIX spec. */
@ -157,16 +165,37 @@ int sem_timedwait( sem_t * sem,
}
}
/* Take the semaphore using the FreeRTOS API. */
if( xSemaphoreTake( ( SemaphoreHandle_t ) &pxSem->xSemaphore,
xDelay ) != pdTRUE )
int iPreviousValue = Atomic_Decrement_u32( ( uint32_t * ) &pxSem->value );
/* If previous semaphore value is larger than zero, the thread entering this function call
* can take the semaphore without yielding. Else (<=0), calling into FreeRTOS API to yield.
*/
if( iPreviousValue > 0 )
{
errno = iStatus;
iStatus = -1;
/* Under no circumstance shall the function fail with a timeout if the semaphore can be locked immediately. */
iStatus = 0;
}
else
{
iStatus = 0;
/* Take the semaphore using the FreeRTOS API. */
if( xSemaphoreTake( ( SemaphoreHandle_t ) &pxSem->xSemaphore,
xDelay ) != pdTRUE )
{
if( iStatus == 0 )
{
errno = ETIMEDOUT;
}
else
{
errno = iStatus;
}
iStatus = -1;
}
else
{
iStatus = 0;
}
}
return iStatus;

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -42,13 +42,9 @@
/* FreeRTOS timer include. */
#include "timers.h"
/**
* #brief Timespec zero check macros.
*/
/**@{ */
/* 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.
@ -66,7 +62,6 @@ 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 );
@ -85,23 +80,11 @@ void prvTimerCallback( TimerHandle_t xTimerHandle )
/* 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 the user has provided thread attributes, create a thread
* with the provided attributes. Otherwise dispatch callback directly */
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 );
}
( *pxTimer->xTimerEvent.sigev_notify_function )( pxTimer->xTimerEvent.sigev_value );
}
else
{
@ -196,7 +179,9 @@ int timer_delete( timer_t timerid )
int timer_getoverrun( timer_t timerid )
{
( void ) timerid;
/* Silence warnings about unused parameters. */
( void ) timerid;
return 0;
}
@ -256,7 +241,29 @@ int timer_settime( timer_t timerid,
/* Absolute timeout. */
if( ( flags & TIMER_ABSTIME ) == TIMER_ABSTIME )
{
( void ) UTILS_AbsoluteTimespecToTicks( &value->it_value, &xNextTimerExpiration );
struct timespec xCurrentTime = { 0 };
/* Get current time */
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
{
iStatus = EINVAL;
}
else
{
iStatus = UTILS_AbsoluteTimespecToDeltaTicks( &value->it_value, &xCurrentTime, &xNextTimerExpiration );
}
/* Make sure xNextTimerExpiration is zero in case we got negative time difference */
if( iStatus != 0 )
{
xNextTimerExpiration = 0;
if( iStatus == ETIMEDOUT )
{
/* Set Status to 0 as absolute time is past is treated as expiry but not an error */
iStatus = 0;
}
}
}
/* Relative timeout. */
else

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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

View File

@ -1,5 +1,5 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Amazon FreeRTOS POSIX V1.1.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
@ -30,6 +30,7 @@
/* C standard library includes. */
#include <stddef.h>
#include <limits.h>
/* FreeRTOS+POSIX includes. */
#include "FreeRTOS_POSIX.h"
@ -58,35 +59,34 @@ size_t UTILS_strnlen( const char * const pcString,
/*-----------------------------------------------------------*/
int UTILS_AbsoluteTimespecToTicks( const struct timespec * const pxAbsoluteTime,
TickType_t * const pxResult )
int UTILS_AbsoluteTimespecToDeltaTicks( const struct timespec * const pxAbsoluteTime,
const struct timespec * const pxCurrentTime,
TickType_t * const pxResult )
{
int iStatus = 0;
struct timespec xCurrentTime = { 0 }, xDifference = { 0 };
struct timespec xDifference = { 0 };
/* Check parameters. */
if( ( pxAbsoluteTime == NULL ) || ( pxResult == NULL ) )
if( ( pxAbsoluteTime == NULL ) || ( pxCurrentTime == NULL ) || ( pxResult == NULL ) )
{
iStatus = EINVAL;
}
/* Get the current time. */
/* Calculate the difference between the current time and absolute time. */
if( iStatus == 0 )
{
if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
{
iStatus = errno;
}
}
iStatus = UTILS_TimespecSubtract( pxAbsoluteTime, pxCurrentTime, &xDifference );
/* Calculate the difference between the current time and pxAbsoluteTime. */
if( iStatus == 0 )
{
if( UTILS_TimespecSubtract( &xDifference, pxAbsoluteTime, &xCurrentTime ) != 0 )
if( iStatus == 1 )
{
/* pxAbsoluteTime was in the past. */
iStatus = ETIMEDOUT;
}
else if( iStatus == -1 )
{
/* error */
iStatus = EINVAL;
}
}
/* Convert the time difference to ticks. */
@ -104,7 +104,7 @@ int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
TickType_t * const pxResult )
{
int iStatus = 0;
uint64_t ullTotalTicks = 0;
int64_t llTotalTicks = 0;
long lNanoseconds = 0;
/* Check parameters. */
@ -112,7 +112,7 @@ int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
{
iStatus = EINVAL;
}
else if( ( pxTimespec != NULL ) && ( UTILS_ValidateTimespec( pxTimespec ) == false ) )
else if( ( iStatus == 0 ) && ( UTILS_ValidateTimespec( pxTimespec ) == false ) )
{
iStatus = EINVAL;
}
@ -120,7 +120,7 @@ int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
if( iStatus == 0 )
{
/* Convert timespec.tv_sec to ticks. */
ullTotalTicks = ( uint64_t ) configTICK_RATE_HZ * ( uint64_t ) ( pxTimespec->tv_sec );
llTotalTicks = ( int64_t ) configTICK_RATE_HZ * ( 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
@ -129,10 +129,30 @@ int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
( 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;
llTotalTicks += ( int64_t ) lNanoseconds;
/* Check for overflow */
if( llTotalTicks < 0 )
{
iStatus = EINVAL;
}
else
{
/* check if TickType_t is 32 bit or 64 bit */
uint32_t ulTickTypeSize = sizeof( TickType_t );
/* check for downcast overflow */
if( ulTickTypeSize == sizeof( uint32_t ) )
{
if( llTotalTicks > UINT_MAX )
{
iStatus = EINVAL;
}
}
}
/* Write result. */
*pxResult = ( TickType_t ) ullTotalTicks;
*pxResult = ( TickType_t ) llTotalTicks;
}
return iStatus;
@ -162,71 +182,188 @@ void UTILS_NanosecondsToTimespec( int64_t llSource,
/*-----------------------------------------------------------*/
int UTILS_TimespecAdd( struct timespec * const pxResult,
const struct timespec * const x,
const struct timespec * const y )
int UTILS_TimespecAdd( const struct timespec * const x,
const struct timespec * const y,
struct timespec * const pxResult )
{
int64_t llResult64 = 0;
int64_t llPartialSec = 0;
int iStatus = 0;
/* Check parameters. */
if( ( pxResult == NULL ) || ( x == NULL ) || ( y == NULL ) )
{
return -1;
iStatus = -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 ) );
if( iStatus == 0 )
{
/* Perform addition. */
pxResult->tv_nsec = x->tv_nsec + y->tv_nsec;
/* Convert result to timespec. */
UTILS_NanosecondsToTimespec( llResult64, pxResult );
/* check for overflow in case nsec value was invalid */
if( pxResult->tv_nsec < 0 )
{
iStatus = 1;
}
else
{
llPartialSec = ( pxResult->tv_nsec ) / NANOSECONDS_PER_SECOND;
pxResult->tv_nsec = ( pxResult->tv_nsec ) % NANOSECONDS_PER_SECOND;
pxResult->tv_sec = x->tv_sec + y->tv_sec + llPartialSec;
return ( int ) ( llResult64 < 0LL );
/* check for overflow */
if( pxResult->tv_sec < 0 )
{
iStatus = 1;
}
}
}
return iStatus;
}
/*-----------------------------------------------------------*/
int UTILS_TimespecAddNanoseconds( struct timespec * const pxResult,
const struct timespec * const x,
int64_t llNanoseconds )
int UTILS_TimespecAddNanoseconds( const struct timespec * const x,
int64_t llNanoseconds,
struct timespec * const pxResult )
{
struct timespec y = { .tv_sec = ( time_t ) 0, .tv_nsec = 0L };
int64_t llTotalNSec = 0;
int iStatus = 0;
/* Check parameters. */
if( ( pxResult == NULL ) || ( x == NULL ) )
{
return -1;
iStatus = -1;
}
/* Convert llNanoseconds to a timespec. */
UTILS_NanosecondsToTimespec( llNanoseconds, &y );
if( iStatus == 0 )
{
/* add nano seconds */
llTotalNSec = x->tv_nsec + llNanoseconds;
/* Perform addition. */
return UTILS_TimespecAdd( pxResult, x, &y );
/* check for nano seconds overflow */
if( llTotalNSec < 0 )
{
iStatus = 1;
}
else
{
pxResult->tv_nsec = llTotalNSec % NANOSECONDS_PER_SECOND;
pxResult->tv_sec = x->tv_sec + ( llTotalNSec / NANOSECONDS_PER_SECOND );
/* check for seconds overflow */
if( pxResult->tv_sec < 0 )
{
iStatus = 1;
}
}
}
return iStatus;
}
/*-----------------------------------------------------------*/
int UTILS_TimespecSubtract( struct timespec * const pxResult,
const struct timespec * const x,
const struct timespec * const y )
int UTILS_TimespecSubtract( const struct timespec * const x,
const struct timespec * const y,
struct timespec * const pxResult )
{
int64_t llResult64 = 0;
int iCompareResult = 0;
int iStatus = 0;
/* Check parameters. */
if( ( pxResult == NULL ) || ( x == NULL ) || ( y == NULL ) )
{
return -1;
iStatus = -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 ) );
if( iStatus == 0 )
{
iCompareResult = UTILS_TimespecCompare( x, y );
/* Convert result to timespec. */
UTILS_NanosecondsToTimespec( llResult64, pxResult );
/* if x < y then result would be negative, return 1 */
if( iCompareResult == -1 )
{
iStatus = 1;
}
else if( iCompareResult == 0 )
{
/* if times are the same return zero */
pxResult->tv_sec = 0;
pxResult->tv_nsec = 0;
}
else
{
/* If x > y Perform subtraction. */
pxResult->tv_sec = x->tv_sec - y->tv_sec;
pxResult->tv_nsec = x->tv_nsec - y->tv_nsec;
return ( int ) ( llResult64 < 0LL );
/* check if nano seconds value needs to borrow */
if( pxResult->tv_nsec < 0 )
{
/* Based on comparison, tv_sec > 0 */
pxResult->tv_sec--;
pxResult->tv_nsec += ( long ) NANOSECONDS_PER_SECOND;
}
/* if nano second is negative after borrow, it is an overflow error */
if( pxResult->tv_nsec < 0 )
{
iStatus = -1;
}
}
}
return iStatus;
}
/*-----------------------------------------------------------*/
int UTILS_TimespecCompare( const struct timespec * const x,
const struct timespec * const y )
{
int iStatus = 0;
/* Check parameters */
if( ( x == NULL ) && ( y == NULL ) )
{
iStatus = 0;
}
else if( y == NULL )
{
iStatus = 1;
}
else if( x == NULL )
{
iStatus = -1;
}
else if( x->tv_sec > y->tv_sec )
{
iStatus = 1;
}
else if( x->tv_sec < y->tv_sec )
{
iStatus = -1;
}
else
{
/* seconds are equal compare nano seconds */
if( x->tv_nsec > y->tv_nsec )
{
iStatus = 1;
}
else if( x->tv_nsec < y->tv_nsec )
{
iStatus = -1;
}
else
{
iStatus = 0;
}
}
return iStatus;
}
/*-----------------------------------------------------------*/

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -56,41 +56,39 @@
#undef ETIMEDOUT
/**
* @brief posix_errno Definition of POSIX errnos.
* @name 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. */
#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.
* @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
#define errno FreeRTOS_errno
#endif
/**@} */

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -33,11 +33,10 @@
#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. */
@ -48,11 +47,10 @@
#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. */
@ -62,21 +60,20 @@
/**
* @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. */
/**@{ */
#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_ */

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -59,10 +59,10 @@ struct mq_attr
*
* @retval 0 - Upon successful completion
* @retval -1 - A error occurred. errno is also set.
*
* \sideeffect Possible errno values
*
* @sideeffect Possible errno values
* <br>
* EBADF - The mqdes argument is not a valid message queue descriptor.
* EBADF - The mqdes argument is not a valid message queue descriptor.
*/
int mq_close( mqd_t mqdes );
@ -70,11 +70,11 @@ 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
* @sideeffect Possible errno values
* <br>
* DBADF - The mqdes argument is not a valid message queue descriptor.
*/
@ -86,21 +86,21 @@ int mq_getattr( mqd_t mqdes,
*
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html
*
* @note Supported name pattern: leading &lt;slash&gt; 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
* @note Supported name pattern: leading &lt;slash&gt; 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.
* @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.
* @retval (mqd_t) - 1 -- An error occurred. errno is also set.
*
* \sideeffect Possible errno values
* @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.
* 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>
@ -119,18 +119,18 @@ mqd_t mq_open( const char * name,
* 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.
*
* @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
* @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,
* 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.
@ -146,23 +146,22 @@ ssize_t mq_receive( mqd_t mqdes,
* 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
* @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,
* 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,
* 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,
* 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,
@ -175,21 +174,21 @@ int mq_send( mqd_t mqdes,
* 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.
*
* @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
*
* @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
* 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,
* 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.
@ -206,26 +205,25 @@ ssize_t mq_timedreceive( mqd_t mqdes,
* 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
* @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,
* 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
* 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,
* 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,
* 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,
@ -237,11 +235,11 @@ int mq_timedsend( mqd_t mqdes,
* @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
* @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>

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -39,7 +39,7 @@
#include "FreeRTOS_POSIX/time.h"
/**
* @brief pthread detach state.
* @name pthread detach state.
*/
/**@{ */
#define PTHREAD_CREATE_DETACHED 0 /**< Detached. */
@ -47,15 +47,16 @@
/**@} */
/**
* @brief Returned to a single thread after a successful pthread_barrier_wait.
* @name 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()."
* @brief 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.
* @name Mutex types.
*/
/**@{ */
#ifndef PTHREAD_MUTEX_NORMAL
@ -73,15 +74,20 @@
/**@} */
/**
* @brief Compile-time initializers.
* @name Compile-time initializers.
*
* @brief To use PTHREAD_COND_INITIALIZER, posixconfigENABLE_PTHREAD_COND_T needs to be set to 1
* in port specific POSIX config file.
*
* To use PTHREAD_MUTEX_INITIALIZER, posixconfigENABLE_PTHREAD_MUTEX_T needs to be set to 1 in
* port specific POSIX config file.
*/
/**@{ */
#define PTHREAD_COND_INITIALIZER FREERTOS_POSIX_COND_INITIALIZER /**< pthread_cond_t. */
#if posixconfigENABLE_PTHREAD_COND_T == 1
#define PTHREAD_COND_INITIALIZER FREERTOS_POSIX_COND_INITIALIZER /**< pthread_cond_t. */
#endif
#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
@ -91,8 +97,8 @@
* @brief Destroy the thread attributes object.
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_destroy.html
*
* @retval 0 - Upon successful completion
*
* @retval 0 - Upon successful completion.
*/
int pthread_attr_destroy( pthread_attr_t * attr );
@ -101,8 +107,7 @@ int pthread_attr_destroy( pthread_attr_t * attr );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getdetachstate.html
*
* @retval 0 - Upon successful completion
*
* @retval 0 - Upon successful completion.
*/
int pthread_attr_getdetachstate( const pthread_attr_t * attr,
int * detachstate );
@ -112,7 +117,7 @@ int pthread_attr_getdetachstate( const pthread_attr_t * attr,
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getschedparam.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
*/
int pthread_attr_getschedparam( const pthread_attr_t * attr,
struct sched_param * param );
@ -122,7 +127,7 @@ int pthread_attr_getschedparam( const pthread_attr_t * attr,
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_getstacksize.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
*/
int pthread_attr_getstacksize( const pthread_attr_t * attr,
size_t * stacksize );
@ -132,10 +137,9 @@ int pthread_attr_getstacksize( const pthread_attr_t * attr,
*
* @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
* @retval 0 - Upon successful completion.
*
* @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 );
@ -146,7 +150,8 @@ int pthread_attr_init( pthread_attr_t * attr );
* @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.
* @retval EINVAL - The value of detachstate is not valid. Currently, supported detach states are --
* PTHREAD_CREATE_DETACHED and PTHREAD_CREATE_JOINABLE.
*/
int pthread_attr_setdetachstate( pthread_attr_t * attr,
int detachstate );
@ -156,20 +161,32 @@ int pthread_attr_setdetachstate( pthread_attr_t * attr,
*
* @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.
* @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 the schedpolicy attribute.
*
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_attr_setschedpolicy.html
*
* @retval 0 - Upon successful completion.
*
* @warning This function is a stub and always returns 0.
*/
int pthread_attr_setschedpolicy( pthread_attr_t * attr,
int policy );
/**
* @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}
* @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 );
@ -179,9 +196,9 @@ int pthread_attr_setstacksize( pthread_attr_t * attr,
*
* @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.
* @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 );
@ -190,16 +207,17 @@ int pthread_barrier_destroy( pthread_barrier_t * barrier );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_barrier_init.html
*
* @retval 0 - Upon successful completion
* @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.
*
* @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,
@ -211,7 +229,7 @@ int pthread_barrier_init( pthread_barrier_t * 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).
* @retval 0 - Upon successful completion, other thread(s).
*/
int pthread_barrier_wait( pthread_barrier_t * barrier );
@ -220,7 +238,7 @@ int pthread_barrier_wait( pthread_barrier_t * barrier );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_create.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
* @retval EAGAIN - Insufficient memory for either thread structure or task creation.
*/
int pthread_create( pthread_t * thread,
@ -232,8 +250,8 @@ int pthread_create( pthread_t * thread,
* @brief Broadcast a condition.
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html
*
* @retval 0 - Upon successful completion
*
* @retval 0 - Upon successful completion.
*/
int pthread_cond_broadcast( pthread_cond_t * cond );
@ -242,7 +260,7 @@ int pthread_cond_broadcast( pthread_cond_t * cond );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_destroy.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
*/
int pthread_cond_destroy( pthread_cond_t * cond );
@ -251,10 +269,10 @@ int pthread_cond_destroy( pthread_cond_t * cond );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_init.html
*
* @retval 0 - Upon successful completion
* @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.
* @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 );
@ -264,7 +282,7 @@ int pthread_cond_init( pthread_cond_t * cond,
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_signal.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
*/
int pthread_cond_signal( pthread_cond_t * cond );
@ -273,9 +291,10 @@ int pthread_cond_signal( pthread_cond_t * cond );
*
* @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 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,
@ -287,7 +306,7 @@ int pthread_cond_timedwait( pthread_cond_t * cond,
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_wait.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
*/
int pthread_cond_wait( pthread_cond_t * cond,
pthread_mutex_t * mutex );
@ -296,9 +315,9 @@ int pthread_cond_wait( pthread_cond_t * cond,
* @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
*
* @retval 0 - t1 and t2 are both not NULL && equal.
* @retval non-zero - otherwise.
*/
int pthread_equal( pthread_t t1,
pthread_t t2 );
@ -307,7 +326,7 @@ int pthread_equal( pthread_t t1,
* @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 );
@ -316,10 +335,10 @@ 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.
* @retval 0 - Upon successful completion.
*
* @note policy is always set to SCHED_OTHER by this function.
*/
int pthread_getschedparam( pthread_t thread,
int * policy,
@ -329,11 +348,12 @@ int pthread_getschedparam( pthread_t thread,
* @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.
*
* @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 );
@ -343,10 +363,9 @@ int pthread_join( pthread_t thread,
*
* @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.
* @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 );
@ -354,8 +373,8 @@ 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 0 - Upon successful completion.
* @retval ENOMEM - Insufficient memory exists to initialize the mutex structure.
* @retval EAGAIN - Unable to initialize the mutex structure member(s).
*/
@ -366,11 +385,12 @@ int pthread_mutex_init( pthread_mutex_t * mutex,
* @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.
*
* @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 );
@ -378,13 +398,13 @@ 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 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 );
@ -394,11 +414,12 @@ int pthread_mutex_timedlock( pthread_mutex_t * mutex,
*
* @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 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 );
@ -407,8 +428,9 @@ int pthread_mutex_trylock( pthread_mutex_t * 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.
* @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 );
@ -417,7 +439,7 @@ int pthread_mutex_unlock( pthread_mutex_t * mutex );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_destroy.html
*
* @retval 0 - Upon successful completion
* @retval 0 - Upon successful completion.
*/
int pthread_mutexattr_destroy( pthread_mutexattr_t * attr );
@ -425,8 +447,8 @@ 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
*
* @retval 0 - Upon successful completion.
*/
int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr,
int * type );
@ -436,10 +458,10 @@ int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr,
*
* @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().
* @retval 0 - Upon successful completion.
*
* @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 );
@ -448,8 +470,8 @@ int pthread_mutexattr_init( pthread_mutexattr_t * attr );
*
* @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_settype.html
*
* @retval 0 - Upon successful completion
* @retval EINVAL - The value type is invalid.
* @retval 0 - Upon successful completion.
* @retval EINVAL - The value type is invalid.
*/
int pthread_mutexattr_settype( pthread_mutexattr_t * attr,
int type );
@ -468,9 +490,9 @@ pthread_t pthread_self( void );
*
* @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.
*
* @retval 0 - Upon successful completion.
*/
int pthread_setschedparam( pthread_t thread,
int policy,

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -34,10 +34,10 @@
#define _FREERTOS_POSIX_SCHED_H_
/**
* @brief Scheduling Policies
* @name Scheduling Policies
*/
/**@{ */
#define SCHED_OTHER 0 /**< Another scheduling policy. */
#define SCHED_OTHER 0 /**< Another scheduling policy. */
/**@} */
/**
@ -50,19 +50,28 @@ struct sched_param
};
/**
* @brief Get priority limit.
* @brief Get priority limit (max).
*
* 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.
* @return the maximum 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.
* e.g. if configMAX_PRIORITIES == 7, this function returns (configMAX_PRIORITIES - 1).
* configMAX_PRIORITIES is configured in application FreeRTOSConfig.h file.
*/
int sched_get_priority_max( int policy );
/**
* @brief Get priority limit (min).
*
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_get_priority_min.html
*
* @note policy is ignored.
*/
int sched_get_priority_min( int policy );
/**
* @brief Yield the processor.
*

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -35,11 +35,12 @@
/* FreeRTOS+POSIX includes. */
#include "FreeRTOS_POSIX/time.h"
#include "FreeRTOS_POSIX_types.h"
/**
* @brief Semaphore type.
*/
typedef void * sem_t;
typedef PosixSemType_t sem_t;
/**
* @brief Destroy an unnamed semaphore.
@ -47,8 +48,8 @@ typedef void * sem_t;
* @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.
*
* @note Semaphore is destroyed regardless of whether there is any thread currently blocked on this semaphore.
*/
int sem_destroy( sem_t * sem );
@ -58,7 +59,7 @@ int sem_destroy( sem_t * sem );
* @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,
@ -70,16 +71,15 @@ int sem_getvalue( sem_t * sem,
* @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
* @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.
*
* ENOSPC - A resource required to initialize the semaphore has been exhausted.
*/
int sem_init( sem_t * sem,
int pshared,
@ -98,17 +98,17 @@ 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
* @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
* 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,
@ -118,11 +118,11 @@ int sem_timedwait( sem_t * sem,
* @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
* @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.
*/
@ -134,8 +134,8 @@ int sem_trywait( sem_t * sem );
* @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.
*
* @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 );

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -38,7 +38,7 @@
#define _FREERTOS_POSIX_SIGNAL_H_
/**
* @brief Values of sigev_notify.
* @name Values of sigev_notify.
*/
/**@{ */
#define SIGEV_NONE 0 /**< No asynchronous notification is delivered when the event of interest occurs. */
@ -60,11 +60,11 @@ union sigval
*/
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. */
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_ */

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -36,126 +36,156 @@
/* C standard library includes. */
#include <stdint.h>
/* FreeRTOS types include */
#include "FreeRTOS_POSIX_types.h"
/**
* @brief Used for system times in clock ticks or CLOCKS_PER_SEC.
* @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;
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;
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;
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;
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;
typedef PthreadAttrType_t pthread_attr_t;
#endif
/**
* @brief Used to identify a barrier.
*
* Enabled/disabled by posixconfigENABLE_PTHREAD_BARRIER_T.
*/
typedef void * pthread_barrier_t;
#if !defined( posixconfigENABLE_PTHREAD_BARRIER_T ) || ( posixconfigENABLE_PTHREAD_BARRIER_T == 1 )
typedef PthreadBarrierType_t pthread_barrier_t;
#endif
/**
* @brief Used to define a barrier attributes object.
*/
typedef void * pthread_barrierattr_t;
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;
typedef PthreadCondType_t 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;
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;
typedef PthreadMutexType_t 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;
typedef PthreadMutexAttrType_t pthread_mutexattr_t;
#endif
/**
* @brief Used to identify a thread.
* Enabled/disabled by posixconfigENABLE_PTHREAD_T
*
* Enabled/disabled by posixconfigENABLE_PTHREAD_T.
*/
#if !defined( posixconfigENABLE_PTHREAD_T ) || ( posixconfigENABLE_PTHREAD_T == 1 )
typedef void * pthread_t;
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;
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;
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;
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;
typedef unsigned long useconds_t;
#endif
/**
* @brief Used for file sizes.
*
* Enabled/disabled by posixconfigENABLE_OFF_T.
*/
#if !defined( posixconfigENABLE_OFF_T ) || ( posixconfigENABLE_OFF_T == 1 )
typedef long int off_t;
#endif
#endif /* ifndef _FREERTOS_POSIX_TYPES_H_ */

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -38,7 +38,7 @@
#include "FreeRTOS_POSIX/signal.h"
/**
* @brief Unit conversion constants.
* @name Unit conversion constants.
*/
/**@{ */
#define MICROSECONDS_PER_SECOND ( 1000000LL ) /**< Microseconds per second. */
@ -47,7 +47,7 @@
/**@} */
/**
* @brief Clock identifiers.
* @name Clock identifiers.
*/
/**@{ */
#define CLOCK_REALTIME 0 /**< The identifier of the system-wide clock measuring real time. */
@ -55,21 +55,26 @@
/**@} */
/**
* @brief A number used to convert the value returned by the clock() function into seconds.
* @name 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.
* @name Flag indicating time is absolute.
*
* For functions taking timer objects, this refers to the clock associated with the timer.
*/
#define TIMER_ABSTIME 0x01
/**@{ */
#define TIMER_ABSTIME 0x01
/**@} */
#if !defined( posixconfigENABLE_TIMESPEC ) || ( posixconfigENABLE_TIMESPEC == 1 )
/**
* @brief represents an elapsed time
*/
/**
* @brief represents an elapsed time
*/
struct timespec
{
time_t tv_sec; /**< Seconds. */
@ -78,9 +83,10 @@
#endif
#if !defined( posixconfigENABLE_ITIMERSPEC ) || ( posixconfigENABLE_ITIMERSPEC == 1 )
/**
* @brief timer
*/
/**
* @brief timer
*/
struct itimerspec
{
struct timespec it_interval; /**< Timer period. */
@ -88,33 +94,14 @@
};
#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.
*
* 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 );
@ -125,7 +112,7 @@ clock_t clock( void );
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getcpuclockid.html
*
* @retval EPERM
*
*
* @note This function is currently unsupported.
*
*/
@ -152,9 +139,8 @@ int clock_getres( clockid_t clock_id,
*
* @note clock_id is ignored
* @note this function does not check for overflows of time_t.
*
* @retval 0 - Upon successful completion.
*
* @retval 0 - Upon successful completion.
*/
int clock_gettime( clockid_t clock_id,
struct timespec * tp );
@ -164,9 +150,9 @@ int clock_gettime( clockid_t clock_id,
*
* 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 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.
* @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.
@ -181,32 +167,13 @@ int clock_nanosleep( clockid_t clock_id,
*
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_settime.html
*
* @retval -1 with errno set to EPERM.
*
* @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.
*
@ -216,50 +183,23 @@ struct tm * localtime_r( const time_t * timer,
*
* @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 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
* @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>
@ -303,11 +243,11 @@ int timer_gettime( timer_t timerid,
* 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
* @retval -1 - An error occurred, 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,
* 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,

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -33,16 +33,18 @@
#ifndef _FREERTOS_POSIX_UNISTD_H_
#define _FREERTOS_POSIX_UNISTD_H_
#include "FreeRTOS_POSIX/sys/types.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.
* @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 );
@ -52,7 +54,7 @@ unsigned sleep( unsigned seconds );
* This is a useful, non-POSIX function.
* @param[in] usec The number of microseconds to suspend execution.
*
* @retval 0 - Upon successful cocmpletion.
* @retval 0 - Upon successful completion.
*/
int usleep( useconds_t usec );

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS+POSIX V1.0.0
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS POSIX V1.1.0
* Copyright (C) 2019 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
@ -55,20 +55,23 @@ size_t UTILS_strnlen( const char * const pcString,
*
* @param[in] pxAbsoluteTime A time in the future, specified as seconds and
* nanoseconds since CLOCK_REALTIME's 0.
* @param[in] pxCurrentTime current time, specified as seconds and
* nanoseconds.
* @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 );
int UTILS_AbsoluteTimespecToDeltaTicks( const struct timespec * const pxAbsoluteTime,
const struct timespec * const pxCurrentTime,
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
* @param[out] 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.
@ -90,51 +93,63 @@ void UTILS_NanosecondsToTimespec( int64_t llSource,
/**
* @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.
* @param[out] pxResult Where the result of the calculation is stored.
*
* @return -1 if any argument was NULL; 1 if result is negative; otherwise, 0.
* @return -1 if any argument was NULL; 1 if result is negative (overflow); otherwise, 0.
*/
int UTILS_TimespecAdd( struct timespec * const pxResult,
const struct timespec * const x,
const struct timespec * const y );
int UTILS_TimespecAdd( const struct timespec * const x,
const struct timespec * const y,
struct timespec * const pxResult );
/**
* @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.
* @param[out] pxResult Where the result of the calculation is stored.
*
* @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 );
int UTILS_TimespecAddNanoseconds( const struct timespec * const x,
int64_t llNanoseconds,
struct timespec * const pxResult );
/**
* @brief Calculates pxResult = x - y.
* @brief Calculates pxResult = x - y. If the result is negative contents of
* pResult are undefined
*
* @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.
* @param[out] pxResult Where the result of the calculation is stored.
*
* @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 );
int UTILS_TimespecSubtract( const struct timespec * const x,
const struct timespec * const y,
struct timespec * const pxResult );
/**
* @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);
* @brief Compare x == y.
*
* @param[in] x The first argument for comparison.
* @param[in] y The second argument for comparison.
*
* @return 0 if x == y; 1 if x > y; -1 if x < y or any argument was NULL
*/
int UTILS_TimespecCompare( 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_ */

View File

@ -1,6 +1,6 @@
/*
* Amazon FreeRTOS
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Amazon FreeRTOS Common 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
@ -23,9 +23,8 @@
* http://www.FreeRTOS.org
*/
/**
* @file aws_doubly_linked_list.h
* @file iot_doubly_linked_list.h
* @brief Doubly Linked List implementation.
*
* A generic implementation of circular Doubly Linked List which consists of a

View File

@ -73,6 +73,7 @@
/* System headers. */
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
/* Demo includes. */
#include "posix_demo.h"
@ -270,11 +271,14 @@ static void * prvDispatcherThread( void * pvArgs )
*
* See the top of this file for detailed description.
*/
void vStartPOSIXDemo( void )
void vStartPOSIXDemo( void *pvParameters )
{
int i = 0;
int iStatus = 0;
/* Remove warnings about unused parameters. */
( void ) pvParameters;
/* Handles of the threads and related resources. */
DispatcherThreadResources_t pxDispatcher = { 0 };
WorkerThreadResources_t pxWorkers[ MQUEUE_NUMBER_OF_WORKERS ] = { { 0 } };
@ -363,4 +367,8 @@ void vStartPOSIXDemo( void )
{
printf( "Queues did not get initialized properly. Did not run demo. %s", LINE_BREAK );
}
/* This task was created with the native xTaskCreate() API function, so
must not run off the end of its implementing thread. */
vTaskDelete( NULL );
}

View File

@ -1,351 +0,0 @@
/*
* 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;
}

View File

@ -1,105 +0,0 @@
/*
* 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 */

View File

@ -1,32 +0,0 @@
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.

View File

@ -1,19 +0,0 @@
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.

View File

@ -1,4 +0,0 @@
Contains source and header files that implement FreeRTOS+CLI. See
http://www.FreeRTOS.org/cli for documentation and license information.

View File

@ -1,5 +0,0 @@
[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

View File

@ -1,7 +0,0 @@
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

View File

@ -1,653 +0,0 @@
/*
* 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 ) */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,199 +0,0 @@
/*
* 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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,378 +0,0 @@
/*
* 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;
}
/*-----------------------------------------------------------*/

View File

@ -1,187 +0,0 @@
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.

View File

@ -1,19 +0,0 @@
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.

View File

@ -1,5 +0,0 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
URL=http://www.freertos.org/tcp
IDList=

View File

@ -1,560 +0,0 @@
/*
* 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 */

View File

@ -1,141 +0,0 @@
/*
* 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 */

View File

@ -1,87 +0,0 @@
/*
* 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 */

View File

@ -1,133 +0,0 @@
/*
* 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 */

View File

@ -1,328 +0,0 @@
/*
* 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 */

View File

@ -1,827 +0,0 @@
/*
* 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 */

View File

@ -1,393 +0,0 @@
/*
* 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 */

View File

@ -1,256 +0,0 @@
/*
* 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 ) */

View File

@ -1,80 +0,0 @@
/*
* 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 */

View File

@ -1,210 +0,0 @@
/*
* 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 */

View File

@ -1,90 +0,0 @@
/*
* 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 */

View File

@ -1,193 +0,0 @@
/*
* 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 */

View File

@ -1,70 +0,0 @@
/*
* 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 */

View File

@ -1,423 +0,0 @@
/*
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
*/
/******************************************************************************
*
* See the following web page for essential buffer allocation scheme usage and
* configuration details:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
*
******************************************************************************/
/* Standard includes. */
#include <stdint.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkInterface.h"
#include "NetworkBufferManagement.h"
/* For an Ethernet interrupt to be able to obtain a network buffer there must
be at least this number of buffers available. */
#define baINTERRUPT_BUFFER_GET_THRESHOLD ( 3 )
/* A list of free (available) NetworkBufferDescriptor_t structures. */
static List_t xFreeBuffersList;
/* Some statistics about the use of buffers. */
static UBaseType_t uxMinimumFreeNetworkBuffers = 0u;
/* Declares the pool of NetworkBufferDescriptor_t structures that are available
to the system. All the network buffers referenced from xFreeBuffersList exist
in this array. The array is not accessed directly except during initialisation,
when the xFreeBuffersList is filled (as all the buffers are free when the system
is booted). */
static NetworkBufferDescriptor_t xNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
/* This constant is defined as true to let FreeRTOS_TCP_IP.c know that the
network buffers have constant size, large enough to hold the biggest Ethernet
packet. No resizing will be done. */
const BaseType_t xBufferAllocFixedSize = pdTRUE;
/* The semaphore used to obtain network buffers. */
static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
#if( ipconfigTCP_IP_SANITY != 0 )
static char cIsLow = pdFALSE;
UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
#else
static UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
#endif /* ipconfigTCP_IP_SANITY */
static void prvShowWarnings( void );
/* The user can define their own ipconfigBUFFER_ALLOC_LOCK() and
ipconfigBUFFER_ALLOC_UNLOCK() macros, especially for use form an ISR. If these
are not defined then default them to call the normal enter/exit critical
section macros. */
#if !defined( ipconfigBUFFER_ALLOC_LOCK )
#define ipconfigBUFFER_ALLOC_INIT( ) do {} while (0)
#define ipconfigBUFFER_ALLOC_LOCK_FROM_ISR() \
UBaseType_t uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
{
#define ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR() \
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
}
#define ipconfigBUFFER_ALLOC_LOCK() taskENTER_CRITICAL()
#define ipconfigBUFFER_ALLOC_UNLOCK() taskEXIT_CRITICAL()
#endif /* ipconfigBUFFER_ALLOC_LOCK */
/*-----------------------------------------------------------*/
#if( ipconfigTCP_IP_SANITY != 0 )
/* HT: SANITY code will be removed as soon as the library is stable
* and and ready to become public
* Function below gives information about the use of buffers */
#define WARN_LOW ( 2 )
#define WARN_HIGH ( ( 5 * ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) / 10 )
#endif /* ipconfigTCP_IP_SANITY */
/*-----------------------------------------------------------*/
#if( ipconfigTCP_IP_SANITY != 0 )
BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr )
{
return ( bIsValidNetworkDescriptor( pxDescr ) != 0 ) &&
( listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxDescr->xBufferListItem ) ) != 0 );
}
/*-----------------------------------------------------------*/
static void prvShowWarnings( void )
{
UBaseType_t uxCount = uxGetNumberOfFreeNetworkBuffers( );
if( ( ( cIsLow == 0 ) && ( uxCount <= WARN_LOW ) ) || ( ( cIsLow != 0 ) && ( uxCount >= WARN_HIGH ) ) )
{
cIsLow = !cIsLow;
FreeRTOS_debug_printf( ( "*** Warning *** %s %lu buffers left\n", cIsLow ? "only" : "now", uxCount ) );
}
}
/*-----------------------------------------------------------*/
UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
{
uint32_t offset = ( uint32_t ) ( ((const char *)pxDesc) - ((const char *)xNetworkBuffers) );
if( ( offset >= sizeof( xNetworkBuffers ) ) ||
( ( offset % sizeof( xNetworkBuffers[0] ) ) != 0 ) )
return pdFALSE;
return (UBaseType_t) (pxDesc - xNetworkBuffers) + 1;
}
/*-----------------------------------------------------------*/
#else
static UBaseType_t bIsValidNetworkDescriptor (const NetworkBufferDescriptor_t * pxDesc)
{
( void ) pxDesc;
return ( UBaseType_t ) pdTRUE;
}
/*-----------------------------------------------------------*/
static void prvShowWarnings( void )
{
}
/*-----------------------------------------------------------*/
#endif /* ipconfigTCP_IP_SANITY */
BaseType_t xNetworkBuffersInitialise( void )
{
BaseType_t xReturn, x;
/* Only initialise the buffers and their associated kernel objects if they
have not been initialised before. */
if( xNetworkBufferSemaphore == NULL )
{
/* In case alternative locking is used, the mutexes can be initialised
here */
ipconfigBUFFER_ALLOC_INIT();
xNetworkBufferSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
configASSERT( xNetworkBufferSemaphore );
if( xNetworkBufferSemaphore != NULL )
{
vListInitialise( &xFreeBuffersList );
/* Initialise all the network buffers. The buffer storage comes
from the network interface, and different hardware has different
requirements. */
vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers );
for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
{
/* Initialise and set the owner of the buffer list items. */
vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) );
listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] );
/* Currently, all buffers are available for use. */
vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) );
}
uxMinimumFreeNetworkBuffers = ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
}
}
if( xNetworkBufferSemaphore == NULL )
{
xReturn = pdFAIL;
}
else
{
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
{
NetworkBufferDescriptor_t *pxReturn = NULL;
BaseType_t xInvalid = pdFALSE;
UBaseType_t uxCount;
/* The current implementation only has a single size memory block, so
the requested size parameter is not used (yet). */
( void ) xRequestedSizeBytes;
if( xNetworkBufferSemaphore != NULL )
{
/* If there is a semaphore available, there is a network buffer
available. */
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
{
/* Protect the structure as they are accessed from tasks and
interrupts. */
ipconfigBUFFER_ALLOC_LOCK();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
if( ( bIsValidNetworkDescriptor( pxReturn ) != pdFALSE_UNSIGNED ) &&
listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) )
{
uxListRemove( &( pxReturn->xBufferListItem ) );
}
else
{
xInvalid = pdTRUE;
}
}
ipconfigBUFFER_ALLOC_UNLOCK();
if( xInvalid == pdTRUE )
{
/* _RB_ Can printf() be called from an interrupt? (comment
above says this can be called from an interrupt too) */
/* _HT_ The function shall not be called from an ISR. Comment
was indeed misleading. Hopefully clear now?
So the printf()is OK here. */
FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n",
pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) );
pxReturn = NULL;
}
else
{
/* Reading UBaseType_t, no critical section needed. */
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
/* For stats, latch the lowest number of network buffers since
booting. */
if( uxMinimumFreeNetworkBuffers > uxCount )
{
uxMinimumFreeNetworkBuffers = uxCount;
}
pxReturn->xDataLength = xRequestedSizeBytes;
#if( ipconfigTCP_IP_SANITY != 0 )
{
prvShowWarnings();
}
#endif /* ipconfigTCP_IP_SANITY */
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
/* make sure the buffer is not linked */
pxReturn->pxNextBuffer = NULL;
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
if( xTCPWindowLoggingLevel > 3 )
{
FreeRTOS_debug_printf( ( "BUF_GET[%ld]: %p (%p)\n",
bIsValidNetworkDescriptor( pxReturn ),
pxReturn, pxReturn->pucEthernetBuffer ) );
}
}
iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
}
else
{
iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
}
}
return pxReturn;
}
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t *pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes )
{
NetworkBufferDescriptor_t *pxReturn = NULL;
/* The current implementation only has a single size memory block, so
the requested size parameter is not used (yet). */
( void ) xRequestedSizeBytes;
/* If there is a semaphore available then there is a buffer available, but,
as this is called from an interrupt, only take a buffer if there are at
least baINTERRUPT_BUFFER_GET_THRESHOLD buffers remaining. This prevents,
to a certain degree at least, a rapidly executing interrupt exhausting
buffer and in so doing preventing tasks from continuing. */
if( uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) xNetworkBufferSemaphore ) > ( UBaseType_t ) baINTERRUPT_BUFFER_GET_THRESHOLD )
{
if( xSemaphoreTakeFromISR( xNetworkBufferSemaphore, NULL ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and interrupts. */
ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
uxListRemove( &( pxReturn->xBufferListItem ) );
}
ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxReturn );
}
}
if( pxReturn == NULL )
{
iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR();
}
return pxReturn;
}
/*-----------------------------------------------------------*/
BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Ensure the buffer is returned to the list of free buffers before the
counting semaphore is 'given' to say a buffer is available. */
ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
{
vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
}
ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
xSemaphoreGiveFromISR( xNetworkBufferSemaphore, &xHigherPriorityTaskWoken );
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
return xHigherPriorityTaskWoken;
}
/*-----------------------------------------------------------*/
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xListItemAlreadyInFreeList;
if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED )
{
FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) );
return ;
}
/* Ensure the buffer is returned to the list of free buffers before the
counting semaphore is 'given' to say a buffer is available. */
ipconfigBUFFER_ALLOC_LOCK();
{
{
xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
if( xListItemAlreadyInFreeList == pdFALSE )
{
vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
}
}
}
ipconfigBUFFER_ALLOC_UNLOCK();
if( xListItemAlreadyInFreeList )
{
FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n",
pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) );
}
if( xListItemAlreadyInFreeList == pdFALSE )
{
xSemaphoreGive( xNetworkBufferSemaphore );
prvShowWarnings();
if( xTCPWindowLoggingLevel > 3 )
FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n",
bIsValidNetworkDescriptor( pxNetworkBuffer ),
pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer,
uxGetNumberOfFreeNetworkBuffers( ) ) );
}
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
/*-----------------------------------------------------------*/
UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
{
return uxMinimumFreeNetworkBuffers;
}
/*-----------------------------------------------------------*/
UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
{
return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
}
NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
{
/* In BufferAllocation_1.c all network buffer are allocated with a
maximum size of 'ipTOTAL_ETHERNET_FRAME_SIZE'.No need to resize the
network buffer. */
( void ) xNewSizeBytes;
return pxNetworkBuffer;
}
/*#endif */ /* ipconfigINCLUDE_TEST_CODE */

View File

@ -1,390 +0,0 @@
/*
* 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!
*/
/******************************************************************************
*
* See the following web page for essential buffer allocation scheme usage and
* configuration details:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
*
******************************************************************************/
/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
heap_4 can be used. */
/* Standard includes. */
#include <stdint.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkInterface.h"
#include "NetworkBufferManagement.h"
/* The obtained network buffer must be large enough to hold a packet that might
replace the packet that was requested to be sent. */
#if ipconfigUSE_TCP == 1
#define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
#else
#define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
#endif /* ipconfigUSE_TCP == 1 */
/*_RB_ This is too complex not to have an explanation. */
#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
#define STATIC_ASSERT(e) \
;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
#endif
/* A list of free (available) NetworkBufferDescriptor_t structures. */
static List_t xFreeBuffersList;
/* Some statistics about the use of buffers. */
static size_t uxMinimumFreeNetworkBuffers;
/* Declares the pool of NetworkBufferDescriptor_t structures that are available
to the system. All the network buffers referenced from xFreeBuffersList exist
in this array. The array is not accessed directly except during initialisation,
when the xFreeBuffersList is filled (as all the buffers are free when the system
is booted). */
static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
network buffers have a variable size: resizing may be necessary */
const BaseType_t xBufferAllocFixedSize = pdFALSE;
/* The semaphore used to obtain network buffers. */
static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
/*-----------------------------------------------------------*/
BaseType_t xNetworkBuffersInitialise( void )
{
BaseType_t xReturn, x;
/* Only initialise the buffers and their associated kernel objects if they
have not been initialised before. */
if( xNetworkBufferSemaphore == NULL )
{
xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
configASSERT( xNetworkBufferSemaphore );
if( xNetworkBufferSemaphore != NULL )
{
#if ( configQUEUE_REGISTRY_SIZE > 0 )
{
vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
}
#endif /* configQUEUE_REGISTRY_SIZE */
/* If the trace recorder code is included name the semaphore for viewing
in FreeRTOS+Trace. */
#if( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
{
extern QueueHandle_t xNetworkEventQueue;
vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
}
#endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
vListInitialise( &xFreeBuffersList );
/* Initialise all the network buffers. No storage is allocated to
the buffers yet. */
for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
{
/* Initialise and set the owner of the buffer list items. */
xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
/* Currently, all buffers are available for use. */
vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
}
uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
}
}
if( xNetworkBufferSemaphore == NULL )
{
xReturn = pdFAIL;
}
else
{
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes )
{
uint8_t *pucEthernetBuffer;
size_t xSize = *pxRequestedSizeBytes;
if( xSize < baMINIMAL_BUFFER_SIZE )
{
/* Buffers must be at least large enough to hold a TCP-packet with
headers, or an ARP packet, in case TCP is not included. */
xSize = baMINIMAL_BUFFER_SIZE;
}
/* Round up xSize to the nearest multiple of N bytes,
where N equals 'sizeof( size_t )'. */
if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
{
xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
}
*pxRequestedSizeBytes = xSize;
/* Allocate a buffer large enough to store the requested Ethernet frame size
and a pointer to a network buffer structure (hence the addition of
ipBUFFER_PADDING bytes). */
pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
configASSERT( pucEthernetBuffer );
if( pucEthernetBuffer != NULL )
{
/* Enough space is left at the start of the buffer to place a pointer to
the network buffer structure that references this Ethernet buffer.
Return a pointer to the start of the Ethernet buffer itself. */
pucEthernetBuffer += ipBUFFER_PADDING;
}
return pucEthernetBuffer;
}
/*-----------------------------------------------------------*/
void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer )
{
/* There is space before the Ethernet buffer in which a pointer to the
network buffer that references this Ethernet buffer is stored. Remove the
space before freeing the buffer. */
if( pucEthernetBuffer != NULL )
{
pucEthernetBuffer -= ipBUFFER_PADDING;
vPortFree( ( void * ) pucEthernetBuffer );
}
}
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
{
NetworkBufferDescriptor_t *pxReturn = NULL;
size_t uxCount;
if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
{
/* ARP packets can replace application packets, so the storage must be
at least large enough to hold an ARP. */
xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
}
/* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
xRequestedSizeBytes += 2u;
if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
{
xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
}
/* If there is a semaphore available, there is a network buffer available. */
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and interrupts. */
taskENTER_CRITICAL();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
uxListRemove( &( pxReturn->xBufferListItem ) );
}
taskEXIT_CRITICAL();
/* Reading UBaseType_t, no critical section needed. */
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
if( uxMinimumFreeNetworkBuffers > uxCount )
{
uxMinimumFreeNetworkBuffers = uxCount;
}
/* Allocate storage of exactly the requested size to the buffer. */
configASSERT( pxReturn->pucEthernetBuffer == NULL );
if( xRequestedSizeBytes > 0 )
{
/* Extra space is obtained so a pointer to the network buffer can
be stored at the beginning of the buffer. */
pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
if( pxReturn->pucEthernetBuffer == NULL )
{
/* The attempt to allocate storage for the buffer payload failed,
so the network buffer structure cannot be used and must be
released. */
vReleaseNetworkBufferAndDescriptor( pxReturn );
pxReturn = NULL;
}
else
{
/* Store a pointer to the network buffer structure in the
buffer storage area, then move the buffer pointer on past the
stored pointer so the pointer value is not overwritten by the
application when the buffer is used. */
*( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
/* Store the actual size of the allocated buffer, which may be
greater than the original requested size. */
pxReturn->xDataLength = xRequestedSizeBytes;
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
/* make sure the buffer is not linked */
pxReturn->pxNextBuffer = NULL;
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
}
}
else
{
/* A descriptor is being returned without an associated buffer being
allocated. */
}
}
if( pxReturn == NULL )
{
iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
}
else
{
iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
}
return pxReturn;
}
/*-----------------------------------------------------------*/
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xListItemAlreadyInFreeList;
/* Ensure the buffer is returned to the list of free buffers before the
counting semaphore is 'given' to say a buffer is available. Release the
storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
pxNetworkBuffer->pucEthernetBuffer = NULL;
taskENTER_CRITICAL();
{
xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
if( xListItemAlreadyInFreeList == pdFALSE )
{
vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
}
}
taskEXIT_CRITICAL();
/*
* Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
* The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
*/
if( xListItemAlreadyInFreeList == pdFALSE )
{
if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
{
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
}
else
{
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
}
/*-----------------------------------------------------------*/
/*
* Returns the number of free network buffers
*/
UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
{
return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
}
/*-----------------------------------------------------------*/
UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
{
return uxMinimumFreeNetworkBuffers;
}
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
{
size_t xOriginalLength;
uint8_t *pucBuffer;
xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
if( pucBuffer == NULL )
{
/* In case the allocation fails, return NULL. */
pxNetworkBuffer = NULL;
}
else
{
pxNetworkBuffer->xDataLength = xNewSizeBytes;
if( xNewSizeBytes > xOriginalLength )
{
xNewSizeBytes = xOriginalLength;
}
memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
}
return pxNetworkBuffer;
}

View File

@ -1,46 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
__attribute__( (packed) );

View File

@ -1,48 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
/* Nothing to do here. */

View File

@ -1,49 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
__packed

View File

@ -1,48 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
;
#pragma pack( pop )

View File

@ -1,47 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
#pragma pack( push, 1 )

View File

@ -1,54 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
#ifdef _SH
#ifdef __RENESAS__
;
#pragma unpack
#endif
#endif

View File

@ -1,53 +0,0 @@
/*
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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
#ifdef _SH
#ifdef __RENESAS__
#pragma pack 1
#endif
#endif

View File

@ -1,649 +0,0 @@
/*
* 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"
#include "queue.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
/* Some files from the Atmel Software Framework */
/*_RB_ The SAM4E portable layer has three different header files called gmac.h! */
#include "instance/gmac.h"
#include <sysclk.h>
#include <ethernet_phy.h>
#ifndef BMSR_LINK_STATUS
#define BMSR_LINK_STATUS 0x0004 //!< Link status
#endif
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
receiving packets. */
#define PHY_LS_HIGH_CHECK_TIME_MS 15000
#endif
#ifndef PHY_LS_LOW_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still low every second. */
#define PHY_LS_LOW_CHECK_TIME_MS 1000
#endif
/* Interrupt events to process. Currently only the Rx event is processed
although code for other events is included to allow for possible future
expansion. */
#define EMAC_IF_RX_EVENT 1UL
#define EMAC_IF_TX_EVENT 2UL
#define EMAC_IF_ERR_EVENT 4UL
#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
#define HZ_PER_MHZ ( 1000000UL )
#ifndef EMAC_MAX_BLOCK_TIME_MS
#define EMAC_MAX_BLOCK_TIME_MS 100ul
#endif
#if !defined( GMAC_USES_TX_CALLBACK ) || ( GMAC_USES_TX_CALLBACK != 1 )
#error Please define GMAC_USES_TX_CALLBACK as 1
#endif
#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
#warning The EMAC of SAM4E has fixed-size RX buffers so ZERO_COPY_RX is not possible
#endif
/* Default the size of the stack used by the EMAC deferred handler task to 4x
the size of the stack used by the idle task - but allow this to be overridden in
FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
#ifndef configEMAC_TASK_STACK_SIZE
#define configEMAC_TASK_STACK_SIZE ( 4 * configMINIMAL_STACK_SIZE )
#endif
/*-----------------------------------------------------------*/
/*
* Wait a fixed time for the link status to indicate the network is up.
*/
static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
void vGMACGenerateChecksum( uint8_t *apBuffer );
#endif
/*
* Called from the ASF GMAC driver.
*/
static void prvRxCallback( uint32_t ulStatus );
static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer );
/*
* A deferred interrupt handler task that processes GMAC interrupts.
*/
static void prvEMACHandlerTask( void *pvParameters );
/*
* Initialise the ASF GMAC driver.
*/
static BaseType_t prvGMACInit( void );
/*
* Try to obtain an Rx packet from the hardware.
*/
static uint32_t prvEMACRxPoll( void );
/*-----------------------------------------------------------*/
/* Bit map of outstanding ETH interrupt events for processing. Currently only
the Rx interrupt is handled, although code is included for other events to
enable future expansion. */
static volatile uint32_t ulISREvents;
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
static uint32_t ulPHYLinkStatus = 0;
static volatile BaseType_t xGMACSwitchRequired;
/* ethernet_phy_addr: the address of the PHY in use.
Atmel was a bit ambiguous about it so the address will be stored
in this variable, see ethernet_phy.c */
extern int ethernet_phy_addr;
/* LLMNR multicast address. */
static const uint8_t llmnr_mac_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
/* The GMAC object as defined by the ASF drivers. */
static gmac_device_t gs_gmac_dev;
/* MAC address to use. */
extern const uint8_t ucMACAddress[ 6 ];
/* Holds the handle of the task used as a deferred interrupt processor. The
handle is used so direct notifications can be sent to the task for all EMAC/DMA
related interrupts. */
TaskHandle_t xEMACTaskHandle = NULL;
static QueueHandle_t xTxBufferQueue;
int tx_release_count[ 4 ];
/* xTXDescriptorSemaphore is a counting semaphore with
a maximum count of GMAC_TX_BUFFERS, which is the number of
DMA TX descriptors. */
static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
/*-----------------------------------------------------------*/
/*
* GMAC interrupt handler.
*/
void GMAC_Handler(void)
{
xGMACSwitchRequired = pdFALSE;
/* gmac_handler() may call prvRxCallback() which may change
the value of xGMACSwitchRequired. */
gmac_handler( &gs_gmac_dev );
if( xGMACSwitchRequired != pdFALSE )
{
portEND_SWITCHING_ISR( xGMACSwitchRequired );
}
}
/*-----------------------------------------------------------*/
static void prvRxCallback( uint32_t ulStatus )
{
if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
{
/* let the prvEMACHandlerTask know that there was an RX event. */
ulISREvents |= EMAC_IF_RX_EVENT;
/* Only an RX interrupt can wakeup prvEMACHandlerTask. */
vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
}
}
/*-----------------------------------------------------------*/
static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer )
{
if( ( xTxBufferQueue != NULL ) && ( xEMACTaskHandle != NULL ) )
{
/* let the prvEMACHandlerTask know that there was an RX event. */
ulISREvents |= EMAC_IF_TX_EVENT;
vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
xQueueSendFromISR( xTxBufferQueue, &puc_buffer, ( BaseType_t * ) &xGMACSwitchRequired );
tx_release_count[ 2 ]++;
}
}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
{
const TickType_t x5_Seconds = 5000UL;
if( xEMACTaskHandle == NULL )
{
prvGMACInit();
/* Wait at most 5 seconds for a Link Status in the PHY. */
xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
/* The handler task is created at the highest possible priority to
ensure the interrupt handler can return directly to it. */
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
configASSERT( xEMACTaskHandle );
}
if( xTxBufferQueue == NULL )
{
xTxBufferQueue = xQueueCreate( GMAC_TX_BUFFERS, sizeof( void * ) );
configASSERT( xTxBufferQueue );
}
if( xTXDescriptorSemaphore == NULL )
{
xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) GMAC_TX_BUFFERS, ( UBaseType_t ) GMAC_TX_BUFFERS );
configASSERT( xTXDescriptorSemaphore );
}
/* When returning non-zero, the stack will become active and
start DHCP (in configured) */
return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
}
/*-----------------------------------------------------------*/
BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xResult;
/* This function returns true if the Link Status in the PHY is high. */
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
xResult = pdTRUE;
}
else
{
xResult = pdFALSE;
}
return xResult;
}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
{
/* Do not wait too long for a free TX DMA buffer. */
const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
do {
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
{
/* Do not attempt to send packets as long as the Link Status is low. */
break;
}
if( xTXDescriptorSemaphore == NULL )
{
/* Semaphore has not been created yet? */
break;
}
if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
{
/* Time-out waiting for a free TX descriptor. */
tx_release_count[ 3 ]++;
break;
}
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
/* Confirm that the pxDescriptor may be kept by the driver. */
configASSERT( bReleaseAfterSend != pdFALSE );
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
gmac_dev_write( &gs_gmac_dev, (void *)pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, prvTxCallback );
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
/* Confirm that the pxDescriptor may be kept by the driver. */
bReleaseAfterSend = pdFALSE;
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
/* Not interested in a call-back after TX. */
iptraceNETWORK_INTERFACE_TRANSMIT();
} while( 0 );
if( bReleaseAfterSend != pdFALSE )
{
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
return pdTRUE;
}
/*-----------------------------------------------------------*/
static BaseType_t prvGMACInit( void )
{
uint32_t ncfgr;
gmac_options_t gmac_option;
memset( &gmac_option, '\0', sizeof( gmac_option ) );
gmac_option.uc_copy_all_frame = 0;
gmac_option.uc_no_boardcast = 0;
memcpy( gmac_option.uc_mac_addr, ucMACAddress, sizeof( gmac_option.uc_mac_addr ) );
gs_gmac_dev.p_hw = GMAC;
gmac_dev_init( GMAC, &gs_gmac_dev, &gmac_option );
NVIC_SetPriority( GMAC_IRQn, configMAC_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( GMAC_IRQn );
/* Contact the Ethernet PHY and store it's address in 'ethernet_phy_addr' */
ethernet_phy_init( GMAC, ETHERNET_CONF_PHY_ADDR, sysclk_get_cpu_hz() );
ethernet_phy_auto_negotiate( GMAC, ethernet_phy_addr );
ethernet_phy_set_link( GMAC, ethernet_phy_addr, 1 );
/* The GMAC driver will call a hook prvRxCallback(), which
in turn will wake-up the task by calling vTaskNotifyGiveFromISR() */
gmac_dev_set_rx_callback( &gs_gmac_dev, prvRxCallback );
gmac_set_address( GMAC, 1, (uint8_t*)llmnr_mac_address );
ncfgr = GMAC_NCFGR_SPD | GMAC_NCFGR_FD;
GMAC->GMAC_NCFGR = ( GMAC->GMAC_NCFGR & ~( GMAC_NCFGR_SPD | GMAC_NCFGR_FD ) ) | ncfgr;
return 1;
}
/*-----------------------------------------------------------*/
static inline unsigned long ulReadMDIO( unsigned /*short*/ usAddress )
{
uint32_t ulValue, ulReturn;
int rc;
gmac_enable_management( GMAC, 1 );
rc = gmac_phy_read( GMAC, ethernet_phy_addr, usAddress, &ulValue );
gmac_enable_management( GMAC, 0 );
if( rc == GMAC_OK )
{
ulReturn = ulValue;
}
else
{
ulReturn = 0UL;
}
return ulReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
{
TickType_t xStartTime = xTaskGetTickCount();
TickType_t xEndTime;
BaseType_t xReturn;
const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
for( ;; )
{
xEndTime = xTaskGetTickCount();
if( ( xEndTime - xStartTime ) > xMaxTime )
{
/* Wated more than xMaxTime, return. */
xReturn = pdFALSE;
break;
}
/* Check the link status again. */
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
/* Link is up - return. */
xReturn = pdTRUE;
break;
}
/* Link is down - wait in the Blocked state for a short while (to allow
other tasks to execute) before checking again. */
vTaskDelay( xShortTime );
}
FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
xReturn,
ethernet_phy_addr,
sysclk_get_cpu_hz() / HZ_PER_MHZ ) );
return xReturn;
}
/*-----------------------------------------------------------*/
//#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
void vGMACGenerateChecksum( uint8_t *apBuffer )
{
ProtocolPacket_t *xProtPacket = (ProtocolPacket_t *)apBuffer;
if ( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
{
IPHeader_t *pxIPHeader = &( xProtPacket->xTCPPacket.xIPHeader );
/* Calculate the IP header checksum. */
pxIPHeader->usHeaderChecksum = 0x00;
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0u, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
/* Calculate the TCP checksum for an outgoing packet. */
usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, pdTRUE );
}
}
//#endif
/*-----------------------------------------------------------*/
static uint32_t prvEMACRxPoll( void )
{
unsigned char *pucUseBuffer;
uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
static NetworkBufferDescriptor_t *pxNextNetworkBufferDescriptor = NULL;
const UBaseType_t xMinDescriptorsToLeave = 2UL;
const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
for( ;; )
{
/* If pxNextNetworkBufferDescriptor was not left pointing at a valid
descriptor then allocate one now. */
if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
{
pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
}
if( pxNextNetworkBufferDescriptor != NULL )
{
/* Point pucUseBuffer to the buffer pointed to by the descriptor. */
pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
}
else
{
/* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
messages will be flushed and ignored. */
pucUseBuffer = NULL;
}
/* Read the next packet from the hardware into pucUseBuffer. */
ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount );
if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
{
/* No data from the hardware. */
break;
}
if( pxNextNetworkBufferDescriptor == NULL )
{
/* Data was read from the hardware, but no descriptor was available
for it, so it will be dropped. */
iptraceETHERNET_RX_EVENT_LOST();
continue;
}
iptraceNETWORK_INTERFACE_RECEIVE();
pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;
/* Send the descriptor to the IP task for processing. */
if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
{
/* The buffer could not be sent to the stack so must be released
again. */
vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
iptraceETHERNET_RX_EVENT_LOST();
FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
}
/* Now the buffer has either been passed to the IP-task,
or it has been released in the code above. */
pxNextNetworkBufferDescriptor = NULL;
ulReturnValue++;
}
return ulReturnValue;
}
/*-----------------------------------------------------------*/
void vCheckBuffersAndQueue( void )
{
static UBaseType_t uxLastMinBufferCount = 0;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
static UBaseType_t uxLastMinQueueSpace;
#endif
static UBaseType_t uxCurrentCount;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
uxCurrentCount = uxGetMinimumIPQueueSpace();
if( uxLastMinQueueSpace != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinQueueSpace = uxCurrentCount;
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
}
}
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
}
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxCount;
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
NetworkBufferDescriptor_t *pxBuffer;
#endif
uint8_t *pucBuffer;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
configASSERT( xEMACTaskHandle );
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
for( ;; )
{
vCheckBuffersAndQueue();
if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
{
/* No events to process now, wait for the next. */
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
}
if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
{
ulISREvents &= ~EMAC_IF_RX_EVENT;
/* Wait for the EMAC interrupt to indicate that another packet has been
received. */
xResult = prvEMACRxPoll();
}
if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
{
/* Future extension: code to release TX buffers if zero-copy is used. */
ulISREvents &= ~EMAC_IF_TX_EVENT;
while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
{
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
if( pxBuffer != NULL )
{
vReleaseNetworkBufferAndDescriptor( pxBuffer );
tx_release_count[ 0 ]++;
}
else
{
tx_release_count[ 1 ]++;
}
}
#else
{
tx_release_count[ 0 ]++;
}
#endif
uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
if( uxCount < GMAC_TX_BUFFERS )
{
/* Tell the counting semaphore that one more TX descriptor is available. */
xSemaphoreGive( xTXDescriptorSemaphore );
}
}
}
if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
{
/* Future extension: logging about errors that occurred. */
ulISREvents &= ~EMAC_IF_ERR_EVENT;
}
if( xResult > 0 )
{
/* A packet was received. No need to check for the PHY status now,
but set a timer to check it later on. */
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
xResult = 0;
}
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
{
/* Check the link status again. */
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
{
ulPHYLinkStatus = xStatus;
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
}
vTaskSetTimeOutState( &xPhyTime );
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
}
else
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
}
}
}
}
/*-----------------------------------------------------------*/

View File

@ -1,746 +0,0 @@
/**
* \file
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _SAM4E_GMAC_COMPONENT_
#define _SAM4E_GMAC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Gigabit Ethernet MAC */
/* ============================================================================= */
/** \addtogroup SAM4E_GMAC Gigabit Ethernet MAC */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief GmacSa hardware registers */
typedef struct {
RwReg GMAC_SAB; /**< \brief (GmacSa Offset: 0x0) Specific Address 1 Bottom [31:0] Register */
RwReg GMAC_SAT; /**< \brief (GmacSa Offset: 0x4) Specific Address 1 Top [47:32] Register */
} GmacSa;
/** \brief Gmac hardware registers */
#define GMACSA_NUMBER 4
typedef struct {
RwReg GMAC_NCR; /**< \brief (Gmac Offset: 0x000) Network Control Register */
RwReg GMAC_NCFGR; /**< \brief (Gmac Offset: 0x004) Network Configuration Register */
RoReg GMAC_NSR; /**< \brief (Gmac Offset: 0x008) Network Status Register */
RwReg GMAC_UR; /**< \brief (Gmac Offset: 0x00C) User Register */
RwReg GMAC_DCFGR; /**< \brief (Gmac Offset: 0x010) DMA Configuration Register */
RwReg GMAC_TSR; /**< \brief (Gmac Offset: 0x014) Transmit Status Register */
RwReg GMAC_RBQB; /**< \brief (Gmac Offset: 0x018) Receive Buffer Queue Base Address */
RwReg GMAC_TBQB; /**< \brief (Gmac Offset: 0x01C) Transmit Buffer Queue Base Address */
RwReg GMAC_RSR; /**< \brief (Gmac Offset: 0x020) Receive Status Register */
RoReg GMAC_ISR; /**< \brief (Gmac Offset: 0x024) Interrupt Status Register */
WoReg GMAC_IER; /**< \brief (Gmac Offset: 0x028) Interrupt Enable Register */
WoReg GMAC_IDR; /**< \brief (Gmac Offset: 0x02C) Interrupt Disable Register */
RoReg GMAC_IMR; /**< \brief (Gmac Offset: 0x030) Interrupt Mask Register */
RwReg GMAC_MAN; /**< \brief (Gmac Offset: 0x034) PHY Maintenance Register */
RoReg GMAC_RPQ; /**< \brief (Gmac Offset: 0x038) Received Pause Quantum Register */
RwReg GMAC_TPQ; /**< \brief (Gmac Offset: 0x03C) Transmit Pause Quantum Register */
RwReg GMAC_TPSF; /**< \brief (Gmac Offset: 0x040) TX Partial Store and Forward Register */
RwReg GMAC_RPSF; /**< \brief (Gmac Offset: 0x044) RX Partial Store and Forward Register */
RoReg Reserved1[14];
RwReg GMAC_HRB; /**< \brief (Gmac Offset: 0x080) Hash Register Bottom [31:0] */
RwReg GMAC_HRT; /**< \brief (Gmac Offset: 0x084) Hash Register Top [63:32] */
GmacSa GMAC_SA[GMACSA_NUMBER]; /**< \brief (Gmac Offset: 0x088) 1 .. 4 */
RwReg GMAC_TIDM[4]; /**< \brief (Gmac Offset: 0x0A8) Type ID Match 1 Register */
RwReg GMAC_WOL; /**< \brief (Gmac Offset: 0x0B8) Wake on LAN Register */
RwReg GMAC_IPGS; /**< \brief (Gmac Offset: 0x0BC) IPG Stretch Register */
RwReg GMAC_SVLAN; /**< \brief (Gmac Offset: 0x0C0) Stacked VLAN Register */
RwReg GMAC_TPFCP; /**< \brief (Gmac Offset: 0x0C4) Transmit PFC Pause Register */
RwReg GMAC_SAMB1; /**< \brief (Gmac Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register */
RwReg GMAC_SAMT1; /**< \brief (Gmac Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register */
RoReg Reserved2[12];
RoReg GMAC_OTLO; /**< \brief (Gmac Offset: 0x100) Octets Transmitted [31:0] Register */
RoReg GMAC_OTHI; /**< \brief (Gmac Offset: 0x104) Octets Transmitted [47:32] Register */
RoReg GMAC_FT; /**< \brief (Gmac Offset: 0x108) Frames Transmitted Register */
RoReg GMAC_BCFT; /**< \brief (Gmac Offset: 0x10C) Broadcast Frames Transmitted Register */
RoReg GMAC_MFT; /**< \brief (Gmac Offset: 0x110) Multicast Frames Transmitted Register */
RoReg GMAC_PFT; /**< \brief (Gmac Offset: 0x114) Pause Frames Transmitted Register */
RoReg GMAC_BFT64; /**< \brief (Gmac Offset: 0x118) 64 Byte Frames Transmitted Register */
RoReg GMAC_TBFT127; /**< \brief (Gmac Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register */
RoReg GMAC_TBFT255; /**< \brief (Gmac Offset: 0x120) 128 to 255 Byte Frames Transmitted Register */
RoReg GMAC_TBFT511; /**< \brief (Gmac Offset: 0x124) 256 to 511 Byte Frames Transmitted Register */
RoReg GMAC_TBFT1023; /**< \brief (Gmac Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register */
RoReg GMAC_TBFT1518; /**< \brief (Gmac Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register */
RoReg GMAC_GTBFT1518; /**< \brief (Gmac Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register */
RoReg GMAC_TUR; /**< \brief (Gmac Offset: 0x134) Transmit Under Runs Register */
RoReg GMAC_SCF; /**< \brief (Gmac Offset: 0x138) Single Collision Frames Register */
RoReg GMAC_MCF; /**< \brief (Gmac Offset: 0x13C) Multiple Collision Frames Register */
RoReg GMAC_EC; /**< \brief (Gmac Offset: 0x140) Excessive Collisions Register */
RoReg GMAC_LC; /**< \brief (Gmac Offset: 0x144) Late Collisions Register */
RoReg GMAC_DTF; /**< \brief (Gmac Offset: 0x148) Deferred Transmission Frames Register */
RoReg GMAC_CSE; /**< \brief (Gmac Offset: 0x14C) Carrier Sense Errors Register */
RoReg GMAC_ORLO; /**< \brief (Gmac Offset: 0x150) Octets Received [31:0] Received */
RoReg GMAC_ORHI; /**< \brief (Gmac Offset: 0x154) Octets Received [47:32] Received */
RoReg GMAC_FR; /**< \brief (Gmac Offset: 0x158) Frames Received Register */
RoReg GMAC_BCFR; /**< \brief (Gmac Offset: 0x15C) Broadcast Frames Received Register */
RoReg GMAC_MFR; /**< \brief (Gmac Offset: 0x160) Multicast Frames Received Register */
RoReg GMAC_PFR; /**< \brief (Gmac Offset: 0x164) Pause Frames Received Register */
RoReg GMAC_BFR64; /**< \brief (Gmac Offset: 0x168) 64 Byte Frames Received Register */
RoReg GMAC_TBFR127; /**< \brief (Gmac Offset: 0x16C) 65 to 127 Byte Frames Received Register */
RoReg GMAC_TBFR255; /**< \brief (Gmac Offset: 0x170) 128 to 255 Byte Frames Received Register */
RoReg GMAC_TBFR511; /**< \brief (Gmac Offset: 0x174) 256 to 511Byte Frames Received Register */
RoReg GMAC_TBFR1023; /**< \brief (Gmac Offset: 0x178) 512 to 1023 Byte Frames Received Register */
RoReg GMAC_TBFR1518; /**< \brief (Gmac Offset: 0x17C) 1024 to 1518 Byte Frames Received Register */
RoReg GMAC_TMXBFR; /**< \brief (Gmac Offset: 0x180) 1519 to Maximum Byte Frames Received Register */
RoReg GMAC_UFR; /**< \brief (Gmac Offset: 0x184) Undersize Frames Received Register */
RoReg GMAC_OFR; /**< \brief (Gmac Offset: 0x188) Oversize Frames Received Register */
RoReg GMAC_JR; /**< \brief (Gmac Offset: 0x18C) Jabbers Received Register */
RoReg GMAC_FCSE; /**< \brief (Gmac Offset: 0x190) Frame Check Sequence Errors Register */
RoReg GMAC_LFFE; /**< \brief (Gmac Offset: 0x194) Length Field Frame Errors Register */
RoReg GMAC_RSE; /**< \brief (Gmac Offset: 0x198) Receive Symbol Errors Register */
RoReg GMAC_AE; /**< \brief (Gmac Offset: 0x19C) Alignment Errors Register */
RoReg GMAC_RRE; /**< \brief (Gmac Offset: 0x1A0) Receive Resource Errors Register */
RoReg GMAC_ROE; /**< \brief (Gmac Offset: 0x1A4) Receive Overrun Register */
RoReg GMAC_IHCE; /**< \brief (Gmac Offset: 0x1A8) IP Header Checksum Errors Register */
RoReg GMAC_TCE; /**< \brief (Gmac Offset: 0x1AC) TCP Checksum Errors Register */
RoReg GMAC_UCE; /**< \brief (Gmac Offset: 0x1B0) UDP Checksum Errors Register */
RoReg Reserved3[5];
RwReg GMAC_TSSS; /**< \brief (Gmac Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register */
RwReg GMAC_TSSN; /**< \brief (Gmac Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register */
RwReg GMAC_TS; /**< \brief (Gmac Offset: 0x1D0) 1588 Timer Seconds Register */
RwReg GMAC_TN; /**< \brief (Gmac Offset: 0x1D4) 1588 Timer Nanoseconds Register */
WoReg GMAC_TA; /**< \brief (Gmac Offset: 0x1D8) 1588 Timer Adjust Register */
RwReg GMAC_TI; /**< \brief (Gmac Offset: 0x1DC) 1588 Timer Increment Register */
RoReg GMAC_EFTS; /**< \brief (Gmac Offset: 0x1E0) PTP Event Frame Transmitted Seconds */
RoReg GMAC_EFTN; /**< \brief (Gmac Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds */
RoReg GMAC_EFRS; /**< \brief (Gmac Offset: 0x1E8) PTP Event Frame Received Seconds */
RoReg GMAC_EFRN; /**< \brief (Gmac Offset: 0x1EC) PTP Event Frame Received Nanoseconds */
RoReg GMAC_PEFTS; /**< \brief (Gmac Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds */
RoReg GMAC_PEFTN; /**< \brief (Gmac Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds */
RoReg GMAC_PEFRS; /**< \brief (Gmac Offset: 0x1F8) PTP Peer Event Frame Received Seconds */
RoReg GMAC_PEFRN; /**< \brief (Gmac Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds */
RoReg Reserved4[128];
RoReg GMAC_ISRPQ[7]; /**< \brief (Gmac Offset: 0x400) Interrupt Status Register Priority Queue */
RoReg Reserved5[9];
RwReg GMAC_TBQBAPQ[7]; /**< \brief (Gmac Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue */
RoReg Reserved6[9];
RwReg GMAC_RBQBAPQ[7]; /**< \brief (Gmac Offset: 0x480) Receive Buffer Queue Base Address Priority Queue */
RoReg Reserved7[1];
RwReg GMAC_RBSRPQ[7]; /**< \brief (Gmac Offset: 0x4A0) Receive Buffer Size Register Priority Queue */
RoReg Reserved8[17];
RwReg GMAC_ST1RPQ[16]; /**< \brief (Gmac Offset: 0x500) Screening Type1 Register Priority Queue */
RwReg GMAC_ST2RPQ[16]; /**< \brief (Gmac Offset: 0x540) Screening Type2 Register Priority Queue */
RoReg Reserved9[32];
WoReg GMAC_IERPQ[7]; /**< \brief (Gmac Offset: 0x600) Interrupt Enable Register Priority Queue */
RoReg Reserved10[1];
WoReg GMAC_IDRPQ[7]; /**< \brief (Gmac Offset: 0x620) Interrupt Disable Register Priority Queue */
RoReg Reserved11[1];
RwReg GMAC_IMRPQ[7]; /**< \brief (Gmac Offset: 0x640) Interrupt Mask Register Priority Queue */
} Gmac;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- GMAC_NCR : (GMAC Offset: 0x000) Network Control Register -------- */
#define GMAC_NCR_LB (0x1u << 0) /**< \brief (GMAC_NCR) Loop Back */
#define GMAC_NCR_LBL (0x1u << 1) /**< \brief (GMAC_NCR) Loop Back Local */
#define GMAC_NCR_RXEN (0x1u << 2) /**< \brief (GMAC_NCR) Receive Enable */
#define GMAC_NCR_TXEN (0x1u << 3) /**< \brief (GMAC_NCR) Transmit Enable */
#define GMAC_NCR_MPE (0x1u << 4) /**< \brief (GMAC_NCR) Management Port Enable */
#define GMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (GMAC_NCR) Clear Statistics Registers */
#define GMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (GMAC_NCR) Increment Statistics Registers */
#define GMAC_NCR_WESTAT (0x1u << 7) /**< \brief (GMAC_NCR) Write Enable for Statistics Registers */
#define GMAC_NCR_BP (0x1u << 8) /**< \brief (GMAC_NCR) Back pressure */
#define GMAC_NCR_TSTART (0x1u << 9) /**< \brief (GMAC_NCR) Start Transmission */
#define GMAC_NCR_THALT (0x1u << 10) /**< \brief (GMAC_NCR) Transmit Halt */
#define GMAC_NCR_TXPF (0x1u << 11) /**< \brief (GMAC_NCR) Transmit Pause Frame */
#define GMAC_NCR_TXZQPF (0x1u << 12) /**< \brief (GMAC_NCR) Transmit Zero Quantum Pause Frame */
#define GMAC_NCR_RDS (0x1u << 14) /**< \brief (GMAC_NCR) Read Snapshot */
#define GMAC_NCR_SRTSM (0x1u << 15) /**< \brief (GMAC_NCR) Store Receive Time Stamp to Memory */
#define GMAC_NCR_ENPBPR (0x1u << 16) /**< \brief (GMAC_NCR) Enable PFC Priority-based Pause Reception */
#define GMAC_NCR_TXPBPF (0x1u << 17) /**< \brief (GMAC_NCR) Transmit PFC Priority-based Pause Frame */
#define GMAC_NCR_FNP (0x1u << 18) /**< \brief (GMAC_NCR) Flush Next Packet */
/* -------- GMAC_NCFGR : (GMAC Offset: 0x004) Network Configuration Register -------- */
#define GMAC_NCFGR_SPD (0x1u << 0) /**< \brief (GMAC_NCFGR) Speed */
#define GMAC_NCFGR_FD (0x1u << 1) /**< \brief (GMAC_NCFGR) Full Duplex */
#define GMAC_NCFGR_DNVLAN (0x1u << 2) /**< \brief (GMAC_NCFGR) Discard Non-VLAN FRAMES */
#define GMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (GMAC_NCFGR) Jumbo Frame Size */
#define GMAC_NCFGR_CAF (0x1u << 4) /**< \brief (GMAC_NCFGR) Copy All Frames */
#define GMAC_NCFGR_NBC (0x1u << 5) /**< \brief (GMAC_NCFGR) No Broadcast */
#define GMAC_NCFGR_MTIHEN (0x1u << 6) /**< \brief (GMAC_NCFGR) Multicast Hash Enable */
#define GMAC_NCFGR_UNIHEN (0x1u << 7) /**< \brief (GMAC_NCFGR) Unicast Hash Enable */
#define GMAC_NCFGR_MAXFS (0x1u << 8) /**< \brief (GMAC_NCFGR) 1536 Maximum Frame Size */
#define GMAC_NCFGR_GBE (0x1u << 10) /**< \brief (GMAC_NCFGR) Gigabit Mode Enable */
#define GMAC_NCFGR_PIS (0x1u << 11) /**< \brief (GMAC_NCFGR) Physical Interface Select */
#define GMAC_NCFGR_RTY (0x1u << 12) /**< \brief (GMAC_NCFGR) Retry Test */
#define GMAC_NCFGR_PEN (0x1u << 13) /**< \brief (GMAC_NCFGR) Pause Enable */
#define GMAC_NCFGR_RXBUFO_Pos 14
#define GMAC_NCFGR_RXBUFO_Msk (0x3u << GMAC_NCFGR_RXBUFO_Pos) /**< \brief (GMAC_NCFGR) Receive Buffer Offset */
#define GMAC_NCFGR_RXBUFO(value) ((GMAC_NCFGR_RXBUFO_Msk & ((value) << GMAC_NCFGR_RXBUFO_Pos)))
#define GMAC_NCFGR_LFERD (0x1u << 16) /**< \brief (GMAC_NCFGR) Length Field Error Frame Discard */
#define GMAC_NCFGR_RFCS (0x1u << 17) /**< \brief (GMAC_NCFGR) Remove FCS */
#define GMAC_NCFGR_CLK_Pos 18
#define GMAC_NCFGR_CLK_Msk (0x7u << GMAC_NCFGR_CLK_Pos) /**< \brief (GMAC_NCFGR) MDC CLock Division */
#define GMAC_NCFGR_CLK_MCK_8 (0x0u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz) */
#define GMAC_NCFGR_CLK_MCK_16 (0x1u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz) */
#define GMAC_NCFGR_CLK_MCK_32 (0x2u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz) */
#define GMAC_NCFGR_CLK_MCK_48 (0x3u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 48 (MCK up to 120MHz) */
#define GMAC_NCFGR_CLK_MCK_64 (0x4u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz) */
#define GMAC_NCFGR_CLK_MCK_96 (0x5u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 96 (MCK up to 240 MHz) */
#define GMAC_NCFGR_CLK_MCK_128 (0x6u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 128 (MCK up to 320 MHz) */
#define GMAC_NCFGR_CLK_MCK_224 (0x7u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 224 (MCK up to 540 MHz) */
#define GMAC_NCFGR_DBW_Pos 21
#define GMAC_NCFGR_DBW_Msk (0x3u << GMAC_NCFGR_DBW_Pos) /**< \brief (GMAC_NCFGR) Data Bus Width */
#define GMAC_NCFGR_DBW_DBW32 (0x0u << 21) /**< \brief (GMAC_NCFGR) 32-bit data bus width */
#define GMAC_NCFGR_DBW_DBW64 (0x1u << 21) /**< \brief (GMAC_NCFGR) 64-bit data bus width */
#define GMAC_NCFGR_DCPF (0x1u << 23) /**< \brief (GMAC_NCFGR) Disable Copy of Pause Frames */
#define GMAC_NCFGR_RXCOEN (0x1u << 24) /**< \brief (GMAC_NCFGR) Receive Checksum Offload Enable */
#define GMAC_NCFGR_EFRHD (0x1u << 25) /**< \brief (GMAC_NCFGR) Enable Frames Received in Half Duplex */
#define GMAC_NCFGR_IRXFCS (0x1u << 26) /**< \brief (GMAC_NCFGR) Ignore RX FCS */
#define GMAC_NCFGR_IPGSEN (0x1u << 28) /**< \brief (GMAC_NCFGR) IP Stretch Enable */
#define GMAC_NCFGR_RXBP (0x1u << 29) /**< \brief (GMAC_NCFGR) Receive Bad Preamble */
#define GMAC_NCFGR_IRXER (0x1u << 30) /**< \brief (GMAC_NCFGR) Ignore IPG rx_er */
/* -------- GMAC_NSR : (GMAC Offset: 0x008) Network Status Register -------- */
#define GMAC_NSR_MDIO (0x1u << 1) /**< \brief (GMAC_NSR) MDIO Input Status */
#define GMAC_NSR_IDLE (0x1u << 2) /**< \brief (GMAC_NSR) PHY Management Logic Idle */
/* -------- GMAC_UR : (GMAC Offset: 0x00C) User Register -------- */
#define GMAC_UR_RGMII (0x1u << 0) /**< \brief (GMAC_UR) RGMII Mode */
#define GMAC_UR_HDFC (0x1u << 6) /**< \brief (GMAC_UR) Half Duplex Flow Control */
#define GMAC_UR_BPDG (0x1u << 7) /**< \brief (GMAC_UR) BPDG Bypass Deglitchers */
/* -------- GMAC_DCFGR : (GMAC Offset: 0x010) DMA Configuration Register -------- */
#define GMAC_DCFGR_FBLDO_Pos 0
#define GMAC_DCFGR_FBLDO_Msk (0x1fu << GMAC_DCFGR_FBLDO_Pos) /**< \brief (GMAC_DCFGR) Fixed Burst Length for DMA Data Operations: */
#define GMAC_DCFGR_FBLDO_SINGLE (0x1u << 0) /**< \brief (GMAC_DCFGR) 00001: Always use SINGLE AHB bursts */
#define GMAC_DCFGR_FBLDO_INCR4 (0x4u << 0) /**< \brief (GMAC_DCFGR) 001xx: Attempt to use INCR4 AHB bursts (Default) */
#define GMAC_DCFGR_FBLDO_INCR8 (0x8u << 0) /**< \brief (GMAC_DCFGR) 01xxx: Attempt to use INCR8 AHB bursts */
#define GMAC_DCFGR_FBLDO_INCR16 (0x10u << 0) /**< \brief (GMAC_DCFGR) 1xxxx: Attempt to use INCR16 AHB bursts */
#define GMAC_DCFGR_ESMA (0x1u << 6) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Management Descriptor Accesses */
#define GMAC_DCFGR_ESPA (0x1u << 7) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Packet Data Accesses */
#define GMAC_DCFGR_RXBMS_Pos 8
#define GMAC_DCFGR_RXBMS_Msk (0x3u << GMAC_DCFGR_RXBMS_Pos) /**< \brief (GMAC_DCFGR) Receiver Packet Buffer Memory Size Select */
#define GMAC_DCFGR_RXBMS_EIGHTH (0x0u << 8) /**< \brief (GMAC_DCFGR) 1 Kbyte Memory Size */
#define GMAC_DCFGR_RXBMS_QUARTER (0x1u << 8) /**< \brief (GMAC_DCFGR) 2 Kbytes Memory Size */
#define GMAC_DCFGR_RXBMS_HALF (0x2u << 8) /**< \brief (GMAC_DCFGR) 4 Kbytes Memory Size */
#define GMAC_DCFGR_RXBMS_FULL (0x3u << 8) /**< \brief (GMAC_DCFGR) 8 Kbytes Memory Size */
#define GMAC_DCFGR_TXPBMS (0x1u << 10) /**< \brief (GMAC_DCFGR) Transmitter Packet Buffer Memory Size Select */
#define GMAC_DCFGR_TXCOEN (0x1u << 11) /**< \brief (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable */
#define GMAC_DCFGR_DRBS_Pos 16
#define GMAC_DCFGR_DRBS_Msk (0xffu << GMAC_DCFGR_DRBS_Pos) /**< \brief (GMAC_DCFGR) DMA Receive Buffer Size */
#define GMAC_DCFGR_DRBS(value) ((GMAC_DCFGR_DRBS_Msk & ((value) << GMAC_DCFGR_DRBS_Pos)))
#define GMAC_DCFGR_DDRP (0x1u << 24) /**< \brief (GMAC_DCFGR) DMA Discard Receive Packets */
/* -------- GMAC_TSR : (GMAC Offset: 0x014) Transmit Status Register -------- */
#define GMAC_TSR_UBR (0x1u << 0) /**< \brief (GMAC_TSR) Used Bit Read */
#define GMAC_TSR_COL (0x1u << 1) /**< \brief (GMAC_TSR) Collision Occurred */
#define GMAC_TSR_RLE (0x1u << 2) /**< \brief (GMAC_TSR) Retry Limit Exceeded */
#define GMAC_TSR_TXGO (0x1u << 3) /**< \brief (GMAC_TSR) Transmit Go */
#define GMAC_TSR_TFC (0x1u << 4) /**< \brief (GMAC_TSR) Transmit Frame Corruption due to AHB error */
#define GMAC_TSR_TXCOMP (0x1u << 5) /**< \brief (GMAC_TSR) Transmit Complete */
#define GMAC_TSR_UND (0x1u << 6) /**< \brief (GMAC_TSR) Transmit Under Run */
#define GMAC_TSR_LCO (0x1u << 7) /**< \brief (GMAC_TSR) Late Collision Occurred */
#define GMAC_TSR_HRESP (0x1u << 8) /**< \brief (GMAC_TSR) HRESP Not OK */
/* -------- GMAC_RBQB : (GMAC Offset: 0x018) Receive Buffer Queue Base Address -------- */
#define GMAC_RBQB_ADDR_Pos 2
#define GMAC_RBQB_ADDR_Msk (0x3fffffffu << GMAC_RBQB_ADDR_Pos) /**< \brief (GMAC_RBQB) Receive buffer queue base address */
#define GMAC_RBQB_ADDR(value) ((GMAC_RBQB_ADDR_Msk & ((value) << GMAC_RBQB_ADDR_Pos)))
/* -------- GMAC_TBQB : (GMAC Offset: 0x01C) Transmit Buffer Queue Base Address -------- */
#define GMAC_TBQB_ADDR_Pos 2
#define GMAC_TBQB_ADDR_Msk (0x3fffffffu << GMAC_TBQB_ADDR_Pos) /**< \brief (GMAC_TBQB) Transmit Buffer Queue Base Address */
#define GMAC_TBQB_ADDR(value) ((GMAC_TBQB_ADDR_Msk & ((value) << GMAC_TBQB_ADDR_Pos)))
/* -------- GMAC_RSR : (GMAC Offset: 0x020) Receive Status Register -------- */
#define GMAC_RSR_BNA (0x1u << 0) /**< \brief (GMAC_RSR) Buffer Not Available */
#define GMAC_RSR_REC (0x1u << 1) /**< \brief (GMAC_RSR) Frame Received */
#define GMAC_RSR_RXOVR (0x1u << 2) /**< \brief (GMAC_RSR) Receive Overrun */
#define GMAC_RSR_HNO (0x1u << 3) /**< \brief (GMAC_RSR) HRESP Not OK */
/* -------- GMAC_ISR : (GMAC Offset: 0x024) Interrupt Status Register -------- */
#define GMAC_ISR_MFS (0x1u << 0) /**< \brief (GMAC_ISR) Management Frame Sent */
#define GMAC_ISR_RCOMP (0x1u << 1) /**< \brief (GMAC_ISR) Receive Complete */
#define GMAC_ISR_RXUBR (0x1u << 2) /**< \brief (GMAC_ISR) RX Used Bit Read */
#define GMAC_ISR_TXUBR (0x1u << 3) /**< \brief (GMAC_ISR) TX Used Bit Read */
#define GMAC_ISR_TUR (0x1u << 4) /**< \brief (GMAC_ISR) Transmit Under Run */
#define GMAC_ISR_RLEX (0x1u << 5) /**< \brief (GMAC_ISR) Retry Limit Exceeded or Late Collision */
#define GMAC_ISR_TFC (0x1u << 6) /**< \brief (GMAC_ISR) Transmit Frame Corruption due to AHB error */
#define GMAC_ISR_TCOMP (0x1u << 7) /**< \brief (GMAC_ISR) Transmit Complete */
#define GMAC_ISR_ROVR (0x1u << 10) /**< \brief (GMAC_ISR) Receive Overrun */
#define GMAC_ISR_HRESP (0x1u << 11) /**< \brief (GMAC_ISR) HRESP Not OK */
#define GMAC_ISR_PFNZ (0x1u << 12) /**< \brief (GMAC_ISR) Pause Frame with Non-zero Pause Quantum Received */
#define GMAC_ISR_PTZ (0x1u << 13) /**< \brief (GMAC_ISR) Pause Time Zero */
#define GMAC_ISR_PFTR (0x1u << 14) /**< \brief (GMAC_ISR) Pause Frame Transmitted */
#define GMAC_ISR_EXINT (0x1u << 15) /**< \brief (GMAC_ISR) External Interrupt */
#define GMAC_ISR_DRQFR (0x1u << 18) /**< \brief (GMAC_ISR) PTP Delay Request Frame Received */
#define GMAC_ISR_SFR (0x1u << 19) /**< \brief (GMAC_ISR) PTP Sync Frame Received */
#define GMAC_ISR_DRQFT (0x1u << 20) /**< \brief (GMAC_ISR) PTP Delay Request Frame Transmitted */
#define GMAC_ISR_SFT (0x1u << 21) /**< \brief (GMAC_ISR) PTP Sync Frame Transmitted */
#define GMAC_ISR_PDRQFR (0x1u << 22) /**< \brief (GMAC_ISR) PDelay Request Frame Received */
#define GMAC_ISR_PDRSFR (0x1u << 23) /**< \brief (GMAC_ISR) PDelay Response Frame Received */
#define GMAC_ISR_PDRQFT (0x1u << 24) /**< \brief (GMAC_ISR) PDelay Request Frame Transmitted */
#define GMAC_ISR_PDRSFT (0x1u << 25) /**< \brief (GMAC_ISR) PDelay Response Frame Transmitted */
#define GMAC_ISR_SRI (0x1u << 26) /**< \brief (GMAC_ISR) TSU Seconds Register Increment */
#define GMAC_ISR_WOL (0x1u << 28) /**< \brief (GMAC_ISR) Wake On LAN */
/* -------- GMAC_IER : (GMAC Offset: 0x028) Interrupt Enable Register -------- */
#define GMAC_IER_MFS (0x1u << 0) /**< \brief (GMAC_IER) Management Frame Sent */
#define GMAC_IER_RCOMP (0x1u << 1) /**< \brief (GMAC_IER) Receive Complete */
#define GMAC_IER_RXUBR (0x1u << 2) /**< \brief (GMAC_IER) RX Used Bit Read */
#define GMAC_IER_TXUBR (0x1u << 3) /**< \brief (GMAC_IER) TX Used Bit Read */
#define GMAC_IER_TUR (0x1u << 4) /**< \brief (GMAC_IER) Transmit Under Run */
#define GMAC_IER_RLEX (0x1u << 5) /**< \brief (GMAC_IER) Retry Limit Exceeded or Late Collision */
#define GMAC_IER_TFC (0x1u << 6) /**< \brief (GMAC_IER) Transmit Frame Corruption due to AHB error */
#define GMAC_IER_TCOMP (0x1u << 7) /**< \brief (GMAC_IER) Transmit Complete */
#define GMAC_IER_ROVR (0x1u << 10) /**< \brief (GMAC_IER) Receive Overrun */
#define GMAC_IER_HRESP (0x1u << 11) /**< \brief (GMAC_IER) HRESP Not OK */
#define GMAC_IER_PFNZ (0x1u << 12) /**< \brief (GMAC_IER) Pause Frame with Non-zero Pause Quantum Received */
#define GMAC_IER_PTZ (0x1u << 13) /**< \brief (GMAC_IER) Pause Time Zero */
#define GMAC_IER_PFTR (0x1u << 14) /**< \brief (GMAC_IER) Pause Frame Transmitted */
#define GMAC_IER_EXINT (0x1u << 15) /**< \brief (GMAC_IER) External Interrupt */
#define GMAC_IER_DRQFR (0x1u << 18) /**< \brief (GMAC_IER) PTP Delay Request Frame Received */
#define GMAC_IER_SFR (0x1u << 19) /**< \brief (GMAC_IER) PTP Sync Frame Received */
#define GMAC_IER_DRQFT (0x1u << 20) /**< \brief (GMAC_IER) PTP Delay Request Frame Transmitted */
#define GMAC_IER_SFT (0x1u << 21) /**< \brief (GMAC_IER) PTP Sync Frame Transmitted */
#define GMAC_IER_PDRQFR (0x1u << 22) /**< \brief (GMAC_IER) PDelay Request Frame Received */
#define GMAC_IER_PDRSFR (0x1u << 23) /**< \brief (GMAC_IER) PDelay Response Frame Received */
#define GMAC_IER_PDRQFT (0x1u << 24) /**< \brief (GMAC_IER) PDelay Request Frame Transmitted */
#define GMAC_IER_PDRSFT (0x1u << 25) /**< \brief (GMAC_IER) PDelay Response Frame Transmitted */
#define GMAC_IER_SRI (0x1u << 26) /**< \brief (GMAC_IER) TSU Seconds Register Increment */
#define GMAC_IER_WOL (0x1u << 28) /**< \brief (GMAC_IER) Wake On LAN */
/* -------- GMAC_IDR : (GMAC Offset: 0x02C) Interrupt Disable Register -------- */
#define GMAC_IDR_MFS (0x1u << 0) /**< \brief (GMAC_IDR) Management Frame Sent */
#define GMAC_IDR_RCOMP (0x1u << 1) /**< \brief (GMAC_IDR) Receive Complete */
#define GMAC_IDR_RXUBR (0x1u << 2) /**< \brief (GMAC_IDR) RX Used Bit Read */
#define GMAC_IDR_TXUBR (0x1u << 3) /**< \brief (GMAC_IDR) TX Used Bit Read */
#define GMAC_IDR_TUR (0x1u << 4) /**< \brief (GMAC_IDR) Transmit Under Run */
#define GMAC_IDR_RLEX (0x1u << 5) /**< \brief (GMAC_IDR) Retry Limit Exceeded or Late Collision */
#define GMAC_IDR_TFC (0x1u << 6) /**< \brief (GMAC_IDR) Transmit Frame Corruption due to AHB error */
#define GMAC_IDR_TCOMP (0x1u << 7) /**< \brief (GMAC_IDR) Transmit Complete */
#define GMAC_IDR_ROVR (0x1u << 10) /**< \brief (GMAC_IDR) Receive Overrun */
#define GMAC_IDR_HRESP (0x1u << 11) /**< \brief (GMAC_IDR) HRESP Not OK */
#define GMAC_IDR_PFNZ (0x1u << 12) /**< \brief (GMAC_IDR) Pause Frame with Non-zero Pause Quantum Received */
#define GMAC_IDR_PTZ (0x1u << 13) /**< \brief (GMAC_IDR) Pause Time Zero */
#define GMAC_IDR_PFTR (0x1u << 14) /**< \brief (GMAC_IDR) Pause Frame Transmitted */
#define GMAC_IDR_EXINT (0x1u << 15) /**< \brief (GMAC_IDR) External Interrupt */
#define GMAC_IDR_DRQFR (0x1u << 18) /**< \brief (GMAC_IDR) PTP Delay Request Frame Received */
#define GMAC_IDR_SFR (0x1u << 19) /**< \brief (GMAC_IDR) PTP Sync Frame Received */
#define GMAC_IDR_DRQFT (0x1u << 20) /**< \brief (GMAC_IDR) PTP Delay Request Frame Transmitted */
#define GMAC_IDR_SFT (0x1u << 21) /**< \brief (GMAC_IDR) PTP Sync Frame Transmitted */
#define GMAC_IDR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IDR) PDelay Request Frame Received */
#define GMAC_IDR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IDR) PDelay Response Frame Received */
#define GMAC_IDR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IDR) PDelay Request Frame Transmitted */
#define GMAC_IDR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IDR) PDelay Response Frame Transmitted */
#define GMAC_IDR_SRI (0x1u << 26) /**< \brief (GMAC_IDR) TSU Seconds Register Increment */
#define GMAC_IDR_WOL (0x1u << 28) /**< \brief (GMAC_IDR) Wake On LAN */
/* -------- GMAC_IMR : (GMAC Offset: 0x030) Interrupt Mask Register -------- */
#define GMAC_IMR_MFS (0x1u << 0) /**< \brief (GMAC_IMR) Management Frame Sent */
#define GMAC_IMR_RCOMP (0x1u << 1) /**< \brief (GMAC_IMR) Receive Complete */
#define GMAC_IMR_RXUBR (0x1u << 2) /**< \brief (GMAC_IMR) RX Used Bit Read */
#define GMAC_IMR_TXUBR (0x1u << 3) /**< \brief (GMAC_IMR) TX Used Bit Read */
#define GMAC_IMR_TUR (0x1u << 4) /**< \brief (GMAC_IMR) Transmit Under Run */
#define GMAC_IMR_RLEX (0x1u << 5) /**< \brief (GMAC_IMR) Retry Limit Exceeded or Late Collision */
#define GMAC_IMR_TFC (0x1u << 6) /**< \brief (GMAC_IMR) Transmit Frame Corruption due to AHB error */
#define GMAC_IMR_TCOMP (0x1u << 7) /**< \brief (GMAC_IMR) Transmit Complete */
#define GMAC_IMR_ROVR (0x1u << 10) /**< \brief (GMAC_IMR) Receive Overrun */
#define GMAC_IMR_HRESP (0x1u << 11) /**< \brief (GMAC_IMR) HRESP Not OK */
#define GMAC_IMR_PFNZ (0x1u << 12) /**< \brief (GMAC_IMR) Pause Frame with Non-zero Pause Quantum Received */
#define GMAC_IMR_PTZ (0x1u << 13) /**< \brief (GMAC_IMR) Pause Time Zero */
#define GMAC_IMR_PFTR (0x1u << 14) /**< \brief (GMAC_IMR) Pause Frame Transmitted */
#define GMAC_IMR_EXINT (0x1u << 15) /**< \brief (GMAC_IMR) External Interrupt */
#define GMAC_IMR_DRQFR (0x1u << 18) /**< \brief (GMAC_IMR) PTP Delay Request Frame Received */
#define GMAC_IMR_SFR (0x1u << 19) /**< \brief (GMAC_IMR) PTP Sync Frame Received */
#define GMAC_IMR_DRQFT (0x1u << 20) /**< \brief (GMAC_IMR) PTP Delay Request Frame Transmitted */
#define GMAC_IMR_SFT (0x1u << 21) /**< \brief (GMAC_IMR) PTP Sync Frame Transmitted */
#define GMAC_IMR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IMR) PDelay Request Frame Received */
#define GMAC_IMR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IMR) PDelay Response Frame Received */
#define GMAC_IMR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IMR) PDelay Request Frame Transmitted */
#define GMAC_IMR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IMR) PDelay Response Frame Transmitted */
/* -------- GMAC_MAN : (GMAC Offset: 0x034) PHY Maintenance Register -------- */
#define GMAC_MAN_DATA_Pos 0
#define GMAC_MAN_DATA_Msk (0xffffu << GMAC_MAN_DATA_Pos) /**< \brief (GMAC_MAN) PHY Data */
#define GMAC_MAN_DATA(value) ((GMAC_MAN_DATA_Msk & ((value) << GMAC_MAN_DATA_Pos)))
#define GMAC_MAN_WTN_Pos 16
#define GMAC_MAN_WTN_Msk (0x3u << GMAC_MAN_WTN_Pos) /**< \brief (GMAC_MAN) Write Ten */
#define GMAC_MAN_WTN(value) ((GMAC_MAN_WTN_Msk & ((value) << GMAC_MAN_WTN_Pos)))
#define GMAC_MAN_REGA_Pos 18
#define GMAC_MAN_REGA_Msk (0x1fu << GMAC_MAN_REGA_Pos) /**< \brief (GMAC_MAN) Register Address */
#define GMAC_MAN_REGA(value) ((GMAC_MAN_REGA_Msk & ((value) << GMAC_MAN_REGA_Pos)))
#define GMAC_MAN_PHYA_Pos 23
#define GMAC_MAN_PHYA_Msk (0x1fu << GMAC_MAN_PHYA_Pos) /**< \brief (GMAC_MAN) PHY Address */
#define GMAC_MAN_PHYA(value) ((GMAC_MAN_PHYA_Msk & ((value) << GMAC_MAN_PHYA_Pos)))
#define GMAC_MAN_OP_Pos 28
#define GMAC_MAN_OP_Msk (0x3u << GMAC_MAN_OP_Pos) /**< \brief (GMAC_MAN) Operation */
#define GMAC_MAN_OP(value) ((GMAC_MAN_OP_Msk & ((value) << GMAC_MAN_OP_Pos)))
#define GMAC_MAN_CLTTO (0x1u << 30) /**< \brief (GMAC_MAN) Clause 22 Operation */
#define GMAC_MAN_WZO (0x1u << 31) /**< \brief (GMAC_MAN) Write ZERO */
/* -------- GMAC_RPQ : (GMAC Offset: 0x038) Received Pause Quantum Register -------- */
#define GMAC_RPQ_RPQ_Pos 0
#define GMAC_RPQ_RPQ_Msk (0xffffu << GMAC_RPQ_RPQ_Pos) /**< \brief (GMAC_RPQ) Received Pause Quantum */
/* -------- GMAC_TPQ : (GMAC Offset: 0x03C) Transmit Pause Quantum Register -------- */
#define GMAC_TPQ_TPQ_Pos 0
#define GMAC_TPQ_TPQ_Msk (0xffffu << GMAC_TPQ_TPQ_Pos) /**< \brief (GMAC_TPQ) Transmit Pause Quantum */
#define GMAC_TPQ_TPQ(value) ((GMAC_TPQ_TPQ_Msk & ((value) << GMAC_TPQ_TPQ_Pos)))
/* -------- GMAC_TPSF : (GMAC Offset: 0x040) TX Partial Store and Forward Register -------- */
#define GMAC_TPSF_TPB1ADR_Pos 0
#define GMAC_TPSF_TPB1ADR_Msk (0xfffu << GMAC_TPSF_TPB1ADR_Pos) /**< \brief (GMAC_TPSF) tx_pbuf_addr-1:0 */
#define GMAC_TPSF_TPB1ADR(value) ((GMAC_TPSF_TPB1ADR_Msk & ((value) << GMAC_TPSF_TPB1ADR_Pos)))
#define GMAC_TPSF_ENTXP (0x1u << 31) /**< \brief (GMAC_TPSF) Enable TX Partial Store and Forward Operation */
/* -------- GMAC_RPSF : (GMAC Offset: 0x044) RX Partial Store and Forward Register -------- */
#define GMAC_RPSF_RPB1ADR_Pos 0
#define GMAC_RPSF_RPB1ADR_Msk (0xfffu << GMAC_RPSF_RPB1ADR_Pos) /**< \brief (GMAC_RPSF) rx_pbuf_addr-1:0 */
#define GMAC_RPSF_RPB1ADR(value) ((GMAC_RPSF_RPB1ADR_Msk & ((value) << GMAC_RPSF_RPB1ADR_Pos)))
#define GMAC_RPSF_ENRXP (0x1u << 31) /**< \brief (GMAC_RPSF) Enable RX Partial Store and Forward Operation */
/* -------- GMAC_HRB : (GMAC Offset: 0x080) Hash Register Bottom [31:0] -------- */
#define GMAC_HRB_ADDR_Pos 0
#define GMAC_HRB_ADDR_Msk (0xffffffffu << GMAC_HRB_ADDR_Pos) /**< \brief (GMAC_HRB) Hash Address */
#define GMAC_HRB_ADDR(value) ((GMAC_HRB_ADDR_Msk & ((value) << GMAC_HRB_ADDR_Pos)))
/* -------- GMAC_HRT : (GMAC Offset: 0x084) Hash Register Top [63:32] -------- */
#define GMAC_HRT_ADDR_Pos 0
#define GMAC_HRT_ADDR_Msk (0xffffffffu << GMAC_HRT_ADDR_Pos) /**< \brief (GMAC_HRT) Hash Address */
#define GMAC_HRT_ADDR(value) ((GMAC_HRT_ADDR_Msk & ((value) << GMAC_HRT_ADDR_Pos)))
/* -------- GMAC_SAB1 : (GMAC Offset: 0x088) Specific Address 1 Bottom [31:0] Register -------- */
#define GMAC_SAB1_ADDR_Pos 0
#define GMAC_SAB1_ADDR_Msk (0xffffffffu << GMAC_SAB1_ADDR_Pos) /**< \brief (GMAC_SAB1) Specific Address 1 */
#define GMAC_SAB1_ADDR(value) ((GMAC_SAB1_ADDR_Msk & ((value) << GMAC_SAB1_ADDR_Pos)))
/* -------- GMAC_SAT1 : (GMAC Offset: 0x08C) Specific Address 1 Top [47:32] Register -------- */
#define GMAC_SAT1_ADDR_Pos 0
#define GMAC_SAT1_ADDR_Msk (0xffffu << GMAC_SAT1_ADDR_Pos) /**< \brief (GMAC_SAT1) Specific Address 1 */
#define GMAC_SAT1_ADDR(value) ((GMAC_SAT1_ADDR_Msk & ((value) << GMAC_SAT1_ADDR_Pos)))
/* -------- GMAC_SAB2 : (GMAC Offset: 0x090) Specific Address 2 Bottom [31:0] Register -------- */
#define GMAC_SAB2_ADDR_Pos 0
#define GMAC_SAB2_ADDR_Msk (0xffffffffu << GMAC_SAB2_ADDR_Pos) /**< \brief (GMAC_SAB2) Specific Address 2 */
#define GMAC_SAB2_ADDR(value) ((GMAC_SAB2_ADDR_Msk & ((value) << GMAC_SAB2_ADDR_Pos)))
/* -------- GMAC_SAT2 : (GMAC Offset: 0x094) Specific Address 2 Top [47:32] Register -------- */
#define GMAC_SAT2_ADDR_Pos 0
#define GMAC_SAT2_ADDR_Msk (0xffffu << GMAC_SAT2_ADDR_Pos) /**< \brief (GMAC_SAT2) Specific Address 2 */
#define GMAC_SAT2_ADDR(value) ((GMAC_SAT2_ADDR_Msk & ((value) << GMAC_SAT2_ADDR_Pos)))
/* -------- GMAC_SAB3 : (GMAC Offset: 0x098) Specific Address 3 Bottom [31:0] Register -------- */
#define GMAC_SAB3_ADDR_Pos 0
#define GMAC_SAB3_ADDR_Msk (0xffffffffu << GMAC_SAB3_ADDR_Pos) /**< \brief (GMAC_SAB3) Specific Address 3 */
#define GMAC_SAB3_ADDR(value) ((GMAC_SAB3_ADDR_Msk & ((value) << GMAC_SAB3_ADDR_Pos)))
/* -------- GMAC_SAT3 : (GMAC Offset: 0x09C) Specific Address 3 Top [47:32] Register -------- */
#define GMAC_SAT3_ADDR_Pos 0
#define GMAC_SAT3_ADDR_Msk (0xffffu << GMAC_SAT3_ADDR_Pos) /**< \brief (GMAC_SAT3) Specific Address 3 */
#define GMAC_SAT3_ADDR(value) ((GMAC_SAT3_ADDR_Msk & ((value) << GMAC_SAT3_ADDR_Pos)))
/* -------- GMAC_SAB4 : (GMAC Offset: 0x0A0) Specific Address 4 Bottom [31:0] Register -------- */
#define GMAC_SAB4_ADDR_Pos 0
#define GMAC_SAB4_ADDR_Msk (0xffffffffu << GMAC_SAB4_ADDR_Pos) /**< \brief (GMAC_SAB4) Specific Address 4 */
#define GMAC_SAB4_ADDR(value) ((GMAC_SAB4_ADDR_Msk & ((value) << GMAC_SAB4_ADDR_Pos)))
/* -------- GMAC_SAT4 : (GMAC Offset: 0x0A4) Specific Address 4 Top [47:32] Register -------- */
#define GMAC_SAT4_ADDR_Pos 0
#define GMAC_SAT4_ADDR_Msk (0xffffu << GMAC_SAT4_ADDR_Pos) /**< \brief (GMAC_SAT4) Specific Address 4 */
#define GMAC_SAT4_ADDR(value) ((GMAC_SAT4_ADDR_Msk & ((value) << GMAC_SAT4_ADDR_Pos)))
/* -------- GMAC_TIDM[4] : (GMAC Offset: 0x0A8) Type ID Match 1 Register -------- */
#define GMAC_TIDM_TID_Pos 0
#define GMAC_TIDM_TID_Msk (0xffffu << GMAC_TIDM_TID_Pos) /**< \brief (GMAC_TIDM[4]) Type ID Match 1 */
#define GMAC_TIDM_TID(value) ((GMAC_TIDM_TID_Msk & ((value) << GMAC_TIDM_TID_Pos)))
/* -------- GMAC_WOL : (GMAC Offset: 0x0B8) Wake on LAN Register -------- */
#define GMAC_WOL_IP_Pos 0
#define GMAC_WOL_IP_Msk (0xffffu << GMAC_WOL_IP_Pos) /**< \brief (GMAC_WOL) ARP Request IP Address */
#define GMAC_WOL_IP(value) ((GMAC_WOL_IP_Msk & ((value) << GMAC_WOL_IP_Pos)))
#define GMAC_WOL_MAG (0x1u << 16) /**< \brief (GMAC_WOL) Magic Packet Event Enable */
#define GMAC_WOL_ARP (0x1u << 17) /**< \brief (GMAC_WOL) ARP Request IP Address */
#define GMAC_WOL_SA1 (0x1u << 18) /**< \brief (GMAC_WOL) Specific Address Register 1 Event Enable */
#define GMAC_WOL_MTI (0x1u << 19) /**< \brief (GMAC_WOL) Multicast Hash Event Enable */
/* -------- GMAC_IPGS : (GMAC Offset: 0x0BC) IPG Stretch Register -------- */
#define GMAC_IPGS_FL_Pos 0
#define GMAC_IPGS_FL_Msk (0xffffu << GMAC_IPGS_FL_Pos) /**< \brief (GMAC_IPGS) Frame Length */
#define GMAC_IPGS_FL(value) ((GMAC_IPGS_FL_Msk & ((value) << GMAC_IPGS_FL_Pos)))
/* -------- GMAC_SVLAN : (GMAC Offset: 0x0C0) Stacked VLAN Register -------- */
#define GMAC_SVLAN_VLAN_TYPE_Pos 0
#define GMAC_SVLAN_VLAN_TYPE_Msk (0xffffu << GMAC_SVLAN_VLAN_TYPE_Pos) /**< \brief (GMAC_SVLAN) User Defined VLAN_TYPE Field */
#define GMAC_SVLAN_VLAN_TYPE(value) ((GMAC_SVLAN_VLAN_TYPE_Msk & ((value) << GMAC_SVLAN_VLAN_TYPE_Pos)))
#define GMAC_SVLAN_ESVLAN (0x1u << 31) /**< \brief (GMAC_SVLAN) Enable Stacked VLAN Processing Mode */
/* -------- GMAC_TPFCP : (GMAC Offset: 0x0C4) Transmit PFC Pause Register -------- */
#define GMAC_TPFCP_PEV_Pos 0
#define GMAC_TPFCP_PEV_Msk (0xffu << GMAC_TPFCP_PEV_Pos) /**< \brief (GMAC_TPFCP) Priority Enable Vector */
#define GMAC_TPFCP_PEV(value) ((GMAC_TPFCP_PEV_Msk & ((value) << GMAC_TPFCP_PEV_Pos)))
#define GMAC_TPFCP_PQ_Pos 8
#define GMAC_TPFCP_PQ_Msk (0xffu << GMAC_TPFCP_PQ_Pos) /**< \brief (GMAC_TPFCP) Pause Quantum */
#define GMAC_TPFCP_PQ(value) ((GMAC_TPFCP_PQ_Msk & ((value) << GMAC_TPFCP_PQ_Pos)))
/* -------- GMAC_SAMB1 : (GMAC Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register -------- */
#define GMAC_SAMB1_ADDR_Pos 0
#define GMAC_SAMB1_ADDR_Msk (0xffffffffu << GMAC_SAMB1_ADDR_Pos) /**< \brief (GMAC_SAMB1) Specific Address 1 Mask */
#define GMAC_SAMB1_ADDR(value) ((GMAC_SAMB1_ADDR_Msk & ((value) << GMAC_SAMB1_ADDR_Pos)))
/* -------- GMAC_SAMT1 : (GMAC Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register -------- */
#define GMAC_SAMT1_ADDR_Pos 0
#define GMAC_SAMT1_ADDR_Msk (0xffffu << GMAC_SAMT1_ADDR_Pos) /**< \brief (GMAC_SAMT1) Specific Address 1 Mask */
#define GMAC_SAMT1_ADDR(value) ((GMAC_SAMT1_ADDR_Msk & ((value) << GMAC_SAMT1_ADDR_Pos)))
/* -------- GMAC_OTLO : (GMAC Offset: 0x100) Octets Transmitted [31:0] Register -------- */
#define GMAC_OTLO_TXO_Pos 0
#define GMAC_OTLO_TXO_Msk (0xffffffffu << GMAC_OTLO_TXO_Pos) /**< \brief (GMAC_OTLO) Transmitted Octets */
/* -------- GMAC_OTHI : (GMAC Offset: 0x104) Octets Transmitted [47:32] Register -------- */
#define GMAC_OTHI_TXO_Pos 0
#define GMAC_OTHI_TXO_Msk (0xffffu << GMAC_OTHI_TXO_Pos) /**< \brief (GMAC_OTHI) Transmitted Octets */
/* -------- GMAC_FT : (GMAC Offset: 0x108) Frames Transmitted Register -------- */
#define GMAC_FT_FTX_Pos 0
#define GMAC_FT_FTX_Msk (0xffffffffu << GMAC_FT_FTX_Pos) /**< \brief (GMAC_FT) Frames Transmitted without Error */
/* -------- GMAC_BCFT : (GMAC Offset: 0x10C) Broadcast Frames Transmitted Register -------- */
#define GMAC_BCFT_BFTX_Pos 0
#define GMAC_BCFT_BFTX_Msk (0xffffffffu << GMAC_BCFT_BFTX_Pos) /**< \brief (GMAC_BCFT) Broadcast Frames Transmitted without Error */
/* -------- GMAC_MFT : (GMAC Offset: 0x110) Multicast Frames Transmitted Register -------- */
#define GMAC_MFT_MFTX_Pos 0
#define GMAC_MFT_MFTX_Msk (0xffffffffu << GMAC_MFT_MFTX_Pos) /**< \brief (GMAC_MFT) Multicast Frames Transmitted without Error */
/* -------- GMAC_PFT : (GMAC Offset: 0x114) Pause Frames Transmitted Register -------- */
#define GMAC_PFT_PFTX_Pos 0
#define GMAC_PFT_PFTX_Msk (0xffffu << GMAC_PFT_PFTX_Pos) /**< \brief (GMAC_PFT) Pause Frames Transmitted Register */
/* -------- GMAC_BFT64 : (GMAC Offset: 0x118) 64 Byte Frames Transmitted Register -------- */
#define GMAC_BFT64_NFTX_Pos 0
#define GMAC_BFT64_NFTX_Msk (0xffffffffu << GMAC_BFT64_NFTX_Pos) /**< \brief (GMAC_BFT64) 64 Byte Frames Transmitted without Error */
/* -------- GMAC_TBFT127 : (GMAC Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register -------- */
#define GMAC_TBFT127_NFTX_Pos 0
#define GMAC_TBFT127_NFTX_Msk (0xffffffffu << GMAC_TBFT127_NFTX_Pos) /**< \brief (GMAC_TBFT127) 65 to 127 Byte Frames Transmitted without Error */
/* -------- GMAC_TBFT255 : (GMAC Offset: 0x120) 128 to 255 Byte Frames Transmitted Register -------- */
#define GMAC_TBFT255_NFTX_Pos 0
#define GMAC_TBFT255_NFTX_Msk (0xffffffffu << GMAC_TBFT255_NFTX_Pos) /**< \brief (GMAC_TBFT255) 128 to 255 Byte Frames Transmitted without Error */
/* -------- GMAC_TBFT511 : (GMAC Offset: 0x124) 256 to 511 Byte Frames Transmitted Register -------- */
#define GMAC_TBFT511_NFTX_Pos 0
#define GMAC_TBFT511_NFTX_Msk (0xffffffffu << GMAC_TBFT511_NFTX_Pos) /**< \brief (GMAC_TBFT511) 256 to 511 Byte Frames Transmitted without Error */
/* -------- GMAC_TBFT1023 : (GMAC Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register -------- */
#define GMAC_TBFT1023_NFTX_Pos 0
#define GMAC_TBFT1023_NFTX_Msk (0xffffffffu << GMAC_TBFT1023_NFTX_Pos) /**< \brief (GMAC_TBFT1023) 512 to 1023 Byte Frames Transmitted without Error */
/* -------- GMAC_TBFT1518 : (GMAC Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register -------- */
#define GMAC_TBFT1518_NFTX_Pos 0
#define GMAC_TBFT1518_NFTX_Msk (0xffffffffu << GMAC_TBFT1518_NFTX_Pos) /**< \brief (GMAC_TBFT1518) 1024 to 1518 Byte Frames Transmitted without Error */
/* -------- GMAC_GTBFT1518 : (GMAC Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register -------- */
#define GMAC_GTBFT1518_NFTX_Pos 0
#define GMAC_GTBFT1518_NFTX_Msk (0xffffffffu << GMAC_GTBFT1518_NFTX_Pos) /**< \brief (GMAC_GTBFT1518) Greater than 1518 Byte Frames Transmitted without Error */
/* -------- GMAC_TUR : (GMAC Offset: 0x134) Transmit Under Runs Register -------- */
#define GMAC_TUR_TXUNR_Pos 0
#define GMAC_TUR_TXUNR_Msk (0x3ffu << GMAC_TUR_TXUNR_Pos) /**< \brief (GMAC_TUR) Transmit Under Runs */
/* -------- GMAC_SCF : (GMAC Offset: 0x138) Single Collision Frames Register -------- */
#define GMAC_SCF_SCOL_Pos 0
#define GMAC_SCF_SCOL_Msk (0x3ffffu << GMAC_SCF_SCOL_Pos) /**< \brief (GMAC_SCF) Single Collision */
/* -------- GMAC_MCF : (GMAC Offset: 0x13C) Multiple Collision Frames Register -------- */
#define GMAC_MCF_MCOL_Pos 0
#define GMAC_MCF_MCOL_Msk (0x3ffffu << GMAC_MCF_MCOL_Pos) /**< \brief (GMAC_MCF) Multiple Collision */
/* -------- GMAC_EC : (GMAC Offset: 0x140) Excessive Collisions Register -------- */
#define GMAC_EC_XCOL_Pos 0
#define GMAC_EC_XCOL_Msk (0x3ffu << GMAC_EC_XCOL_Pos) /**< \brief (GMAC_EC) Excessive Collisions */
/* -------- GMAC_LC : (GMAC Offset: 0x144) Late Collisions Register -------- */
#define GMAC_LC_LCOL_Pos 0
#define GMAC_LC_LCOL_Msk (0x3ffu << GMAC_LC_LCOL_Pos) /**< \brief (GMAC_LC) Late Collisions */
/* -------- GMAC_DTF : (GMAC Offset: 0x148) Deferred Transmission Frames Register -------- */
#define GMAC_DTF_DEFT_Pos 0
#define GMAC_DTF_DEFT_Msk (0x3ffffu << GMAC_DTF_DEFT_Pos) /**< \brief (GMAC_DTF) Deferred Transmission */
/* -------- GMAC_CSE : (GMAC Offset: 0x14C) Carrier Sense Errors Register -------- */
#define GMAC_CSE_CSR_Pos 0
#define GMAC_CSE_CSR_Msk (0x3ffu << GMAC_CSE_CSR_Pos) /**< \brief (GMAC_CSE) Carrier Sense Error */
/* -------- GMAC_ORLO : (GMAC Offset: 0x150) Octets Received [31:0] Received -------- */
#define GMAC_ORLO_RXO_Pos 0
#define GMAC_ORLO_RXO_Msk (0xffffffffu << GMAC_ORLO_RXO_Pos) /**< \brief (GMAC_ORLO) Received Octets */
/* -------- GMAC_ORHI : (GMAC Offset: 0x154) Octets Received [47:32] Received -------- */
#define GMAC_ORHI_RXO_Pos 0
#define GMAC_ORHI_RXO_Msk (0xffffu << GMAC_ORHI_RXO_Pos) /**< \brief (GMAC_ORHI) Received Octets */
/* -------- GMAC_FR : (GMAC Offset: 0x158) Frames Received Register -------- */
#define GMAC_FR_FRX_Pos 0
#define GMAC_FR_FRX_Msk (0xffffffffu << GMAC_FR_FRX_Pos) /**< \brief (GMAC_FR) Frames Received without Error */
/* -------- GMAC_BCFR : (GMAC Offset: 0x15C) Broadcast Frames Received Register -------- */
#define GMAC_BCFR_BFRX_Pos 0
#define GMAC_BCFR_BFRX_Msk (0xffffffffu << GMAC_BCFR_BFRX_Pos) /**< \brief (GMAC_BCFR) Broadcast Frames Received without Error */
/* -------- GMAC_MFR : (GMAC Offset: 0x160) Multicast Frames Received Register -------- */
#define GMAC_MFR_MFRX_Pos 0
#define GMAC_MFR_MFRX_Msk (0xffffffffu << GMAC_MFR_MFRX_Pos) /**< \brief (GMAC_MFR) Multicast Frames Received without Error */
/* -------- GMAC_PFR : (GMAC Offset: 0x164) Pause Frames Received Register -------- */
#define GMAC_PFR_PFRX_Pos 0
#define GMAC_PFR_PFRX_Msk (0xffffu << GMAC_PFR_PFRX_Pos) /**< \brief (GMAC_PFR) Pause Frames Received Register */
/* -------- GMAC_BFR64 : (GMAC Offset: 0x168) 64 Byte Frames Received Register -------- */
#define GMAC_BFR64_NFRX_Pos 0
#define GMAC_BFR64_NFRX_Msk (0xffffffffu << GMAC_BFR64_NFRX_Pos) /**< \brief (GMAC_BFR64) 64 Byte Frames Received without Error */
/* -------- GMAC_TBFR127 : (GMAC Offset: 0x16C) 65 to 127 Byte Frames Received Register -------- */
#define GMAC_TBFR127_NFRX_Pos 0
#define GMAC_TBFR127_NFRX_Msk (0xffffffffu << GMAC_TBFR127_NFRX_Pos) /**< \brief (GMAC_TBFR127) 65 to 127 Byte Frames Received without Error */
/* -------- GMAC_TBFR255 : (GMAC Offset: 0x170) 128 to 255 Byte Frames Received Register -------- */
#define GMAC_TBFR255_NFRX_Pos 0
#define GMAC_TBFR255_NFRX_Msk (0xffffffffu << GMAC_TBFR255_NFRX_Pos) /**< \brief (GMAC_TBFR255) 128 to 255 Byte Frames Received without Error */
/* -------- GMAC_TBFR511 : (GMAC Offset: 0x174) 256 to 511Byte Frames Received Register -------- */
#define GMAC_TBFR511_NFRX_Pos 0
#define GMAC_TBFR511_NFRX_Msk (0xffffffffu << GMAC_TBFR511_NFRX_Pos) /**< \brief (GMAC_TBFR511) 256 to 511 Byte Frames Received without Error */
/* -------- GMAC_TBFR1023 : (GMAC Offset: 0x178) 512 to 1023 Byte Frames Received Register -------- */
#define GMAC_TBFR1023_NFRX_Pos 0
#define GMAC_TBFR1023_NFRX_Msk (0xffffffffu << GMAC_TBFR1023_NFRX_Pos) /**< \brief (GMAC_TBFR1023) 512 to 1023 Byte Frames Received without Error */
/* -------- GMAC_TBFR1518 : (GMAC Offset: 0x17C) 1024 to 1518 Byte Frames Received Register -------- */
#define GMAC_TBFR1518_NFRX_Pos 0
#define GMAC_TBFR1518_NFRX_Msk (0xffffffffu << GMAC_TBFR1518_NFRX_Pos) /**< \brief (GMAC_TBFR1518) 1024 to 1518 Byte Frames Received without Error */
/* -------- GMAC_TMXBFR : (GMAC Offset: 0x180) 1519 to Maximum Byte Frames Received Register -------- */
#define GMAC_TMXBFR_NFRX_Pos 0
#define GMAC_TMXBFR_NFRX_Msk (0xffffffffu << GMAC_TMXBFR_NFRX_Pos) /**< \brief (GMAC_TMXBFR) 1519 to Maximum Byte Frames Received without Error */
/* -------- GMAC_UFR : (GMAC Offset: 0x184) Undersize Frames Received Register -------- */
#define GMAC_UFR_UFRX_Pos 0
#define GMAC_UFR_UFRX_Msk (0x3ffu << GMAC_UFR_UFRX_Pos) /**< \brief (GMAC_UFR) Undersize Frames Received */
/* -------- GMAC_OFR : (GMAC Offset: 0x188) Oversize Frames Received Register -------- */
#define GMAC_OFR_OFRX_Pos 0
#define GMAC_OFR_OFRX_Msk (0x3ffu << GMAC_OFR_OFRX_Pos) /**< \brief (GMAC_OFR) Oversized Frames Received */
/* -------- GMAC_JR : (GMAC Offset: 0x18C) Jabbers Received Register -------- */
#define GMAC_JR_JRX_Pos 0
#define GMAC_JR_JRX_Msk (0x3ffu << GMAC_JR_JRX_Pos) /**< \brief (GMAC_JR) Jabbers Received */
/* -------- GMAC_FCSE : (GMAC Offset: 0x190) Frame Check Sequence Errors Register -------- */
#define GMAC_FCSE_FCKR_Pos 0
#define GMAC_FCSE_FCKR_Msk (0x3ffu << GMAC_FCSE_FCKR_Pos) /**< \brief (GMAC_FCSE) Frame Check Sequence Errors */
/* -------- GMAC_LFFE : (GMAC Offset: 0x194) Length Field Frame Errors Register -------- */
#define GMAC_LFFE_LFER_Pos 0
#define GMAC_LFFE_LFER_Msk (0x3ffu << GMAC_LFFE_LFER_Pos) /**< \brief (GMAC_LFFE) Length Field Frame Errors */
/* -------- GMAC_RSE : (GMAC Offset: 0x198) Receive Symbol Errors Register -------- */
#define GMAC_RSE_RXSE_Pos 0
#define GMAC_RSE_RXSE_Msk (0x3ffu << GMAC_RSE_RXSE_Pos) /**< \brief (GMAC_RSE) Receive Symbol Errors */
/* -------- GMAC_AE : (GMAC Offset: 0x19C) Alignment Errors Register -------- */
#define GMAC_AE_AER_Pos 0
#define GMAC_AE_AER_Msk (0x3ffu << GMAC_AE_AER_Pos) /**< \brief (GMAC_AE) Alignment Errors */
/* -------- GMAC_RRE : (GMAC Offset: 0x1A0) Receive Resource Errors Register -------- */
#define GMAC_RRE_RXRER_Pos 0
#define GMAC_RRE_RXRER_Msk (0x3ffffu << GMAC_RRE_RXRER_Pos) /**< \brief (GMAC_RRE) Receive Resource Errors */
/* -------- GMAC_ROE : (GMAC Offset: 0x1A4) Receive Overrun Register -------- */
#define GMAC_ROE_RXOVR_Pos 0
#define GMAC_ROE_RXOVR_Msk (0x3ffu << GMAC_ROE_RXOVR_Pos) /**< \brief (GMAC_ROE) Receive Overruns */
/* -------- GMAC_IHCE : (GMAC Offset: 0x1A8) IP Header Checksum Errors Register -------- */
#define GMAC_IHCE_HCKER_Pos 0
#define GMAC_IHCE_HCKER_Msk (0xffu << GMAC_IHCE_HCKER_Pos) /**< \brief (GMAC_IHCE) IP Header Checksum Errors */
/* -------- GMAC_TCE : (GMAC Offset: 0x1AC) TCP Checksum Errors Register -------- */
#define GMAC_TCE_TCKER_Pos 0
#define GMAC_TCE_TCKER_Msk (0xffu << GMAC_TCE_TCKER_Pos) /**< \brief (GMAC_TCE) TCP Checksum Errors */
/* -------- GMAC_UCE : (GMAC Offset: 0x1B0) UDP Checksum Errors Register -------- */
#define GMAC_UCE_UCKER_Pos 0
#define GMAC_UCE_UCKER_Msk (0xffu << GMAC_UCE_UCKER_Pos) /**< \brief (GMAC_UCE) UDP Checksum Errors */
/* -------- GMAC_TSSS : (GMAC Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register -------- */
#define GMAC_TSSS_VTS_Pos 0
#define GMAC_TSSS_VTS_Msk (0xffffffffu << GMAC_TSSS_VTS_Pos) /**< \brief (GMAC_TSSS) Value of Timer Seconds Register Capture */
#define GMAC_TSSS_VTS(value) ((GMAC_TSSS_VTS_Msk & ((value) << GMAC_TSSS_VTS_Pos)))
/* -------- GMAC_TSSN : (GMAC Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register -------- */
#define GMAC_TSSN_VTN_Pos 0
#define GMAC_TSSN_VTN_Msk (0x3fffffffu << GMAC_TSSN_VTN_Pos) /**< \brief (GMAC_TSSN) Value Timer Nanoseconds Register Capture */
#define GMAC_TSSN_VTN(value) ((GMAC_TSSN_VTN_Msk & ((value) << GMAC_TSSN_VTN_Pos)))
/* -------- GMAC_TS : (GMAC Offset: 0x1D0) 1588 Timer Seconds Register -------- */
#define GMAC_TS_TCS_Pos 0
#define GMAC_TS_TCS_Msk (0xffffffffu << GMAC_TS_TCS_Pos) /**< \brief (GMAC_TS) Timer Count in Seconds */
#define GMAC_TS_TCS(value) ((GMAC_TS_TCS_Msk & ((value) << GMAC_TS_TCS_Pos)))
/* -------- GMAC_TN : (GMAC Offset: 0x1D4) 1588 Timer Nanoseconds Register -------- */
#define GMAC_TN_TNS_Pos 0
#define GMAC_TN_TNS_Msk (0x3fffffffu << GMAC_TN_TNS_Pos) /**< \brief (GMAC_TN) Timer Count in Nanoseconds */
#define GMAC_TN_TNS(value) ((GMAC_TN_TNS_Msk & ((value) << GMAC_TN_TNS_Pos)))
/* -------- GMAC_TA : (GMAC Offset: 0x1D8) 1588 Timer Adjust Register -------- */
#define GMAC_TA_ITDT_Pos 0
#define GMAC_TA_ITDT_Msk (0x3fffffffu << GMAC_TA_ITDT_Pos) /**< \brief (GMAC_TA) Increment/Decrement */
#define GMAC_TA_ITDT(value) ((GMAC_TA_ITDT_Msk & ((value) << GMAC_TA_ITDT_Pos)))
#define GMAC_TA_ADJ (0x1u << 31) /**< \brief (GMAC_TA) Adjust 1588 Timer */
/* -------- GMAC_TI : (GMAC Offset: 0x1DC) 1588 Timer Increment Register -------- */
#define GMAC_TI_CNS_Pos 0
#define GMAC_TI_CNS_Msk (0xffu << GMAC_TI_CNS_Pos) /**< \brief (GMAC_TI) Count Nanoseconds */
#define GMAC_TI_CNS(value) ((GMAC_TI_CNS_Msk & ((value) << GMAC_TI_CNS_Pos)))
#define GMAC_TI_ACNS_Pos 8
#define GMAC_TI_ACNS_Msk (0xffu << GMAC_TI_ACNS_Pos) /**< \brief (GMAC_TI) Alternative Count Nanoseconds */
#define GMAC_TI_ACNS(value) ((GMAC_TI_ACNS_Msk & ((value) << GMAC_TI_ACNS_Pos)))
#define GMAC_TI_NIT_Pos 16
#define GMAC_TI_NIT_Msk (0xffu << GMAC_TI_NIT_Pos) /**< \brief (GMAC_TI) Number of Increments */
#define GMAC_TI_NIT(value) ((GMAC_TI_NIT_Msk & ((value) << GMAC_TI_NIT_Pos)))
/* -------- GMAC_EFTS : (GMAC Offset: 0x1E0) PTP Event Frame Transmitted Seconds -------- */
#define GMAC_EFTS_RUD_Pos 0
#define GMAC_EFTS_RUD_Msk (0xffffffffu << GMAC_EFTS_RUD_Pos) /**< \brief (GMAC_EFTS) Register Update */
/* -------- GMAC_EFTN : (GMAC Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds -------- */
#define GMAC_EFTN_RUD_Pos 0
#define GMAC_EFTN_RUD_Msk (0x3fffffffu << GMAC_EFTN_RUD_Pos) /**< \brief (GMAC_EFTN) Register Update */
/* -------- GMAC_EFRS : (GMAC Offset: 0x1E8) PTP Event Frame Received Seconds -------- */
#define GMAC_EFRS_RUD_Pos 0
#define GMAC_EFRS_RUD_Msk (0xffffffffu << GMAC_EFRS_RUD_Pos) /**< \brief (GMAC_EFRS) Register Update */
/* -------- GMAC_EFRN : (GMAC Offset: 0x1EC) PTP Event Frame Received Nanoseconds -------- */
#define GMAC_EFRN_RUD_Pos 0
#define GMAC_EFRN_RUD_Msk (0x3fffffffu << GMAC_EFRN_RUD_Pos) /**< \brief (GMAC_EFRN) Register Update */
/* -------- GMAC_PEFTS : (GMAC Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds -------- */
#define GMAC_PEFTS_RUD_Pos 0
#define GMAC_PEFTS_RUD_Msk (0xffffffffu << GMAC_PEFTS_RUD_Pos) /**< \brief (GMAC_PEFTS) Register Update */
/* -------- GMAC_PEFTN : (GMAC Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds -------- */
#define GMAC_PEFTN_RUD_Pos 0
#define GMAC_PEFTN_RUD_Msk (0x3fffffffu << GMAC_PEFTN_RUD_Pos) /**< \brief (GMAC_PEFTN) Register Update */
/* -------- GMAC_PEFRS : (GMAC Offset: 0x1F8) PTP Peer Event Frame Received Seconds -------- */
#define GMAC_PEFRS_RUD_Pos 0
#define GMAC_PEFRS_RUD_Msk (0xffffffffu << GMAC_PEFRS_RUD_Pos) /**< \brief (GMAC_PEFRS) Register Update */
/* -------- GMAC_PEFRN : (GMAC Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds -------- */
#define GMAC_PEFRN_RUD_Pos 0
#define GMAC_PEFRN_RUD_Msk (0x3fffffffu << GMAC_PEFRN_RUD_Pos) /**< \brief (GMAC_PEFRN) Register Update */
/* -------- GMAC_ISRPQ[7] : (GMAC Offset: 0x400) Interrupt Status Register Priority Queue -------- */
#define GMAC_ISRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_ISRPQ[7]) Receive Complete */
#define GMAC_ISRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_ISRPQ[7]) RX Used Bit Read */
#define GMAC_ISRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_ISRPQ[7]) Retry Limit Exceeded or Late Collision */
#define GMAC_ISRPQ_TFC (0x1u << 6) /**< \brief (GMAC_ISRPQ[7]) Transmit Frame Corruption due to AHB error */
#define GMAC_ISRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_ISRPQ[7]) Transmit Complete */
#define GMAC_ISRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_ISRPQ[7]) Receive Overrun */
#define GMAC_ISRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_ISRPQ[7]) HRESP Not OK */
/* -------- GMAC_TBQBAPQ[7] : (GMAC Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue -------- */
#define GMAC_TBQBAPQ_TXBQBA_Pos 2
#define GMAC_TBQBAPQ_TXBQBA_Msk (0x3fu << GMAC_TBQBAPQ_TXBQBA_Pos) /**< \brief (GMAC_TBQBAPQ[7]) Transmit Buffer Queue Base Address */
#define GMAC_TBQBAPQ_TXBQBA(value) ((GMAC_TBQBAPQ_TXBQBA_Msk & ((value) << GMAC_TBQBAPQ_TXBQBA_Pos)))
/* -------- GMAC_RBQBAPQ[7] : (GMAC Offset: 0x480) Receive Buffer Queue Base Address Priority Queue -------- */
#define GMAC_RBQBAPQ_RXBQBA_Pos 2
#define GMAC_RBQBAPQ_RXBQBA_Msk (0x3fu << GMAC_RBQBAPQ_RXBQBA_Pos) /**< \brief (GMAC_RBQBAPQ[7]) Receive Buffer Queue Base Address */
#define GMAC_RBQBAPQ_RXBQBA(value) ((GMAC_RBQBAPQ_RXBQBA_Msk & ((value) << GMAC_RBQBAPQ_RXBQBA_Pos)))
/* -------- GMAC_RBSRPQ[7] : (GMAC Offset: 0x4A0) Receive Buffer Size Register Priority Queue -------- */
#define GMAC_RBSRPQ_RBS_Pos 0
#define GMAC_RBSRPQ_RBS_Msk (0xffffu << GMAC_RBSRPQ_RBS_Pos) /**< \brief (GMAC_RBSRPQ[7]) Receive Buffer Size */
#define GMAC_RBSRPQ_RBS(value) ((GMAC_RBSRPQ_RBS_Msk & ((value) << GMAC_RBSRPQ_RBS_Pos)))
/* -------- GMAC_ST1RPQ[16] : (GMAC Offset: 0x500) Screening Type1 Register Priority Queue -------- */
#define GMAC_ST1RPQ_QNB_Pos 0
#define GMAC_ST1RPQ_QNB_Msk (0xfu << GMAC_ST1RPQ_QNB_Pos) /**< \brief (GMAC_ST1RPQ[16]) Que Number (0->7) */
#define GMAC_ST1RPQ_QNB(value) ((GMAC_ST1RPQ_QNB_Msk & ((value) << GMAC_ST1RPQ_QNB_Pos)))
#define GMAC_ST1RPQ_DSTCM_Pos 4
#define GMAC_ST1RPQ_DSTCM_Msk (0xffu << GMAC_ST1RPQ_DSTCM_Pos) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match */
#define GMAC_ST1RPQ_DSTCM(value) ((GMAC_ST1RPQ_DSTCM_Msk & ((value) << GMAC_ST1RPQ_DSTCM_Pos)))
#define GMAC_ST1RPQ_UDPM_Pos 12
#define GMAC_ST1RPQ_UDPM_Msk (0xffffu << GMAC_ST1RPQ_UDPM_Pos) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match */
#define GMAC_ST1RPQ_UDPM(value) ((GMAC_ST1RPQ_UDPM_Msk & ((value) << GMAC_ST1RPQ_UDPM_Pos)))
#define GMAC_ST1RPQ_DSTCE (0x1u << 28) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match Enable */
#define GMAC_ST1RPQ_UDPE (0x1u << 29) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match Enable */
/* -------- GMAC_ST2RPQ[16] : (GMAC Offset: 0x540) Screening Type2 Register Priority Queue -------- */
#define GMAC_ST2RPQ_QNB_Pos 0
#define GMAC_ST2RPQ_QNB_Msk (0xfu << GMAC_ST2RPQ_QNB_Pos) /**< \brief (GMAC_ST2RPQ[16]) Que Number (0->7) */
#define GMAC_ST2RPQ_QNB(value) ((GMAC_ST2RPQ_QNB_Msk & ((value) << GMAC_ST2RPQ_QNB_Pos)))
#define GMAC_ST2RPQ_VLANP_Pos 4
#define GMAC_ST2RPQ_VLANP_Msk (0xfu << GMAC_ST2RPQ_VLANP_Pos) /**< \brief (GMAC_ST2RPQ[16]) VLAN Priority */
#define GMAC_ST2RPQ_VLANP(value) ((GMAC_ST2RPQ_VLANP_Msk & ((value) << GMAC_ST2RPQ_VLANP_Pos)))
#define GMAC_ST2RPQ_VLANE (0x1u << 8) /**< \brief (GMAC_ST2RPQ[16]) VLAN Enable */
/* -------- GMAC_IERPQ[7] : (GMAC Offset: 0x600) Interrupt Enable Register Priority Queue -------- */
#define GMAC_IERPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IERPQ[7]) Receive Complete */
#define GMAC_IERPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IERPQ[7]) RX Used Bit Read */
#define GMAC_IERPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IERPQ[7]) Retry Limit Exceeded or Late Collision */
#define GMAC_IERPQ_TFC (0x1u << 6) /**< \brief (GMAC_IERPQ[7]) Transmit Frame Corruption due to AHB error */
#define GMAC_IERPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IERPQ[7]) Transmit Complete */
#define GMAC_IERPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IERPQ[7]) Receive Overrun */
#define GMAC_IERPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IERPQ[7]) HRESP Not OK */
/* -------- GMAC_IDRPQ[7] : (GMAC Offset: 0x620) Interrupt Disable Register Priority Queue -------- */
#define GMAC_IDRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IDRPQ[7]) Receive Complete */
#define GMAC_IDRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IDRPQ[7]) RX Used Bit Read */
#define GMAC_IDRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IDRPQ[7]) Retry Limit Exceeded or Late Collision */
#define GMAC_IDRPQ_TFC (0x1u << 6) /**< \brief (GMAC_IDRPQ[7]) Transmit Frame Corruption due to AHB error */
#define GMAC_IDRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IDRPQ[7]) Transmit Complete */
#define GMAC_IDRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IDRPQ[7]) Receive Overrun */
#define GMAC_IDRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IDRPQ[7]) HRESP Not OK */
/* -------- GMAC_IMRPQ[7] : (GMAC Offset: 0x640) Interrupt Mask Register Priority Queue -------- */
#define GMAC_IMRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IMRPQ[7]) Receive Complete */
#define GMAC_IMRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IMRPQ[7]) RX Used Bit Read */
#define GMAC_IMRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IMRPQ[7]) Retry Limit Exceeded or Late Collision */
#define GMAC_IMRPQ_AHB (0x1u << 6) /**< \brief (GMAC_IMRPQ[7]) AHB Error */
#define GMAC_IMRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IMRPQ[7]) Transmit Complete */
#define GMAC_IMRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IMRPQ[7]) Receive Overrun */
#define GMAC_IMRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IMRPQ[7]) HRESP Not OK */
/*@}*/
#endif /* _SAM4E_GMAC_COMPONENT_ */

View File

@ -1,454 +0,0 @@
/**
* \file
*
* \brief API driver for KSZ8051MNL PHY component.
*
* Copyright (c) 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "FreeRTOSIPConfig.h"
#include "ethernet_phy.h"
#include "instance/gmac.h"
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/**
* \defgroup ksz8051mnl_ethernet_phy_group PHY component (KSZ8051MNL)
*
* Driver for the ksz8051mnl component. This driver provides access to the main
* features of the PHY.
*
* \section dependencies Dependencies
* This driver depends on the following modules:
* - \ref gmac_group Ethernet Media Access Controller (GMAC) module.
*
* @{
*/
SPhyProps phyProps;
/* Max PHY number */
#define ETH_PHY_MAX_ADDR 31
/* Ethernet PHY operation max retry count */
#define ETH_PHY_RETRY_MAX 1000000
/* Ethernet PHY operation timeout */
#define ETH_PHY_TIMEOUT 10
/**
* \brief Find a valid PHY Address ( from addrStart to 31 ).
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
* \param uc_start_addr Start address of the PHY to be searched.
*
* \return 0xFF when no valid PHY address is found.
*/
int ethernet_phy_addr = 0;
static uint8_t ethernet_phy_find_valid(Gmac *p_gmac, uint8_t uc_phy_addr,
uint8_t uc_start_addr)
{
uint32_t ul_value = 0;
uint8_t uc_cnt;
uint8_t uc_phy_address = uc_phy_addr;
gmac_enable_management(p_gmac, true);
/*
#define GMII_OUI_MSB 0x0022
#define GMII_OUI_LSB 0x05
PHYID1 = 0x0022
PHYID2 = 0x1550
0001_0101_0101_0000 = 0x1550 <= mask should be 0xFFF0
*/
/* Check the current PHY address */
gmac_phy_read(p_gmac, uc_phy_addr, GMII_PHYID1, &ul_value);
/* Find another one */
if (ul_value != GMII_OUI_MSB) {
ethernet_phy_addr = 0xFF;
for (uc_cnt = uc_start_addr; uc_cnt <= ETH_PHY_MAX_ADDR; uc_cnt++) {
uc_phy_address = (uc_phy_address + 1) & 0x1F;
ul_value = 0;
gmac_phy_read(p_gmac, uc_phy_address, GMII_PHYID1, &ul_value);
if (ul_value == GMII_OUI_MSB) {
ethernet_phy_addr = uc_phy_address;
break;
}
}
}
gmac_enable_management(p_gmac, false);
if (ethernet_phy_addr != 0xFF) {
gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_value);
}
return ethernet_phy_addr;
}
/**
* \brief Perform a HW initialization to the PHY and set up clocks.
*
* This should be called only once to initialize the PHY pre-settings.
* The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups).
* The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
* The RXDV pin is used to select test mode on reset (pulled up for test mode).
* The above pins should be predefined for corresponding settings in resetPins.
* The GMAC peripheral pins are configured after the reset is done.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
* \param ul_mck GMAC MCK.
*
* Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck)
{
uint8_t uc_rc = GMAC_TIMEOUT;
uint8_t uc_phy;
ethernet_phy_reset(GMAC,uc_phy_addr);
/* Configure GMAC runtime clock */
uc_rc = gmac_set_mdc_clock(p_gmac, mck);
if (uc_rc != GMAC_OK) {
return 0;
}
/* Check PHY Address */
uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0);
if (uc_phy == 0xFF) {
return 0;
}
if (uc_phy != uc_phy_addr) {
ethernet_phy_reset(p_gmac, uc_phy_addr);
}
phy_props.phy_chn = uc_phy;
return uc_phy;
}
/**
* \brief Get the Link & speed settings, and automatically set up the GMAC with the
* settings.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
* \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
*
* Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
uint8_t uc_apply_setting_flag)
{
uint32_t ul_stat1;
uint32_t ul_stat2;
uint8_t uc_phy_address, uc_speed = true, uc_fd = true;
uint8_t uc_rc = GMAC_TIMEOUT;
gmac_enable_management(p_gmac, true);
uc_phy_address = uc_phy_addr;
uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_stat1);
if (uc_rc != GMAC_OK) {
/* Disable PHY management and start the GMAC transfer */
gmac_enable_management(p_gmac, false);
return uc_rc;
}
if ((ul_stat1 & GMII_LINK_STATUS) == 0) {
/* Disable PHY management and start the GMAC transfer */
gmac_enable_management(p_gmac, false);
return GMAC_INVALID;
}
if (uc_apply_setting_flag == 0) {
/* Disable PHY management and start the GMAC transfer */
gmac_enable_management(p_gmac, false);
return uc_rc;
}
/* Read advertisement */
uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_ANAR, &ul_stat2);
phy_props.phy_stat1 = ul_stat1;
phy_props.phy_stat2 = ul_stat2;
if (uc_rc != GMAC_OK) {
/* Disable PHY management and start the GMAC transfer */
gmac_enable_management(p_gmac, false);
return uc_rc;
}
if ((ul_stat1 & GMII_100BASE_TX_FD) && (ul_stat2 & GMII_100TX_FDX)) {
/* Set GMAC for 100BaseTX and Full Duplex */
uc_speed = true;
uc_fd = true;
} else
if ((ul_stat1 & GMII_100BASE_T4_HD) && (ul_stat2 & GMII_100TX_HDX)) {
/* Set MII for 100BaseTX and Half Duplex */
uc_speed = true;
uc_fd = false;
} else
if ((ul_stat1 & GMII_10BASE_T_FD) && (ul_stat2 & GMII_10_FDX)) {
/* Set MII for 10BaseT and Full Duplex */
uc_speed = false;
uc_fd = true;
} else
if ((ul_stat1 & GMII_10BASE_T_HD) && (ul_stat2 & GMII_10_HDX)) {
/* Set MII for 10BaseT and Half Duplex */
uc_speed = false;
uc_fd = false;
}
gmac_set_speed(p_gmac, uc_speed);
gmac_enable_full_duplex(p_gmac, uc_fd);
/* Start the GMAC transfers */
gmac_enable_management(p_gmac, false);
return uc_rc;
}
PhyProps_t phy_props;
/**
* \brief Issue an auto negotiation of the PHY.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
*
* Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr)
{
uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
uint32_t ul_value;
uint32_t ul_phy_anar;
uint32_t ul_retry_count = 0;
uint8_t uc_speed = 0;
uint8_t uc_fd=0;
uint8_t uc_rc = GMAC_TIMEOUT;
gmac_enable_management(p_gmac, true);
/* Set up control register */
uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -1;
return uc_rc;
}
ul_value &= ~(uint32_t)GMII_AUTONEG; /* Remove auto-negotiation enable */
ul_value &= ~(uint32_t)(GMII_LOOPBACK | GMII_POWER_DOWN);
ul_value |= (uint32_t)GMII_ISOLATE; /* Electrically isolate PHY */
uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -2;
return uc_rc;
}
/*
* Set the Auto_negotiation Advertisement Register.
* MII advertising for Next page.
* 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
*/
ul_phy_anar = GMII_100TX_FDX | GMII_100TX_HDX | GMII_10_FDX | GMII_10_HDX |
GMII_AN_IEEE_802_3;
uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_ANAR, ul_phy_anar);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -3;
return uc_rc;
}
/* Read & modify control register */
uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -4;
return uc_rc;
}
ul_value |= GMII_SPEED_SELECT | GMII_AUTONEG | GMII_DUPLEX_MODE;
uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -5;
return uc_rc;
}
/* Restart auto negotiation */
ul_value |= (uint32_t)GMII_RESTART_AUTONEG;
ul_value &= ~(uint32_t)GMII_ISOLATE;
uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -6;
return uc_rc;
}
/* Check if auto negotiation is completed */
while (1) {
uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -7;
return uc_rc;
}
/* Done successfully */
if (ul_value & GMII_AUTONEG_COMP) {
break;
}
/* Timeout check */
if (ul_retry_max) {
if (++ul_retry_count >= ul_retry_max) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -8;
return GMAC_TIMEOUT;
}
}
}
/* Get the auto negotiate link partner base page */
uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_PCR1, &phy_props.phy_params);
if (uc_rc != GMAC_OK) {
gmac_enable_management(p_gmac, false);
phy_props.phy_result = -9;
return uc_rc;
}
/* Set up the GMAC link speed */
if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_FDX) {
/* Set MII for 100BaseTX and Full Duplex */
uc_speed = true;
uc_fd = true;
} else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_FDX) {
/* Set MII for 10BaseT and Full Duplex */
uc_speed = false;
uc_fd = true;
} else if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_HDX) {
/* Set MII for 100BaseTX and half Duplex */
uc_speed = true;
uc_fd = false;
} else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_HDX) {
/* Set MII for 10BaseT and half Duplex */
uc_speed = false;
uc_fd = false;
}
gmac_set_speed(p_gmac, uc_speed);
gmac_enable_full_duplex(p_gmac, uc_fd);
/* Select Media Independent Interface type */
gmac_select_mii_mode(p_gmac, ETH_PHY_MODE);
gmac_enable_transmit(GMAC, true);
gmac_enable_receive(GMAC, true);
gmac_enable_management(p_gmac, false);
phy_props.phy_result = 1;
return uc_rc;
}
/**
* \brief Issue a SW reset to reset all registers of the PHY.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
*
* \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr)
{
uint32_t ul_bmcr = GMII_RESET;
uint8_t uc_phy_address = uc_phy_addr;
uint32_t ul_timeout = ETH_PHY_TIMEOUT;
uint8_t uc_rc = GMAC_TIMEOUT;
gmac_enable_management(p_gmac, true);
ul_bmcr = GMII_RESET;
gmac_phy_write(p_gmac, uc_phy_address, GMII_BMCR, ul_bmcr);
do {
gmac_phy_read(p_gmac, uc_phy_address, GMII_BMCR, &ul_bmcr);
ul_timeout--;
} while ((ul_bmcr & GMII_RESET) && ul_timeout);
gmac_enable_management(p_gmac, false);
if (!ul_timeout) {
uc_rc = GMAC_OK;
}
return (uc_rc);
}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
/**
* \}
*/

View File

@ -1,281 +0,0 @@
/**
* \file
*
* \brief KSZ8051MNL (Ethernet PHY) driver for SAM.
*
* Copyright (c) 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef ETHERNET_PHY_H_INCLUDED
#define ETHERNET_PHY_H_INCLUDED
#include "compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
// IEEE defined Registers
#define GMII_BMCR 0x00 // Basic Control
#define GMII_BMSR 0x01 // Basic Status
#define GMII_PHYID1 0x02 // PHY Idendifier 1
#define GMII_PHYID2 0x03 // PHY Idendifier 2
#define GMII_ANAR 0x04 // Auto_Negotiation Advertisement
#define GMII_ANLPAR 0x05 // Auto_negotiation Link Partner Ability
#define GMII_ANER 0x06 // Auto-negotiation Expansion
#define GMII_ANNPR 0x07 // Auto-negotiation Next Page
#define GMII_ANLPNPAR 0x08 // Link Partner Next Page Ability
//#define GMII_1000BTCR 9 // 1000Base-T Control // Reserved
//#define GMII_1000BTSR 10 // 1000Base-T Status // Reserved
#define GMII_AFECR1 0x11 // AFE Control 1
//#define GMII_ERDWR 12 // Extend Register - Data Write Register
//#define GMII_ERDRR 13 // Extend Register - Data Read Register
//14 reserved
#define GMII_RXERCR 0x15 // RXER Counter
#define PHY_REG_01_BMSR 0x01 // Basic mode status register
#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
#define PHY_REG_05_LPA 0x05 // Link partner ability reg
#define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
#define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
#define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
#define PHY_REG_10_PHYSTS 0x10 // 16 RO PHY Status Register
#define PHY_REG_11_MICR 0x11 // 17 RW MII Interrupt Control Register
#define PHY_REG_12_MISR 0x12 // 18 RO MII Interrupt Status Register
#define PHY_REG_13_RESERVED1 0x13 // 19 RW RESERVED
#define PHY_REG_14_FCSCR 0x14 // 20 RO False Carrier Sense Counter Register
#define PHY_REG_15_RECR 0x15 // 21 RO Receive Error Counter Register
#define PHY_REG_16_PCSR 0x16 // 22 RW PCS Sub-Layer Configuration and Status Register
#define PHY_REG_17_RBR 0x17 // 23 RW RMII and Bypass Register
#define PHY_REG_18_LEDCR 0x18 // 24 RW LED Direct Control Register
#define PHY_REG_19_PHYCR 0x19 // 25 RW PHY Control Register
#define PHY_REG_1A_10BTSCR 0x1A // 26 RW 10Base-T Status/Control Register
#define PHY_REG_1B_CDCTRL1 0x1B // 27 RW CD Test Control Register and BIST Extensions Register
#define PHY_REG_1B_INT_CTRL 0x1B // 27 RW KSZ8041NL interrupt control
#define PHY_REG_1C_RESERVED2 0x1C // 28 RW RESERVED
#define PHY_REG_1D_EDCR 0x1D // 29 RW Energy Detect Control Register
#define PHY_REG_1E_RESERVED3 0x1E //
#define PHY_REG_1F_RESERVED4 0x1F // 30-31 RW RESERVED
#define PHY_REG_1E_PHYCR_1 0x1E //
#define PHY_REG_1F_PHYCR_2 0x1F //
#define PHY_SPEED_10 1
#define PHY_SPEED_100 2
#define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
#define PHY_MDIX_DIRECT 1
#define PHY_MDIX_CROSSED 2
#define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
#define PHY_DUPLEX_HALF 1
#define PHY_DUPLEX_FULL 2
#define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
typedef struct _SPhyProps {
unsigned char speed;
unsigned char mdix;
unsigned char duplex;
unsigned char spare;
} SPhyProps;
const char *phyPrintable (const SPhyProps *apProps);
extern SPhyProps phyProps;
#define GMII_OMSOR 0x16 // Operation Mode Strap Override
#define GMII_OMSSR 0x17 // Operation Mode Strap Status
#define GMII_ECR 0x18 // Expanded Control
//#define GMII_DPPSR 19 // Digital PMA/PCS Status
//20 reserved
//#define GMII_RXERCR 21 // RXER Counter Register
//22-26 reserved
#define GMII_ICSR 0x1B // Interrupt Control/Status
//#define GMII_DDC1R 28 // Digital Debug Control 1 Register
#define GMII_LCSR 0x1D // LinkMD Control/Status
//29-30 reserved
#define GMII_PCR1 0x1E // PHY Control 1
#define GMII_PCR2 0x1F // PHY Control 2
/*
//Extend Registers
#define GMII_CCR 256 // Common Control Register
#define GMII_SSR 257 // Strap Status Register
#define GMII_OMSOR 258 // Operation Mode Strap Override Register
#define GMII_OMSSR 259 // Operation Mode Strap Status Register
#define GMII_RCCPSR 260 // RGMII Clock and Control Pad Skew Register
#define GMII_RRDPSR 261 // RGMII RX Data Pad Skew Register
#define GMII_ATR 263 // Analog Test Register
*/
// Bit definitions: GMII_BMCR 0x00 Basic Control
#define GMII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
#define GMII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
#define GMII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
#define GMII_AUTONEG (1 << 12) // Auto-negotiation Enable
#define GMII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
#define GMII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
#define GMII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
#define GMII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
#define GMII_COLLISION_TEST (1 << 7) // 1 = Enable COL test; 0 = Disable COL test
//#define GMII_SPEED_SELECT_MSB (1 << 6) // Reserved
// Reserved 6 to 0 // Read as 0, ignore on write
// Bit definitions: GMII_BMSR 0x01 Basic Status
#define GMII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
#define GMII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
#define GMII_100BASE_T4_HD (1 << 13) // 100BASE-TX Half Duplex Capable
#define GMII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
#define GMII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
// Reserved 10 to79 // Read as 0, ignore on write
//#define GMII_EXTEND_STATUS (1 << 8) // 1 = Extend Status Information In Reg 15
// Reserved 7
#define GMII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
#define GMII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
#define GMII_REMOTE_FAULT (1 << 4) // Remote Fault
#define GMII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
#define GMII_LINK_STATUS (1 << 2) // Link Status
#define GMII_JABBER_DETECT (1 << 1) // Jabber Detect
#define GMII_EXTEND_CAPAB (1 << 0) // Extended Capability
// Bit definitions: GMII_PHYID1 0x02 PHY Idendifier 1
// Bit definitions: GMII_PHYID2 0x03 PHY Idendifier 2
#define GMII_LSB_MASK 0x3F
#define GMII_OUI_MSB 0x0022
#define GMII_OUI_LSB 0x05
// Bit definitions: GMII_ANAR 0x04 Auto_Negotiation Advertisement
// Bit definitions: GMII_ANLPAR 0x05 Auto_negotiation Link Partner Ability
#define GMII_NP (1 << 15) // Next page Indication
// Reserved 7
#define GMII_RF (1 << 13) // Remote Fault
// Reserved 12 // Write as 0, ignore on read
#define GMII_PAUSE_MASK (3 << 11) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
// 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
#define GMII_100T4 (1 << 9) // 100BASE-T4 Support
#define GMII_100TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
#define GMII_100TX_HDX (1 << 7) // 100BASE-TX Support
#define GMII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
#define GMII_10_HDX (1 << 5) // 10BASE-T Support
// Selector 4 to 0 // Protocol Selection Bits
#define GMII_AN_IEEE_802_3 0x0001 // [00001] = IEEE 802.3
// Bit definitions: GMII_ANER 0x06 Auto-negotiation Expansion
// Reserved 15 to 5 // Read as 0, ignore on write
#define GMII_PDF (1 << 4) // Local Device Parallel Detection Fault
#define GMII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
#define GMII_NP_ABLE (1 << 2) // Local Device Next Page Able
#define GMII_PAGE_RX (1 << 1) // New Page Received
#define GMII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
/**
* \brief Perform a HW initialization to the PHY and set up clocks.
*
* This should be called only once to initialize the PHY pre-settings.
* The PHY address is the reset status of CRS, RXD[3:0] (the GmacPins' pullups).
* The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
* The RXDV pin is used to select test mode on reset (pulled up for test mode).
* The above pins should be predefined for corresponding settings in resetPins.
* The GMAC peripheral pins are configured after the reset is done.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
* \param ul_mck GMAC MCK.
*
* Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t ul_mck);
/**
* \brief Get the Link & speed settings, and automatically set up the GMAC with the
* settings.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
* \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
*
* Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
uint8_t uc_apply_setting_flag);
/**
* \brief Issue an auto negotiation of the PHY.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
*
* Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr);
/**
* \brief Issue a SW reset to reset all registers of the PHY.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_addr PHY address.
*
* \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr);
typedef struct xPHY_PROPS {
signed char phy_result;
uint32_t phy_params;
uint32_t phy_stat1;
uint32_t phy_stat2;
unsigned char phy_chn;
} PhyProps_t;
extern PhyProps_t phy_props;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* #ifndef ETHERNET_PHY_H_INCLUDED */

View File

@ -1,945 +0,0 @@
/**
* \file
*
* \brief GMAC (Ethernet MAC) driver for SAM.
*
* Copyright (c) 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOSIPConfig.h"
#include "compiler.h"
#include "instance/gmac.h"
#include "ethernet_phy.h"
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (int)( sizeof(x) / sizeof(x)[0] )
#endif
/**
* \defgroup gmac_group Ethernet Media Access Controller
*
* See \ref gmac_quickstart.
*
* Driver for the GMAC (Ethernet Media Access Controller).
* This file contains basic functions for the GMAC, with support for all modes, settings
* and clock speeds.
*
* \section dependencies Dependencies
* This driver does not depend on other modules.
*
* @{
*/
/** TX descriptor lists */
COMPILER_ALIGNED(8)
static gmac_tx_descriptor_t gs_tx_desc[ GMAC_TX_BUFFERS ];
#if( GMAC_USES_TX_CALLBACK != 0 )
/** TX callback lists */
static gmac_dev_tx_cb_t gs_tx_callback[ GMAC_TX_BUFFERS ];
#endif
/** RX descriptors lists */
COMPILER_ALIGNED(8)
static gmac_rx_descriptor_t gs_rx_desc[ GMAC_RX_BUFFERS ];
#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
/** Send Buffer. Section 3.6 of AMBA 2.0 spec states that burst should not cross the
* 1K Boundaries. Receive buffer manager write operations are burst of 2 words => 3 lsb bits
* of the address shall be set to 0.
*/
COMPILER_ALIGNED(8)
static uint8_t gs_uc_tx_buffer[ GMAC_TX_BUFFERS * GMAC_TX_UNITSIZE ];
#endif /* ipconfigZERO_COPY_TX_DRIVER */
/** Receive Buffer */
COMPILER_ALIGNED(8)
static uint8_t gs_uc_rx_buffer[ GMAC_RX_BUFFERS * GMAC_RX_UNITSIZE ];
/**
* GMAC device memory management struct.
*/
typedef struct gmac_dev_mem {
/* Pointer to allocated buffer for RX. The address should be 8-byte aligned
and the size should be GMAC_RX_UNITSIZE * wRxSize. */
uint8_t *p_rx_buffer;
/* Pointer to allocated RX descriptor list. */
gmac_rx_descriptor_t *p_rx_dscr;
/* RX size, in number of registered units (RX descriptors). */
/* Increased size from 16- to 32-bits, because it's more efficient */
uint32_t us_rx_size;
/* Pointer to allocated buffer for TX. The address should be 8-byte aligned
and the size should be GMAC_TX_UNITSIZE * wTxSize. */
uint8_t *p_tx_buffer;
/* Pointer to allocated TX descriptor list. */
gmac_tx_descriptor_t *p_tx_dscr;
/* TX size, in number of registered units (TX descriptors). */
uint32_t us_tx_size;
} gmac_dev_mem_t;
/** Return count in buffer */
#define CIRC_CNT( head, tail, size ) ( ( ( head ) - ( tail ) ) % ( size ) )
/*
* Return space available, from 0 to size-1.
* Always leave one free char as a completely full buffer that has (head == tail),
* which is the same as empty.
*/
#define CIRC_SPACE( head, tail, size ) CIRC_CNT( ( tail ), ( ( head ) + 1 ), ( size ) )
/** Circular buffer is empty ? */
#define CIRC_EMPTY( head, tail ) ( head == tail )
/** Clear circular buffer */
#define CIRC_CLEAR( head, tail ) do { ( head ) = 0; ( tail ) = 0; } while( 0 )
/** Increment head or tail */
static __inline void circ_inc32( int32_t *lHeadOrTail, uint32_t ulSize )
{
( *lHeadOrTail ) ++;
if( ( *lHeadOrTail ) >= ( int32_t )ulSize )
{
( *lHeadOrTail ) = 0;
}
}
/**
* \brief Wait PHY operation to be completed.
*
* \param p_gmac HW controller address.
* \param ul_retry The retry times, 0 to wait forever until completeness.
*
* Return GMAC_OK if the operation is completed successfully.
*/
static uint8_t gmac_wait_phy(Gmac* p_gmac, const uint32_t ul_retry)
{
volatile uint32_t ul_retry_count = 0;
const uint32_t xPHYPollDelay = pdMS_TO_TICKS( 1ul );
while (!gmac_is_phy_idle(p_gmac)) {
if (ul_retry == 0) {
continue;
}
ul_retry_count++;
if (ul_retry_count >= ul_retry) {
return GMAC_TIMEOUT;
}
/* Block the task to allow other tasks to execute while the PHY
is not connected. */
vTaskDelay( xPHYPollDelay );
}
return GMAC_OK;
}
/**
* \brief Disable transfer, reset registers and descriptor lists.
*
* \param p_dev Pointer to GMAC driver instance.
*
*/
static void gmac_reset_tx_mem(gmac_device_t* p_dev)
{
Gmac *p_hw = p_dev->p_hw;
uint8_t *p_tx_buff = p_dev->p_tx_buffer;
gmac_tx_descriptor_t *p_td = p_dev->p_tx_dscr;
uint32_t ul_index;
uint32_t ul_address;
/* Disable TX */
gmac_enable_transmit(p_hw, 0);
/* Set up the TX descriptors */
CIRC_CLEAR(p_dev->l_tx_head, p_dev->l_tx_tail);
for( ul_index = 0; ul_index < p_dev->ul_tx_list_size; ul_index++ )
{
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
ul_address = (uint32_t) 0u;
}
#else
{
ul_address = (uint32_t) (&(p_tx_buff[ul_index * GMAC_TX_UNITSIZE]));
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
p_td[ul_index].addr = ul_address;
p_td[ul_index].status.val = GMAC_TXD_USED;
}
p_td[p_dev->ul_tx_list_size - 1].status.val =
GMAC_TXD_USED | GMAC_TXD_WRAP;
/* Set transmit buffer queue */
gmac_set_tx_queue(p_hw, (uint32_t) p_td);
}
/**
* \brief Disable receiver, reset registers and descriptor list.
*
* \param p_drv Pointer to GMAC Driver instance.
*/
static void gmac_reset_rx_mem(gmac_device_t* p_dev)
{
Gmac *p_hw = p_dev->p_hw;
uint8_t *p_rx_buff = p_dev->p_rx_buffer;
gmac_rx_descriptor_t *pRd = p_dev->p_rx_dscr;
uint32_t ul_index;
uint32_t ul_address;
/* Disable RX */
gmac_enable_receive(p_hw, 0);
/* Set up the RX descriptors */
p_dev->ul_rx_idx = 0;
for( ul_index = 0; ul_index < p_dev->ul_rx_list_size; ul_index++ )
{
ul_address = (uint32_t) (&(p_rx_buff[ul_index * GMAC_RX_UNITSIZE]));
pRd[ul_index].addr.val = ul_address & GMAC_RXD_ADDR_MASK;
pRd[ul_index].status.val = 0;
}
pRd[p_dev->ul_rx_list_size - 1].addr.val |= GMAC_RXD_WRAP;
/* Set receive buffer queue */
gmac_set_rx_queue(p_hw, (uint32_t) pRd);
}
/**
* \brief Initialize the allocated buffer lists for GMAC driver to transfer data.
* Must be invoked after gmac_dev_init() but before RX/TX starts.
*
* \note If input address is not 8-byte aligned, the address is automatically
* adjusted and the list size is reduced by one.
*
* \param p_gmac Pointer to GMAC instance.
* \param p_gmac_dev Pointer to GMAC device instance.
* \param p_dev_mm Pointer to the GMAC memory management control block.
* \param p_tx_cb Pointer to allocated TX callback list.
*
* \return GMAC_OK or GMAC_PARAM.
*/
static uint8_t gmac_init_mem(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
gmac_dev_mem_t* p_dev_mm
#if( GMAC_USES_TX_CALLBACK != 0 )
, gmac_dev_tx_cb_t* p_tx_cb
#endif
)
{
if (p_dev_mm->us_rx_size <= 1 || p_dev_mm->us_tx_size <= 1
#if( GMAC_USES_TX_CALLBACK != 0 )
|| p_tx_cb == NULL
#endif
) {
return GMAC_PARAM;
}
/* Assign RX buffers */
if (((uint32_t) p_dev_mm->p_rx_buffer & 0x7)
|| ((uint32_t) p_dev_mm->p_rx_dscr & 0x7)) {
p_dev_mm->us_rx_size--;
}
p_gmac_dev->p_rx_buffer =
(uint8_t *) ((uint32_t) p_dev_mm->p_rx_buffer & 0xFFFFFFF8);
p_gmac_dev->p_rx_dscr =
(gmac_rx_descriptor_t *) ((uint32_t) p_dev_mm->p_rx_dscr
& 0xFFFFFFF8);
p_gmac_dev->ul_rx_list_size = p_dev_mm->us_rx_size;
/* Assign TX buffers */
if (((uint32_t) p_dev_mm->p_tx_buffer & 0x7)
|| ((uint32_t) p_dev_mm->p_tx_dscr & 0x7)) {
p_dev_mm->us_tx_size--;
}
p_gmac_dev->p_tx_buffer =
(uint8_t *) ((uint32_t) p_dev_mm->p_tx_buffer & 0xFFFFFFF8);
p_gmac_dev->p_tx_dscr =
(gmac_tx_descriptor_t *) ((uint32_t) p_dev_mm->p_tx_dscr
& 0xFFFFFFF8);
p_gmac_dev->ul_tx_list_size = p_dev_mm->us_tx_size;
#if( GMAC_USES_TX_CALLBACK != 0 )
p_gmac_dev->func_tx_cb_list = p_tx_cb;
#endif
/* Reset TX & RX */
gmac_reset_rx_mem(p_gmac_dev);
gmac_reset_tx_mem(p_gmac_dev);
/* Enable Rx and Tx, plus the statistics register */
gmac_enable_transmit(p_gmac, true);
gmac_enable_receive(p_gmac, true);
gmac_enable_statistics_write(p_gmac, true);
/* Set up the interrupts for transmission and errors */
gmac_enable_interrupt(p_gmac,
GMAC_IER_RXUBR | /* Enable receive used bit read interrupt. */
GMAC_IER_TUR | /* Enable transmit underrun interrupt. */
GMAC_IER_RLEX | /* Enable retry limit exceeded interrupt. */
GMAC_IER_TFC | /* Enable transmit buffers exhausted in mid-frame interrupt. */
GMAC_IER_TCOMP | /* Enable transmit complete interrupt. */
GMAC_IER_ROVR | /* Enable receive overrun interrupt. */
GMAC_IER_HRESP | /* Enable Hresp not OK interrupt. */
GMAC_IER_PFNZ | /* Enable pause frame received interrupt. */
GMAC_IER_PTZ); /* Enable pause time zero interrupt. */
return GMAC_OK;
}
/**
* \brief Read the PHY register.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_address PHY address.
* \param uc_address Register address.
* \param p_value Pointer to a 32-bit location to store read data.
*
* \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
uint32_t* p_value)
{
gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 1, 0);
if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
return GMAC_TIMEOUT;
}
*p_value = gmac_get_phy_data(p_gmac);
return GMAC_OK;
}
/**
* \brief Write the PHY register.
*
* \param p_gmac Pointer to the GMAC instance.
* \param uc_phy_address PHY Address.
* \param uc_address Register Address.
* \param ul_value Data to write, actually 16-bit data.
*
* \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
*/
uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
uint8_t uc_address, uint32_t ul_value)
{
gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 0, ul_value);
if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
return GMAC_TIMEOUT;
}
return GMAC_OK;
}
/**
* \brief Initialize the GMAC driver.
*
* \param p_gmac Pointer to the GMAC instance.
* \param p_gmac_dev Pointer to the GMAC device instance.
* \param p_opt GMAC configure options.
*/
void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
gmac_options_t* p_opt)
{
gmac_dev_mem_t gmac_dev_mm;
/* Disable TX & RX and more */
gmac_network_control(p_gmac, 0);
gmac_disable_interrupt(p_gmac, ~0u);
gmac_clear_statistics(p_gmac);
/* Clear all status bits in the receive status register. */
gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA);
/* Clear all status bits in the transmit status register */
gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
| GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND);
/* Clear interrupts */
gmac_get_interrupt_status(p_gmac);
#if !defined(ETHERNET_CONF_DATA_OFFSET)
/* Receive Buffer Offset
* Indicates the number of bytes by which the received data
* is offset from the start of the receive buffer
* which can be handy for alignment reasons */
/* Note: FreeRTOS+TCP wants to have this offset set to 2 bytes */
#error ETHERNET_CONF_DATA_OFFSET not defined, assuming 0
#endif
/* Enable the copy of data into the buffers
ignore broadcasts, and not copy FCS. */
gmac_set_configure(p_gmac,
( gmac_get_configure(p_gmac) & ~GMAC_NCFGR_RXBUFO_Msk ) |
GMAC_NCFGR_RFCS | /* Remove FCS, frame check sequence (last 4 bytes) */
GMAC_NCFGR_PEN | /* Pause Enable */
GMAC_NCFGR_RXBUFO( ETHERNET_CONF_DATA_OFFSET ) |
GMAC_RXD_RXCOEN );
/*
* GMAC_DCFGR_TXCOEN: (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable.
* Note: tha SAM4E does have RX checksum offloading
* but TX checksum offloading has NOT been implemented.
* http://community.atmel.com/forum/sam4e-gmac-transmit-checksum-offload-enablesolved
*/
gmac_set_dma(p_gmac,
gmac_get_dma(p_gmac) | GMAC_DCFGR_TXCOEN );
gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame);
gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast);
/* Fill in GMAC device memory management */
gmac_dev_mm.p_rx_buffer = gs_uc_rx_buffer;
gmac_dev_mm.p_rx_dscr = gs_rx_desc;
gmac_dev_mm.us_rx_size = GMAC_RX_BUFFERS;
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
gmac_dev_mm.p_tx_buffer = NULL;
}
#else
{
gmac_dev_mm.p_tx_buffer = gs_uc_tx_buffer;
}
#endif
gmac_dev_mm.p_tx_dscr = gs_tx_desc;
gmac_dev_mm.us_tx_size = GMAC_TX_BUFFERS;
gmac_init_mem(p_gmac, p_gmac_dev, &gmac_dev_mm
#if( GMAC_USES_TX_CALLBACK != 0 )
, gs_tx_callback
#endif
);
gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr);
}
/**
* \brief Frames can be read from the GMAC in multiple sections.
*
* Returns > 0 if a complete frame is available
* It also it cleans up incomplete older frames
*/
static uint32_t gmac_dev_poll(gmac_device_t* p_gmac_dev)
{
uint32_t ulReturn = 0;
int32_t ulIndex = p_gmac_dev->ul_rx_idx;
gmac_rx_descriptor_t *pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
/* Discard any incomplete frames */
while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) &&
(pxHead->status.val & GMAC_RXD_SOF) == 0) {
pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
p_gmac_dev->ul_rx_idx = ulIndex;
#if( GMAC_STATS != 0 )
{
gmacStats.incompCount++;
}
#endif
}
while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) != 0) {
if ((pxHead->status.val & GMAC_RXD_EOF) != 0) {
/* Here a complete frame has been seen with SOF and EOF */
ulReturn = pxHead->status.bm.len;
break;
}
circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
if ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) == 0) {
/* CPU is not the owner (yet) */
break;
}
if ((pxHead->status.val & GMAC_RXD_SOF) != 0) {
/* Strange, we found a new Start Of Frame
* discard previous segments */
int32_t ulPrev = p_gmac_dev->ul_rx_idx;
pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
do {
pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
circ_inc32 (&ulPrev, p_gmac_dev->ul_rx_list_size);
pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
#if( GMAC_STATS != 0 )
{
gmacStats.truncCount++;
}
#endif
} while (ulPrev != ulIndex);
p_gmac_dev->ul_rx_idx = ulIndex;
}
}
return ulReturn;
}
/**
* \brief Frames can be read from the GMAC in multiple sections.
* Read ul_frame_size bytes from the GMAC receive buffers to pcTo.
* p_rcv_size is the size of the entire frame. Generally gmac_read
* will be repeatedly called until the sum of all the ul_frame_size equals
* the value of p_rcv_size.
*
* \param p_gmac_dev Pointer to the GMAC device instance.
* \param p_frame Address of the frame buffer.
* \param ul_frame_size Length of the frame.
* \param p_rcv_size Received frame size.
*
* \return GMAC_OK if receiving frame successfully, otherwise failed.
*/
uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
uint32_t ul_frame_size, uint32_t* p_rcv_size)
{
int32_t nextIdx; /* A copy of the Rx-index 'ul_rx_idx' */
int32_t bytesLeft = gmac_dev_poll (p_gmac_dev);
gmac_rx_descriptor_t *pxHead;
if (bytesLeft == 0 )
{
return GMAC_RX_NULL;
}
/* gmac_dev_poll has confirmed that there is a complete frame at
* the current position 'ul_rx_idx'
*/
nextIdx = p_gmac_dev->ul_rx_idx;
/* Read +2 bytes because buffers are aligned at -2 bytes */
bytesLeft = min( bytesLeft + 2, ( int32_t )ul_frame_size );
/* The frame will be copied in 1 or 2 memcpy's */
if( ( p_frame != NULL ) && ( bytesLeft != 0 ) )
{
const uint8_t *source;
int32_t left;
int32_t toCopy;
source = p_gmac_dev->p_rx_buffer + nextIdx * GMAC_RX_UNITSIZE;
left = bytesLeft;
toCopy = ( p_gmac_dev->ul_rx_list_size - nextIdx ) * GMAC_RX_UNITSIZE;
if(toCopy > left )
{
toCopy = left;
}
memcpy (p_frame, source, toCopy);
left -= toCopy;
if( left != 0ul )
{
memcpy (p_frame + toCopy, (void*)p_gmac_dev->p_rx_buffer, left);
}
}
do
{
pxHead = &p_gmac_dev->p_rx_dscr[nextIdx];
pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
circ_inc32 (&nextIdx, p_gmac_dev->ul_rx_list_size);
} while ((pxHead->status.val & GMAC_RXD_EOF) == 0);
p_gmac_dev->ul_rx_idx = nextIdx;
*p_rcv_size = bytesLeft;
return GMAC_OK;
}
extern void vGMACGenerateChecksum( uint8_t *apBuffer );
/**
* \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
* GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready.
* If lEndOfFrame is true then the data being copied is the end of the frame
* and the frame can be transmitted.
*
* \param p_gmac_dev Pointer to the GMAC device instance.
* \param p_buffer Pointer to the data buffer.
* \param ul_size Length of the frame.
* \param func_tx_cb Transmit callback function.
*
* \return Length sent.
*/
uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb)
{
volatile gmac_tx_descriptor_t *p_tx_td;
#if( GMAC_USES_TX_CALLBACK != 0 )
volatile gmac_dev_tx_cb_t *p_func_tx_cb;
#endif
Gmac *p_hw = p_gmac_dev->p_hw;
#if( GMAC_USES_TX_CALLBACK == 0 )
( void )func_tx_cb;
#endif
/* Check parameter */
if (ul_size > GMAC_TX_UNITSIZE) {
return GMAC_PARAM;
}
/* Pointers to the current transmit descriptor */
p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_head];
/* If no free TxTd, buffer can't be sent, schedule the wakeup callback */
// if (CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
// p_gmac_dev->ul_tx_list_size) == 0)
{
if ((p_tx_td->status.val & GMAC_TXD_USED) == 0)
return GMAC_TX_BUSY;
}
#if( GMAC_USES_TX_CALLBACK != 0 )
/* Pointers to the current Tx callback */
p_func_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_head];
#endif
/* Set up/copy data to transmission buffer */
if (p_buffer && ul_size) {
/* Driver manages the ring buffer */
/* Calculating the checksum here is faster than calculating it from the GMAC buffer
* because withing p_buffer, it is well aligned */
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
/* Zero-copy... */
p_tx_td->addr = ( uint32_t ) p_buffer;
}
#else
{
/* Or memcopy... */
memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr );
}
#if( GMAC_USES_TX_CALLBACK != 0 )
/* Tx callback */
*p_func_tx_cb = func_tx_cb;
#endif
/* Update transmit descriptor status */
/* The buffer size defined is the length of ethernet frame,
so it's always the last buffer of the frame. */
if( p_gmac_dev->l_tx_head == ( int32_t )( p_gmac_dev->ul_tx_list_size - 1 ) )
{
/* No need to 'and' with GMAC_TXD_LEN_MASK because ul_size has been checked */
p_tx_td->status.val =
ul_size | GMAC_TXD_LAST | GMAC_TXD_WRAP;
} else {
p_tx_td->status.val =
ul_size | GMAC_TXD_LAST;
}
circ_inc32( &p_gmac_dev->l_tx_head, p_gmac_dev->ul_tx_list_size );
/* Now start to transmit if it is still not done */
gmac_start_transmission(p_hw);
return GMAC_OK;
}
/**
* \brief Get current load of transmit.
*
* \param p_gmac_dev Pointer to the GMAC device instance.
*
* \return Current load of transmit.
*/
#if( GMAC_USES_TX_CALLBACK != 0 )
/* Without defining GMAC_USES_TX_CALLBACK, l_tx_tail won't be updated */
uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev)
{
uint16_t us_head = p_gmac_dev->l_tx_head;
uint16_t us_tail = p_gmac_dev->l_tx_tail;
return CIRC_CNT(us_head, us_tail, p_gmac_dev->ul_tx_list_size);
}
#endif
/**
* \brief Register/Clear RX callback. Callback will be invoked after the next received
* frame.
*
* When gmac_dev_read() returns GMAC_RX_NULL, the application task calls
* gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state.
* The callback is in charge to resume the task once a new frame has been
* received. The next time gmac_dev_read() is called, it will be successful.
*
* This function is usually invoked from the RX callback itself with NULL
* callback, to unregister. Once the callback has resumed the application task,
* there is no need to invoke the callback again.
*
* \param p_gmac_dev Pointer to the GMAC device instance.
* \param func_tx_cb Receive callback function.
*/
void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
gmac_dev_rx_cb_t func_rx_cb)
{
Gmac *p_hw = p_gmac_dev->p_hw;
if (func_rx_cb == NULL) {
gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP);
p_gmac_dev->func_rx_cb = NULL;
} else {
p_gmac_dev->func_rx_cb = func_rx_cb;
gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP);
}
}
/**
* \brief Register/Clear TX wakeup callback.
*
* When gmac_dev_write() returns GMAC_TX_BUSY (all transmit descriptor busy), the application
* task calls gmac_dev_set_tx_wakeup_callback() to register func_wakeup() callback and
* enters suspend state. The callback is in charge to resume the task once
* several transmit descriptors have been released. The next time gmac_dev_write() will be called,
* it shall be successful.
*
* This function is usually invoked with NULL callback from the TX wakeup
* callback itself, to unregister. Once the callback has resumed the
* application task, there is no need to invoke the callback again.
*
* \param p_gmac_dev Pointer to GMAC device instance.
* \param func_wakeup Pointer to wakeup callback function.
* \param uc_threshold Number of free transmit descriptor before wakeup callback invoked.
*
* \return GMAC_OK, GMAC_PARAM on parameter error.
*/
#if( GMAC_USES_WAKEUP_CALLBACK )
uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
gmac_dev_wakeup_cb_t func_wakeup_cb, uint8_t uc_threshold)
{
if (func_wakeup_cb == NULL) {
p_gmac_dev->func_wakeup_cb = NULL;
} else {
if (uc_threshold <= p_gmac_dev->ul_tx_list_size) {
p_gmac_dev->func_wakeup_cb = func_wakeup_cb;
p_gmac_dev->uc_wakeup_threshold = uc_threshold;
} else {
return GMAC_PARAM;
}
}
return GMAC_OK;
}
#endif /* GMAC_USES_WAKEUP_CALLBACK */
/**
* \brief Reset TX & RX queue & statistics.
*
* \param p_gmac_dev Pointer to GMAC device instance.
*/
void gmac_dev_reset(gmac_device_t* p_gmac_dev)
{
Gmac *p_hw = p_gmac_dev->p_hw;
gmac_reset_rx_mem(p_gmac_dev);
gmac_reset_tx_mem(p_gmac_dev);
gmac_network_control(p_hw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
| GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
}
void gmac_dev_halt(Gmac* p_gmac);
void gmac_dev_halt(Gmac* p_gmac)
{
gmac_network_control(p_gmac, GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
gmac_disable_interrupt(p_gmac, ~0u);
}
/**
* \brief GMAC Interrupt handler.
*
* \param p_gmac_dev Pointer to GMAC device instance.
*/
#if( GMAC_STATS != 0 )
extern int logPrintf( const char *pcFormat, ... );
void gmac_show_irq_counts ()
{
int index;
for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
if (gmacStats.intStatus[intPairs[index].index]) {
logPrintf("%s : %6u\n", intPairs[index].name, gmacStats.intStatus[intPairs[index].index]);
}
}
}
#endif
void gmac_handler(gmac_device_t* p_gmac_dev)
{
Gmac *p_hw = p_gmac_dev->p_hw;
#if( GMAC_USES_TX_CALLBACK != 0 )
gmac_tx_descriptor_t *p_tx_td;
gmac_dev_tx_cb_t *p_tx_cb = NULL;
uint32_t ul_tx_status_flag;
#endif
#if( GMAC_STATS != 0 )
int index;
#endif
/* volatile */ uint32_t ul_isr;
/* volatile */ uint32_t ul_rsr;
/* volatile */ uint32_t ul_tsr;
ul_isr = gmac_get_interrupt_status(p_hw);
ul_rsr = gmac_get_rx_status(p_hw);
ul_tsr = gmac_get_tx_status(p_hw);
/* Why clear bits that are ignored anyway ? */
/* ul_isr &= ~(gmac_get_interrupt_mask(p_hw) | 0xF8030300); */
#if( GMAC_STATS != 0 )
{
for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
if (ul_isr & intPairs[index].mask)
gmacStats.intStatus[intPairs[index].index]++;
}
}
#endif /* GMAC_STATS != 0 */
/* RX packet */
if ((ul_isr & GMAC_ISR_RCOMP) || (ul_rsr & (GMAC_RSR_REC|GMAC_RSR_RXOVR|GMAC_RSR_BNA))) {
/* Clear status */
gmac_clear_rx_status(p_hw, ul_rsr);
if (ul_isr & GMAC_ISR_RCOMP)
ul_rsr |= GMAC_RSR_REC;
/* Invoke callbacks which can be useful to wake op a task */
if (p_gmac_dev->func_rx_cb) {
p_gmac_dev->func_rx_cb(ul_rsr);
}
}
/* TX packet */
if ((ul_isr & GMAC_ISR_TCOMP) || (ul_tsr & (GMAC_TSR_TXCOMP|GMAC_TSR_COL|GMAC_TSR_RLE|GMAC_TSR_UND))) {
#if( GMAC_USES_TX_CALLBACK != 0 )
ul_tx_status_flag = GMAC_TSR_TXCOMP;
#endif
/* A frame transmitted */
/* Check RLE */
if (ul_tsr & GMAC_TSR_RLE) {
/* Status RLE & Number of discarded buffers */
#if( GMAC_USES_TX_CALLBACK != 0 )
ul_tx_status_flag = GMAC_TSR_RLE | CIRC_CNT(p_gmac_dev->l_tx_head,
p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
#endif
gmac_reset_tx_mem(p_gmac_dev);
gmac_enable_transmit(p_hw, 1);
}
/* Clear status */
gmac_clear_tx_status(p_hw, ul_tsr);
#if( GMAC_USES_TX_CALLBACK != 0 )
if (!CIRC_EMPTY(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail)) {
/* Check the buffers */
do {
p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_tail];
p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
/* Any error? Exit if buffer has not been sent yet */
if ((p_tx_td->status.val & GMAC_TXD_USED) == 0) {
break;
}
/* Notify upper layer that a packet has been sent */
if (*p_tx_cb) {
(*p_tx_cb) (ul_tx_status_flag, (void*)p_tx_td->addr);
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
p_tx_td->addr = 0ul;
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
}
circ_inc32(&p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
} while (CIRC_CNT(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
p_gmac_dev->ul_tx_list_size));
}
if (ul_tsr & GMAC_TSR_RLE) {
/* Notify upper layer RLE */
if (*p_tx_cb) {
(*p_tx_cb) (ul_tx_status_flag, NULL);
}
}
#endif /* GMAC_USES_TX_CALLBACK */
#if( GMAC_USES_WAKEUP_CALLBACK )
/* If a wakeup has been scheduled, notify upper layer that it can
send other packets, and the sending will be successful. */
if ((CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
p_gmac_dev->ul_tx_list_size) >= p_gmac_dev->uc_wakeup_threshold)
&& p_gmac_dev->func_wakeup_cb) {
p_gmac_dev->func_wakeup_cb();
}
#endif
}
}
//@}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond

View File

@ -1,664 +0,0 @@
/*
* Handling of Ethernet PHY's
* PHY's communicate with an EMAC either through
* a Media-Independent Interface (MII), or a Reduced Media-Independent Interface (RMII).
* The EMAC can poll for PHY ports on 32 different addresses. Each of the PHY ports
* shall be treated independently.
*
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.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 "phyHandling.h"
#include "eventLogging.h"
#define phyMIN_PHY_ADDRESS 0
#define phyMAX_PHY_ADDRESS 31
#if defined( PHY_LS_HIGH_CHECK_TIME_MS ) || defined( PHY_LS_LOW_CHECK_TIME_MS )
#warning please use the new defines with 'ipconfig' prefix
#endif
#ifndef ipconfigPHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
receiving packets. */
#define ipconfigPHY_LS_HIGH_CHECK_TIME_MS 15000
#endif
#ifndef ipconfigPHY_LS_LOW_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still low every second. */
#define ipconfigPHY_LS_LOW_CHECK_TIME_MS 1000
#endif
/* Naming and numbering of basic PHY registers. */
#define phyREG_00_BMCR 0x00u /* Basic Mode Control Register. */
#define phyREG_01_BMSR 0x01u /* Basic Mode Status Register. */
#define phyREG_02_PHYSID1 0x02u /* PHYS ID 1 */
#define phyREG_03_PHYSID2 0x03u /* PHYS ID 2 */
#define phyREG_04_ADVERTISE 0x04u /* Advertisement control reg */
/* Naming and numbering of extended PHY registers. */
#define PHYREG_10_PHYSTS 0x10u /* 16 PHY status register Offset */
#define phyREG_19_PHYCR 0x19u /* 25 RW PHY Control Register */
#define phyREG_1F_PHYSPCS 0x1Fu /* 31 RW PHY Special Control Status */
/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
#define phyBMCR_FULL_DUPLEX 0x0100u /* Full duplex. */
#define phyBMCR_AN_RESTART 0x0200u /* Auto negotiation restart. */
#define phyBMCR_AN_ENABLE 0x1000u /* Enable auto negotiation. */
#define phyBMCR_SPEED_100 0x2000u /* Select 100Mbps. */
#define phyBMCR_RESET 0x8000u /* Reset the PHY. */
/* Bit fields for 'phyREG_19_PHYCR', the 'PHY Control Register'. */
#define PHYCR_MDIX_EN 0x8000u /* Enable Auto MDIX. */
#define PHYCR_MDIX_FORCE 0x4000u /* Force MDIX crossed. */
#define phyBMSR_AN_COMPLETE 0x0020u /* Auto-Negotiation process completed */
#define phyBMSR_LINK_STATUS 0x0004u
#define phyPHYSTS_LINK_STATUS 0x0001u /* PHY Link mask */
#define phyPHYSTS_SPEED_STATUS 0x0002u /* PHY Speed mask */
#define phyPHYSTS_DUPLEX_STATUS 0x0004u /* PHY Duplex mask */
/* Bit fields for 'phyREG_1F_PHYSPCS
001 = 10BASE-T half-duplex
101 = 10BASE-T full-duplex
010 = 100BASE-TX half-duplex
110 = 100BASE-TX full-duplex
*/
#define phyPHYSPCS_SPEED_MASK 0x000Cu
#define phyPHYSPCS_SPEED_10 0x0004u
#define phyPHYSPCS_FULL_DUPLEX 0x0010u
/*
* Description of all capabilities that can be advertised to
* the peer (usually a switch or router).
*/
#define phyADVERTISE_CSMA 0x0001u /* Only selector supported. */
#define phyADVERTISE_10HALF 0x0020u /* Try for 10mbps half-duplex. */
#define phyADVERTISE_10FULL 0x0040u /* Try for 10mbps full-duplex. */
#define phyADVERTISE_100HALF 0x0080u /* Try for 100mbps half-duplex. */
#define phyADVERTISE_100FULL 0x0100u /* Try for 100mbps full-duplex. */
#define phyADVERTISE_ALL ( phyADVERTISE_10HALF | phyADVERTISE_10FULL | \
phyADVERTISE_100HALF | phyADVERTISE_100FULL )
/* Send a reset commando to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask );
static BaseType_t xHas_1F_PHYSPCS( uint32_t ulPhyID )
{
BaseType_t xResult;
switch( ulPhyID )
{
case PHY_ID_LAN8720:
case PHY_ID_LAN8742A:
case PHY_ID_KSZ8041:
/*
case PHY_ID_KSZ8051: // same ID as 8041
case PHY_ID_KSZ8081: // same ID as 8041
*/
case PHY_ID_KSZ8863:
default:
/* Most PHY's have a 1F_PHYSPCS */
xResult = pdTRUE;
break;
case PHY_ID_DP83848I:
xResult = pdFALSE;
break;
}
return xResult;
}
/*-----------------------------------------------------------*/
static BaseType_t xHas_19_PHYCR( uint32_t ulPhyID )
{
BaseType_t xResult;
switch( ulPhyID )
{
case PHY_ID_LAN8742A:
case PHY_ID_DP83848I:
xResult = pdTRUE;
break;
default:
/* Most PHY's do not have a 19_PHYCR */
xResult = pdFALSE;
break;
}
return xResult;
}
/*-----------------------------------------------------------*/
/* Initialise the struct and assign a PHY-read and -write function. */
void vPhyInitialise( EthernetPhy_t *pxPhyObject, xApplicationPhyReadHook_t fnPhyRead, xApplicationPhyWriteHook_t fnPhyWrite )
{
memset( ( void * )pxPhyObject, '\0', sizeof( *pxPhyObject ) );
pxPhyObject->fnPhyRead = fnPhyRead;
pxPhyObject->fnPhyWrite = fnPhyWrite;
}
/*-----------------------------------------------------------*/
/* Discover all PHY's connected by polling 32 indexes ( zero-based ) */
BaseType_t xPhyDiscover( EthernetPhy_t *pxPhyObject )
{
BaseType_t xPhyAddress;
pxPhyObject->xPortCount = 0;
for( xPhyAddress = phyMIN_PHY_ADDRESS; xPhyAddress <= phyMAX_PHY_ADDRESS; xPhyAddress++ )
{
uint32_t ulLowerID;
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_03_PHYSID2, &ulLowerID );
/* A valid PHY id can not be all zeros or all ones. */
if( ( ulLowerID != ( uint16_t )~0u ) && ( ulLowerID != ( uint16_t )0u ) )
{
uint32_t ulUpperID;
uint32_t ulPhyID;
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_02_PHYSID1, &ulUpperID );
ulPhyID = ( ( ( uint32_t ) ulUpperID ) << 16 ) | ( ulLowerID & 0xFFF0 );
pxPhyObject->ucPhyIndexes[ pxPhyObject->xPortCount ] = xPhyAddress;
pxPhyObject->ulPhyIDs[ pxPhyObject->xPortCount ] = ulPhyID;
pxPhyObject->xPortCount++;
/* See if there is more storage space. */
if( pxPhyObject->xPortCount == ipconfigPHY_MAX_PORTS )
{
break;
}
}
}
if( pxPhyObject->xPortCount > 0 )
{
FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
eventLogAdd( "PHY ID 0x%lX", pxPhyObject->ulPhyIDs[ 0 ] );
}
return pxPhyObject->xPortCount;
}
/*-----------------------------------------------------------*/
/* Send a reset commando to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
uint32_t ulDoneMask, ulConfig;
TickType_t xRemainingTime;
TimeOut_t xTimer;
BaseType_t xPhyIndex;
/* A bit-mask ofPHY ports that are ready. */
ulDoneMask = 0ul;
/* Set the RESET bits high. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* Read Control register. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig | phyBMCR_RESET );
}
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );
vTaskSetTimeOutState( &xTimer );
/* The reset should last less than a second. */
for( ;; )
{
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
if( ( ulConfig & phyBMCR_RESET ) == 0 )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET %d ready\n", (int)xPhyIndex ) );
ulDoneMask |= ( 1ul << xPhyIndex );
}
}
if( ulDoneMask == ulPhyMask )
{
break;
}
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
break;
}
}
/* Clear the reset bits. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig & ~phyBMCR_RESET );
}
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
eventLogAdd( "PHY reset %d ports", (int)pxPhyObject->xPortCount );
return ulDoneMask;
}
/*-----------------------------------------------------------*/
BaseType_t xPhyConfigure( EthernetPhy_t *pxPhyObject, const PhyProperties_t *pxPhyProperties )
{
uint32_t ulConfig, ulAdvertise;
BaseType_t xPhyIndex;
if( pxPhyObject->xPortCount < 1 )
{
FreeRTOS_printf( ( "xPhyResetAll: No PHY's detected.\n" ) );
return -1;
}
/* The expected ID for the 'LAN8742A' is 0x0007c130. */
/* The expected ID for the 'LAN8720' is 0x0007c0f0. */
/* The expected ID for the 'DP83848I' is 0x20005C90. */
/* Set advertise register. */
if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) && ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
{
ulAdvertise = phyADVERTISE_CSMA | phyADVERTISE_ALL;
/* Reset auto-negotiation capability. */
}
else
{
ulAdvertise = phyADVERTISE_CSMA;
if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO )
{
if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
{
ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_100FULL;
}
else
{
ulAdvertise |= phyADVERTISE_10HALF | phyADVERTISE_100HALF;
}
}
else if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO )
{
if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_10 )
{
ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_10HALF;
}
else
{
ulAdvertise |= phyADVERTISE_100FULL | phyADVERTISE_100HALF;
}
}
else if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
{
if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
{
ulAdvertise |= phyADVERTISE_100FULL;
}
else
{
ulAdvertise |= phyADVERTISE_100HALF;
}
}
else
{
if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
{
ulAdvertise |= phyADVERTISE_10FULL;
}
else
{
ulAdvertise |= phyADVERTISE_10HALF;
}
}
}
/* Send a reset commando to a set of PHY-ports. */
xPhyReset( pxPhyObject, xPhyGetMask( pxPhyObject ) );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
/* Write advertise register. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, ulAdvertise );
/*
AN_EN AN1 AN0 Forced Mode
0 0 0 10BASE-T, Half-Duplex
0 0 1 10BASE-T, Full-Duplex
0 1 0 100BASE-TX, Half-Duplex
0 1 1 100BASE-TX, Full-Duplex
AN_EN AN1 AN0 Advertised Mode
1 0 0 10BASE-T, Half/Full-Duplex
1 0 1 100BASE-TX, Half/Full-Duplex
1 1 0 10BASE-T Half-Duplex
100BASE-TX, Half-Duplex
1 1 1 10BASE-T, Half/Full-Duplex
100BASE-TX, Half/Full-Duplex
*/
/* Read Control register. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
ulConfig &= ~( phyBMCR_SPEED_100 | phyBMCR_FULL_DUPLEX );
ulConfig |= phyBMCR_AN_ENABLE;
if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
{
ulConfig |= phyBMCR_SPEED_100;
}
else if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_10 )
{
ulConfig &= ~phyBMCR_SPEED_100;
}
if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
{
ulConfig |= phyBMCR_FULL_DUPLEX;
}
else if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_HALF )
{
ulConfig &= ~phyBMCR_FULL_DUPLEX;
}
if( xHas_19_PHYCR( ulPhyID ) )
{
uint32_t ulPhyControl;
/* Read PHY Control register. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_19_PHYCR, &ulPhyControl );
/* Clear bits which might get set: */
ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );
if( pxPhyProperties->ucMDI_X == PHY_MDIX_AUTO )
{
ulPhyControl |= PHYCR_MDIX_EN;
}
else if( pxPhyProperties->ucMDI_X == PHY_MDIX_CROSSED )
{
/* Force direct link = Use crossed RJ45 cable. */
ulPhyControl &= ~PHYCR_MDIX_FORCE;
}
else
{
/* Force crossed link = Use direct RJ45 cable. */
ulPhyControl |= PHYCR_MDIX_FORCE;
}
/* update PHY Control Register. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_19_PHYCR, ulPhyControl );
}
FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
eventLogAdd( "adv: %04lX config %04lX", ulAdvertise, ulConfig );
}
/* Keep these values for later use. */
pxPhyObject->ulBCRValue = ulConfig;
pxPhyObject->ulACRValue = ulAdvertise;
return 0;
}
/*-----------------------------------------------------------*/
BaseType_t xPhyFixedValue( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
BaseType_t xPhyIndex;
uint32_t ulValue, ulBitMask = ( uint32_t )1u;
ulValue = ( uint32_t )0u;
if( pxPhyObject->xPhyPreferences.ucDuplex == PHY_DUPLEX_FULL )
{
ulValue |= phyBMCR_FULL_DUPLEX;
}
if( pxPhyObject->xPhyPreferences.ucSpeed == PHY_SPEED_100 )
{
ulValue |= phyBMCR_SPEED_100;
}
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( ulPhyMask & ulBitMask ) != 0lu )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* Enable Auto-Negotiation. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulValue );
}
}
return 0;
}
/*-----------------------------------------------------------*/
BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
uint32_t xPhyIndex, ulDoneMask, ulBitMask;
uint32_t ulPHYLinkStatus, ulRegValue;
TickType_t xRemainingTime;
TimeOut_t xTimer;
if( ulPhyMask == ( uint32_t )0u )
{
return 0;
}
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
if( ( ulPhyMask & ( 1lu << xPhyIndex ) ) != 0lu )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* Enable Auto-Negotiation. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, pxPhyObject->ulACRValue);
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
}
}
eventLogAdd( "AN start" );
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
vTaskSetTimeOutState( &xTimer );
ulDoneMask = 0;
/* Wait until the auto-negotiation will be completed */
for( ;; )
{
ulBitMask = ( uint32_t )1u;
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( ulPhyMask & ulBitMask ) != 0lu )
{
if( ( ulDoneMask & ulBitMask ) == 0lu )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue );
if( ( ulRegValue & phyBMSR_AN_COMPLETE ) != 0 )
{
ulDoneMask |= ulBitMask;
}
}
}
}
if( ulPhyMask == ulDoneMask )
{
break;
}
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
eventLogAdd( "ANtimed out");
break;
}
}
eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
if( ulDoneMask != ( uint32_t)0u )
{
ulBitMask = ( uint32_t )1u;
pxPhyObject->ulLinkStatusMask &= ~( ulDoneMask );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
if( ( ulDoneMask & ulBitMask ) == ( uint32_t )0u )
{
continue;
}
/* Clear the 'phyBMCR_AN_RESTART' bit. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue );
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue);
if( ( ulRegValue & phyBMSR_LINK_STATUS ) != 0 )
{
ulPHYLinkStatus |= phyBMSR_LINK_STATUS;
pxPhyObject->ulLinkStatusMask |= ulBitMask;
}
else
{
ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
}
if( xHas_1F_PHYSPCS( ulPhyID ) )
{
/* 31 RW PHY Special Control Status */
uint32_t ulControlStatus;
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_1F_PHYSPCS, &ulControlStatus);
ulRegValue = 0;
if( ( ulControlStatus & phyPHYSPCS_FULL_DUPLEX ) != 0 )
{
ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
}
if( ( ulControlStatus & phyPHYSPCS_SPEED_MASK ) == phyPHYSPCS_SPEED_10 )
{
ulRegValue |= phyPHYSTS_SPEED_STATUS;
}
}
else
{
/* Read the result of the auto-negotiation. */
pxPhyObject->fnPhyRead( xPhyAddress, PHYREG_10_PHYSTS, &ulRegValue);
}
FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",
ulRegValue,
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );
eventLogAdd( "%s duplex %u mbit %s st",
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" );
{
uint32_t regs[4];
int i,j;
int address = 0x10;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
pxPhyObject->fnPhyRead( xPhyAddress, address, regs + j );
address++;
}
eventLogAdd("%04lX %04lX %04lX %04lX",
regs[0], regs[1], regs[2], regs[3]);
}
}
if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )
{
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
}
else
{
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_HALF;
}
if( ( ulRegValue & phyPHYSTS_SPEED_STATUS ) != 0 )
{
pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_10;
}
else
{
pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_100;
}
}
} /* if( ulDoneMask != ( uint32_t)0u ) */
return 0;
}
/*-----------------------------------------------------------*/
BaseType_t xPhyCheckLinkStatus( EthernetPhy_t *pxPhyObject, BaseType_t xHadReception )
{
uint32_t ulStatus, ulBitMask = 1u;
BaseType_t xPhyIndex;
BaseType_t xNeedCheck = pdFALSE;
if( xHadReception > 0 )
{
/* A packet was received. No need to check for the PHY status now,
but set a timer to check it later on. */
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
}
else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
{
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
if( pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulStatus ) == 0 )
{
if( !!( pxPhyObject->ulLinkStatusMask & ulBitMask ) != !!( ulStatus & phyBMSR_LINK_STATUS ) )
{
if( ( ulStatus & phyBMSR_LINK_STATUS ) != 0 )
{
pxPhyObject->ulLinkStatusMask |= ulBitMask;
}
else
{
pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
}
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
eventLogAdd( "PHY LS now %02lX", pxPhyObject->ulLinkStatusMask );
xNeedCheck = pdTRUE;
}
}
}
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
if( ( pxPhyObject->ulLinkStatusMask & phyBMSR_LINK_STATUS ) != 0 )
{
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
}
else
{
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_LOW_CHECK_TIME_MS );
}
}
return xNeedCheck;
}
/*-----------------------------------------------------------*/

View File

@ -1,267 +0,0 @@
/*
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 "queue.h"
#include "semphr.h"
/* Hardware abstraction. */
#include "FreeRTOS_IO.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_Sockets.h"
#include "NetworkBufferManagement.h"
/* Driver includes. */
#include "lpc17xx_emac.h"
#include "lpc17xx_pinsel.h"
/* Demo includes. */
#include "NetworkInterface.h"
#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
#else
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
#endif
/* When a packet is ready to be sent, if it cannot be sent immediately then the
task performing the transmit will block for niTX_BUFFER_FREE_WAIT
milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
up. */
#define niTX_BUFFER_FREE_WAIT ( pdMS_TO_TICKS( 2UL ) )
#define niMAX_TX_ATTEMPTS ( 5 )
/* The length of the queue used to send interrupt status words from the
interrupt handler to the deferred handler task. */
#define niINTERRUPT_QUEUE_LENGTH ( 10 )
/*-----------------------------------------------------------*/
/*
* A deferred interrupt handler task that processes
*/
static void prvEMACHandlerTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* The queue used to communicate Ethernet events with the IP task. */
extern QueueHandle_t xNetworkEventQueue;
/* The semaphore used to wake the deferred interrupt handler task when an Rx
interrupt is received. */
static SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
{
EMAC_CFG_Type Emac_Config;
PINSEL_CFG_Type xPinConfig;
BaseType_t xStatus, xReturn;
extern uint8_t ucMACAddress[ 6 ];
/* Enable Ethernet Pins */
boardCONFIGURE_ENET_PINS( xPinConfig );
Emac_Config.Mode = EMAC_MODE_AUTO;
Emac_Config.pbEMAC_Addr = ucMACAddress;
xStatus = EMAC_Init( &Emac_Config );
LPC_EMAC->IntEnable &= ~( EMAC_INT_TX_DONE );
if( xStatus != ERROR )
{
vSemaphoreCreateBinary( xEMACRxEventSemaphore );
configASSERT( xEMACRxEventSemaphore );
/* The handler task is created at the highest possible priority to
ensure the interrupt handler can return directly to it. */
xTaskCreate( prvEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* Enable the interrupt and set its priority to the minimum
interrupt priority. */
NVIC_SetPriority( ENET_IRQn, configMAC_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( ENET_IRQn );
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
configASSERT( xStatus != ERROR );
return xReturn;
}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xReturn = pdFAIL;
int32_t x;
extern void EMAC_StartTransmitNextBuffer( uint32_t ulLength );
extern void EMAC_SetNextPacketToSend( uint8_t * pucBuffer );
/* Attempt to obtain access to a Tx buffer. */
for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )
{
if( EMAC_CheckTransmitIndex() == TRUE )
{
/* Will the data fit in the Tx buffer? */
if( pxNetworkBuffer->xDataLength < EMAC_ETH_MAX_FLEN ) /*_RB_ The size needs to come from FreeRTOSIPConfig.h. */
{
/* Assign the buffer to the Tx descriptor that is now known to
be free. */
EMAC_SetNextPacketToSend( pxNetworkBuffer->pucBuffer );
/* The EMAC now owns the buffer. */
pxNetworkBuffer->pucBuffer = NULL;
/* Initiate the Tx. */
EMAC_StartTransmitNextBuffer( pxNetworkBuffer->xDataLength );
iptraceNETWORK_INTERFACE_TRANSMIT();
/* The Tx has been initiated. */
xReturn = pdPASS;
}
break;
}
else
{
vTaskDelay( niTX_BUFFER_FREE_WAIT );
}
}
/* Finished with the network buffer. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
return xReturn;
}
/*-----------------------------------------------------------*/
void ENET_IRQHandler( void )
{
uint32_t ulInterruptCause;
while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 )
{
/* Clear the interrupt. */
LPC_EMAC->IntClear = ulInterruptCause;
/* Clear fatal error conditions. NOTE: The driver does not clear all
errors, only those actually experienced. For future reference, range
errors are not actually errors so can be ignored. */
if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U )
{
LPC_EMAC->Command |= EMAC_CR_TX_RES;
}
/* Unblock the deferred interrupt handler task if the event was an
Rx. */
if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL )
{
xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );
}
}
/* ulInterruptCause is used for convenience here. A context switch is
wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a
compiler warning. */
portEND_SWITCHING_ISR( ulInterruptCause );
}
/*-----------------------------------------------------------*/
static void prvEMACHandlerTask( void *pvParameters )
{
size_t xDataLength;
const uint16_t usCRCLength = 4;
NetworkBufferDescriptor_t *pxNetworkBuffer;
IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
/* This is not included in the header file for some reason. */
extern uint8_t *EMAC_NextPacketToRead( void );
( void ) pvParameters;
configASSERT( xEMACRxEventSemaphore );
for( ;; )
{
/* Wait for the EMAC interrupt to indicate that another packet has been
received. The while() loop is only needed if INCLUDE_vTaskSuspend is
set to 0 in FreeRTOSConfig.h. */
while( xSemaphoreTake( xEMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );
/* At least one packet has been received. */
while( EMAC_CheckReceiveIndex() != FALSE )
{
/* Obtain the length, minus the CRC. The CRC is four bytes
but the length is already minus 1. */
xDataLength = ( size_t ) EMAC_GetReceiveDataSize() - ( usCRCLength - 1U );
if( xDataLength > 0U )
{
/* Obtain a network buffer to pass this data into the
stack. No storage is required as the network buffer
will point directly to the buffer that already holds
the received data. */
pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( 0, ( TickType_t ) 0 );
if( pxNetworkBuffer != NULL )
{
pxNetworkBuffer->pucBuffer = EMAC_NextPacketToRead();
pxNetworkBuffer->xDataLength = xDataLength;
xRxEvent.pvData = ( void * ) pxNetworkBuffer;
/* Data was received and stored. Send a message to the IP
task to let it know. */
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
{
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
iptraceETHERNET_RX_EVENT_LOST();
}
}
else
{
iptraceETHERNET_RX_EVENT_LOST();
}
iptraceNETWORK_INTERFACE_RECEIVE();
}
/* Release the frame. */
EMAC_UpdateRxConsumeIndex();
}
}
}
/*-----------------------------------------------------------*/

View File

@ -1,3 +0,0 @@
NetworkInterface.c:
Requires NXP's LPCOpen library and was developed on an LPC1830 and LPC1835 Xplorer
boards from NGX.

View File

@ -1,10 +0,0 @@
Network drivers are provided as examples only, and do not form part of the
FreeRTOS+TCP stack itself. They:
+ May be based on driver code provided by the chip vendors,
+ May not have been tested in all possible configurations,
+ Will not necessarily be optimised.
+ May have a dependency on a particular PHY part number.
+ May not necessarily comply with any particular coding standard.
+ May have dependencies on chip company libraries.
+ May include other hardware board dependencies.

View File

@ -1,118 +0,0 @@
/*
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 "queue.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_UDP_IP.h"
#include "FreeRTOS_Sockets.h"
#include "NetworkBufferManagement.h"
/* Hardware includes. */
#include "hwEthernet.h"
/* Demo includes. */
#include "NetworkInterface.h"
#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
#else
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
#endif
/* When a packet is ready to be sent, if it cannot be sent immediately then the
task performing the transmit will block for niTX_BUFFER_FREE_WAIT
milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
up. */
#define niTX_BUFFER_FREE_WAIT ( ( TickType_t ) 2UL / portTICK_PERIOD_MS )
#define niMAX_TX_ATTEMPTS ( 5 )
/* The length of the queue used to send interrupt status words from the
interrupt handler to the deferred handler task. */
#define niINTERRUPT_QUEUE_LENGTH ( 10 )
/*-----------------------------------------------------------*/
/*
* A deferred interrupt handler task that processes
*/
extern void vEMACHandlerTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* The queue used to communicate Ethernet events with the IP task. */
extern QueueHandle_t xNetworkEventQueue;
/* The semaphore used to wake the deferred interrupt handler task when an Rx
interrupt is received. */
SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
{
BaseType_t xStatus, xReturn;
extern uint8_t ucMACAddress[ 6 ];
/* Initialise the MAC. */
vInitEmac();
while( lEMACWaitForLink() != pdPASS )
{
vTaskDelay( 20 );
}
vSemaphoreCreateBinary( xEMACRxEventSemaphore );
configASSERT( xEMACRxEventSemaphore );
/* The handler task is created at the highest possible priority to
ensure the interrupt handler can return directly to it. */
xTaskCreate( vEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
xReturn = pdPASS;
return xReturn;
}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
extern void vEMACCopyWrite( uint8_t * pucBuffer, uint16_t usLength );
vEMACCopyWrite( pxNetworkBuffer->pucBuffer, pxNetworkBuffer->xDataLength );
/* Finished with the network buffer. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
return pdTRUE;
}
/*-----------------------------------------------------------*/

View File

@ -1,173 +0,0 @@
#define xBUFFER_CACHE_SIZE 10
#define xMAX_FAULT_INJECTION_RATE 15
#define xMIN_FAULT_INJECTION_RATE 3
#define xNUM_FAULT_TYPES 1
static NetworkBufferDescriptor_t *xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
#define xFAULT_LOG_SIZE 2048
uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
uint32_t ulFaultLogIndex = 0;
static BaseType_t prvCachePacket( NetworkBufferDescriptor_t *pxNetworkBufferIn )
{
BaseType_t x, xReturn = pdFALSE;
for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
{
if( xNetworkBufferCache[ x ] == NULL )
{
xNetworkBufferCache[ x ] = pxNetworkBufferIn;
xReturn = pdTRUE;
break;
}
}
return xReturn;
}
/*-----------------------------------------------------------*/
static NetworkBufferDescriptor_t *prvGetCachedPacket( void )
{
BaseType_t x;
NetworkBufferDescriptor_t *pxReturn = NULL;
for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
{
if( xNetworkBufferCache[ x ] != NULL )
{
pxReturn = xNetworkBufferCache[ x ];
xNetworkBufferCache[ x ] = NULL;
break;
}
}
return pxReturn;
}
/*-----------------------------------------------------------*/
static NetworkBufferDescriptor_t *prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket, const uint8_t *pucPacketData )
{
NetworkBufferDescriptor_t *pxReturn;
/* Obtain a new descriptor. */
pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
if( pxReturn != NULL )
{
/* Copy in the packet data. */
pxReturn->xDataLength = pxOriginalPacket->xDataLength;
memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
}
return pxReturn;
}
/*-----------------------------------------------------------*/
static NetworkBufferDescriptor_t *prvRxFaultInjection( NetworkBufferDescriptor_t *pxNetworkBufferIn, const uint8_t *pucPacketData )
{
static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
NetworkBufferDescriptor_t *pxReturn = pxNetworkBufferIn;
IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
uint32_t ulFault;
return pxNetworkBufferIn;
ulCallCount++;
if( ulCallCount > ulNextFaultCallCount )
{
ulNextFaultCallCount = ipconfigRAND32() % xMAX_FAULT_INJECTION_RATE;
if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
{
ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
}
ulCallCount = 0;
ulFault = ipconfigRAND32() % xNUM_FAULT_TYPES;
if( ulFaultLogIndex < xFAULT_LOG_SIZE )
{
ulInjectedFault[ ulFaultLogIndex ] = ulFault;
ulFaultLogIndex++;
}
switch( ulFault )
{
case 0:
/* Just drop the packet. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
pxReturn = NULL;
break;
case 1:
/* Store the packet in the cache for later. */
if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
{
/* The packet may get sent later, it is not being sent
now. */
pxReturn = NULL;
}
break;
case 2:
/* Send a cached packet. */
pxReturn = prvGetCachedPacket();
if( pxReturn != NULL )
{
/* A cached packet was obtained so drop the original
packet. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
}
else
{
/* Could not obtain a packet from the cache so just return
the packet that was passed in. */
pxReturn = pxNetworkBufferIn;
}
break;
case 4:
/* Send a duplicate of the packet right away. */
pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
/* Send the original packet to the stack. */
xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
{
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
}
break;
case 5:
/* Send both a cached packet and the current packet. */
xRxEvent.pvData = ( void * ) prvGetCachedPacket();
if( xRxEvent.pvData != NULL )
{
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
{
vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
}
}
break;
case 6:
case 7:
case 8:
/* Store the packet in the cache for later. */
if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
{
/* The packet may get sent later, it is not being sent
now. */
pxReturn = NULL;
}
break;
}
}
return pxReturn;
}
/*-----------------------------------------------------------*/

View File

@ -1,634 +0,0 @@
/*
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
*/
/* WinPCap includes. */
#define HAVE_REMOTE
#include "pcap.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
/* Thread-safe circular buffers are being used to pass data to and from the PCAP
access functions. */
#include "Win32-Extensions.h"
#include "FreeRTOS_Stream_Buffer.h"
/* Sizes of the thread safe circular buffers used to pass data to and from the
WinPCAP Windows threads. */
#define xSEND_BUFFER_SIZE 32768
#define xRECV_BUFFER_SIZE 32768
/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
driver will filter incoming packets and only pass the stack those packets it
considers need processing. */
#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
#else
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
#endif
/* Used to insert test code only. */
#define niDISRUPT_PACKETS 0
/*-----------------------------------------------------------*/
/*
* Windows threads that are outside of the control of the FreeRTOS simulator are
* used to interface with the WinPCAP libraries.
*/
DWORD WINAPI prvWinPcapRecvThread( void *pvParam );
DWORD WINAPI prvWinPcapSendThread( void *pvParam );
/*
* Print out a numbered list of network interfaces that are available on the
* host computer.
*/
static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
/*
* Open the network interface. The number of the interface to be opened is set
* by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
*/
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
static int prvOpenInterface( const char *pucName );
/*
* Configure the capture filter to allow blocking reads, and to filter out
* packets that are not of interest to this demo.
*/
static void prvConfigureCaptureBehaviour( void );
/*
* A function that simulates Ethernet interrupts by periodically polling the
* WinPCap interface for new data.
*/
static void prvInterruptSimulatorTask( void *pvParameters );
/*
* Create the buffers that are used to pass data between the FreeRTOS simulator
* and the Win32 threads that manage WinPCAP.
*/
static void prvCreateThreadSafeBuffers( void );
/*
* Utility function used to format print messages only.
*/
static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage );
/*-----------------------------------------------------------*/
/* Required by the WinPCap library. */
static char cErrorBuffer[ PCAP_ERRBUF_SIZE ];
/* An event used to wake up the Win32 thread that sends data through the WinPCAP
library. */
static void *pvSendEvent = NULL;
/* _HT_ made the PCAP interface number configurable through the program's
parameters in order to test in different machines. */
static BaseType_t xConfigNextworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
/* Handles to the Windows threads that handle the PCAP IO. */
static HANDLE vWinPcapRecvThreadHandle = NULL;
static HANDLE vWinPcapSendThreadHandle = NULL;;
/* The interface being used by WinPCap. */
static pcap_t *pxOpenedInterfaceHandle = NULL;
/* Circular buffers used by the PCAP Win32 threads. */
static StreamBuffer_t *xSendBuffer = NULL;
static StreamBuffer_t *xRecvBuffer = NULL;
/* The MAC address initially set to the constants defined in FreeRTOSConfig.h. */
extern uint8_t ucMACAddress[ 6 ];
/* Logs the number of WinPCAP send failures, for viewing in the debugger only. */
static volatile uint32_t ulWinPCAPSendFailures = 0;
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
{
BaseType_t xReturn = pdFALSE;
pcap_if_t *pxAllNetworkInterfaces;
/* Query the computer the simulation is being executed on to find the
network interfaces it has installed. */
pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
/* Open the network interface. The number of the interface to be opened is
set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
Calling this function will set the pxOpenedInterfaceHandle variable. If,
after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
the interface could not be opened. */
if( pxAllNetworkInterfaces != NULL )
{
prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
}
if( pxOpenedInterfaceHandle != NULL )
{
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static void prvCreateThreadSafeBuffers( void )
{
/* The buffer used to pass data to be transmitted from a FreeRTOS task to
the Win32 thread that sends via the WinPCAP library. */
if( xSendBuffer == NULL)
{
xSendBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) + xSEND_BUFFER_SIZE + 1 );
configASSERT( xSendBuffer );
memset( xSendBuffer, '\0', sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) );
xSendBuffer->LENGTH = xSEND_BUFFER_SIZE + 1;
}
/* The buffer used to pass received data from the Win32 thread that receives
via the WinPCAP library to the FreeRTOS task. */
if( xRecvBuffer == NULL)
{
xRecvBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) + xRECV_BUFFER_SIZE + 1 );
configASSERT( xRecvBuffer );
memset( xRecvBuffer, '\0', sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) );
xRecvBuffer->LENGTH = xRECV_BUFFER_SIZE + 1;
}
}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
{
size_t xSpace;
iptraceNETWORK_INTERFACE_TRANSMIT();
configASSERT( xIsCallingFromIPTask() == pdTRUE );
/* Both the length of the data being sent and the actual data being sent
are placed in the thread safe buffer used to pass data between the FreeRTOS
tasks and the Win32 thread that sends data via the WinPCAP library. Drop
the packet if there is insufficient space in the buffer to hold both. */
xSpace = uxStreamBufferGetSpace( xSendBuffer );
if( ( pxNetworkBuffer->xDataLength <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
( xSpace >= ( pxNetworkBuffer->xDataLength + sizeof( pxNetworkBuffer->xDataLength ) ) ) )
{
/* First write in the length of the data, then write in the data
itself. */
uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) &( pxNetworkBuffer->xDataLength ), sizeof( pxNetworkBuffer->xDataLength ) );
uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
}
else
{
FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: send buffers full to store %lu\n", pxNetworkBuffer->xDataLength ) );
}
/* Kick the Tx task in either case in case it doesn't know the buffer is
full. */
SetEvent( pvSendEvent );
/* The buffer has been sent so can be released. */
if( bReleaseAfterSend != pdFALSE )
{
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
}
return pdPASS;
}
/*-----------------------------------------------------------*/
static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
{
pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
int32_t lInterfaceNumber = 1;
char cBuffer[ 512 ];
static BaseType_t xInvalidInterfaceDetected = pdFALSE;
if( xInvalidInterfaceDetected == pdFALSE )
{
if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
{
printf( "Could not obtain a list of network interfaces\n%s\n", cErrorBuffer );
pxAllNetworkInterfaces = NULL;
}
else
{
printf( "\r\n\r\nThe following network interfaces are available:\r\n\r\n" );
}
if( pxAllNetworkInterfaces != NULL )
{
/* Print out the list of network interfaces. The first in the list
is interface '1', not interface '0'. */
for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
{
/* The descriptions of the devices can be full of spaces, clean them
a little. printf() can only be used here because the network is not
up yet - so no other network tasks will be running. */
printf( "Interface %d - %s\n", lInterfaceNumber, prvRemoveSpaces( cBuffer, sizeof( cBuffer ), xInterface->name ) );
printf( " (%s)\n", prvRemoveSpaces(cBuffer, sizeof( cBuffer ), xInterface->description ? xInterface->description : "No description" ) );
printf( "\n" );
lInterfaceNumber++;
}
}
if( lInterfaceNumber == 1 )
{
/* The interface number was never incremented, so the above for() loop
did not execute meaning no interfaces were found. */
printf( " \nNo network interfaces were found.\n" );
pxAllNetworkInterfaces = NULL;
}
printf( "\r\nThe interface that will be opened is set by " );
printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
if( ( xConfigNextworkInterfaceToUse < 0L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
{
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNextworkInterfaceToUse );
printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
printf( "then re-compile and re-start the application. Only Ethernet (as opposed to WiFi)\r\n" );
printf( "interfaces are supported.\r\n\r\nHALTING\r\n\r\n\r\n" );
xInvalidInterfaceDetected = pdTRUE;
if( pxAllNetworkInterfaces != NULL )
{
/* Free the device list, as no devices are going to be opened. */
pcap_freealldevs( pxAllNetworkInterfaces );
pxAllNetworkInterfaces = NULL;
}
}
else
{
printf( "Attempting to open interface number %d.\n", xConfigNextworkInterfaceToUse );
}
}
return pxAllNetworkInterfaces;
}
/*-----------------------------------------------------------*/
static int prvOpenInterface( const char *pucName )
{
static char pucInterfaceName[ 256 ];
if( pucName != NULL )
{
strncpy( pucInterfaceName, pucName, sizeof( pucInterfaceName ) );
}
pxOpenedInterfaceHandle = pcap_open( pucInterfaceName, /* The name of the selected interface. */
ipTOTAL_ETHERNET_FRAME_SIZE, /* The size of the packet to capture. */
PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and
IP address is going to be "simulated", and
not be the real MAC and IP address. This allows
traffic to the simulated IP address to be routed
to uIP, and traffic to the real IP address to be
routed to the Windows TCP/IP stack. */
100,
NULL, /* No authentication is required as this is
not a remote capture session. */
cErrorBuffer
);
if ( pxOpenedInterfaceHandle == NULL )
{
printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
return 1;
}
else
{
/* Configure the capture filter to allow blocking reads, and to filter
out packets that are not of interest to this demo. */
prvConfigureCaptureBehaviour();
}
return 0;
}
/*-----------------------------------------------------------*/
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
{
pcap_if_t *xInterface;
int32_t x;
/* Walk the list of devices until the selected device is located. */
xInterface = pxAllNetworkInterfaces;
if (0 == xConfigNextworkInterfaceToUse) {
while (NULL != xInterface) {
xInterface = xInterface->next;
if (0 == prvOpenInterface(xInterface->name)) {
break;
}
}
}
else {
for (x = 1L; x < xConfigNextworkInterfaceToUse; x++)
{
xInterface = xInterface->next;
}
/* Open the selected interface. */
(void) prvOpenInterface(xInterface->name);
}
/* The device list is no longer required. */
pcap_freealldevs( pxAllNetworkInterfaces );
}
/*-----------------------------------------------------------*/
static void prvConfigureCaptureBehaviour( void )
{
struct bpf_program xFilterCode;
uint32_t ulNetMask;
/* Set up a filter so only the packets of interest are passed to the IP
stack. cErrorBuffer is used for convenience to create the string. Don't
confuse this with an error message. */
sprintf( cErrorBuffer, "broadcast or multicast or ether host %x:%x:%x:%x:%x:%x",
ucMACAddress[0], ucMACAddress[1], ucMACAddress[2], ucMACAddress[3], ucMACAddress[4], ucMACAddress[5] );
ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
{
printf( "\nThe packet filter string is invalid\n" );
}
else
{
if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
{
printf( "\nAn error occurred setting the packet filter.\n" );
}
}
/* Create the buffers used to pass packets between the FreeRTOS simulator
and the Win32 threads that are handling WinPCAP. */
prvCreateThreadSafeBuffers();
if( pvSendEvent == NULL )
{
/* Create event used to signal the Win32 WinPCAP Tx thread. */
pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
/* Create the Win32 thread that handles WinPCAP Rx. */
vWinPcapRecvThreadHandle = CreateThread(
NULL, /* Pointer to thread security attributes. */
0, /* Initial thread stack size, in bytes. */
prvWinPcapRecvThread, /* Pointer to thread function. */
NULL, /* Argument for new thread. */
0, /* Creation flags. */
NULL );
/* Use the cores that are not used by the FreeRTOS tasks. */
SetThreadAffinityMask( vWinPcapRecvThreadHandle, ~0x01u );
/* Create the Win32 thread that handlers WinPCAP Tx. */
vWinPcapSendThreadHandle = CreateThread(
NULL, /* Pointer to thread security attributes. */
0, /* initial thread stack size, in bytes. */
prvWinPcapSendThread, /* Pointer to thread function. */
NULL, /* Argument for new thread. */
0, /* Creation flags. */
NULL );
/* Use the cores that are not used by the FreeRTOS tasks. */
SetThreadAffinityMask( vWinPcapSendThreadHandle, ~0x01u );
/* Create a task that simulates an interrupt in a real system. This will
block waiting for packets, then send a message to the IP task when data
is available. */
xTaskCreate( prvInterruptSimulatorTask, "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
}
}
/*-----------------------------------------------------------*/
/* WinPCAP function. */
void pcap_callback( u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data )
{
(void)user;
/* THIS IS CALLED FROM A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS
OR TO PRINT OUT MESSAGES HERE. */
/* Pass data to the FreeRTOS simulator on a thread safe circular buffer. */
if( ( pkt_header->caplen <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
( uxStreamBufferGetSpace( xRecvBuffer ) >= ( ( ( size_t ) pkt_header->caplen ) + sizeof( *pkt_header ) ) ) )
{
uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_header, sizeof( *pkt_header ) );
uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_data, ( size_t ) pkt_header->caplen );
}
}
/*-----------------------------------------------------------*/
DWORD WINAPI prvWinPcapRecvThread ( void *pvParam )
{
( void ) pvParam;
/* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
OUT MESSAGES HERE. */
for( ;; )
{
pcap_dispatch( pxOpenedInterfaceHandle, 1, pcap_callback, ( u_char * ) "mydata" );
}
}
/*-----------------------------------------------------------*/
DWORD WINAPI prvWinPcapSendThread( void *pvParam )
{
size_t xLength;
uint8_t ucBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
static char cErrorMessage[ 1024 ];
const DWORD xMaxMSToWait = 1000;
/* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
OUT MESSAGES HERE. */
/* Remove compiler warnings about unused parameters. */
( void ) pvParam;
for( ;; )
{
/* Wait until notified of something to send. */
WaitForSingleObject( pvSendEvent, xMaxMSToWait );
/* Is there more than the length value stored in the circular buffer
used to pass data from the FreeRTOS simulator into this Win32 thread? */
while( uxStreamBufferGetSize( xSendBuffer ) > sizeof( xLength ) )
{
uxStreamBufferGet( xSendBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
uxStreamBufferGet( xSendBuffer, 0, ( uint8_t* ) ucBuffer, xLength, pdFALSE );
if( pcap_sendpacket( pxOpenedInterfaceHandle, ucBuffer, xLength ) != 0 )
{
ulWinPCAPSendFailures++;
}
}
}
}
/*-----------------------------------------------------------*/
static void prvInterruptSimulatorTask( void *pvParameters )
{
struct pcap_pkthdr xHeader;
static struct pcap_pkthdr *pxHeader;
const uint8_t *pucPacketData;
uint8_t ucRecvBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
NetworkBufferDescriptor_t *pxNetworkBuffer;
IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
eFrameProcessingResult_t eResult;
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
for( ;; )
{
/* Does the circular buffer used to pass data from the Win32 thread that
handles WinPCAP Rx into the FreeRTOS simulator contain another packet? */
if( uxStreamBufferGetSize( xRecvBuffer ) > sizeof( xHeader ) )
{
/* Get the next packet. */
uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)&xHeader, sizeof( xHeader ), pdFALSE );
uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)ucRecvBuffer, ( size_t ) xHeader.len, pdFALSE );
pucPacketData = ucRecvBuffer;
pxHeader = &xHeader;
iptraceNETWORK_INTERFACE_RECEIVE();
/* Check for minimal size. */
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
{
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
}
else
{
eResult = eReleaseBuffer;
}
if( eResult == eProcessBuffer )
{
/* Will the data fit into the frame buffer? */
if( pxHeader->len <= ipTOTAL_ETHERNET_FRAME_SIZE )
{
/* Obtain a buffer into which the data can be placed. This
is only an interrupt simulator, not a real interrupt, so it
is ok to call the task level function here, but note that
some buffer implementations cannot be called from a real
interrupt. */
pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( pxHeader->len, 0 );
if( pxNetworkBuffer != NULL )
{
memcpy( pxNetworkBuffer->pucEthernetBuffer, pucPacketData, pxHeader->len );
pxNetworkBuffer->xDataLength = ( size_t ) pxHeader->len;
#if( niDISRUPT_PACKETS == 1 )
{
pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData );
}
#endif /* niDISRUPT_PACKETS */
if( pxNetworkBuffer != NULL )
{
xRxEvent.pvData = ( void * ) pxNetworkBuffer;
/* Data was received and stored. Send a message to
the IP task to let it know. */
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
{
/* The buffer could not be sent to the stack so
must be released again. This is only an
interrupt simulator, not a real interrupt, so it
is ok to use the task level function here, but
note no all buffer implementations will allow
this function to be executed from a real
interrupt. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
iptraceETHERNET_RX_EVENT_LOST();
}
}
else
{
/* The packet was already released or stored inside
vRxFaultInjection(). Don't release it here. */
}
}
else
{
iptraceETHERNET_RX_EVENT_LOST();
}
}
else
{
/* Log that a packet was dropped because it would have
overflowed the buffer, but there may be more buffers to
process. */
}
}
}
else
{
/* There is no real way of simulating an interrupt. Make sure
other tasks can run. */
vTaskDelay( configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY );
}
}
}
/*-----------------------------------------------------------*/
static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage )
{
char *pcTarget = pcBuffer;
/* Utility function used to formap messages being printed only. */
while( ( *pcMessage != 0 ) && ( pcTarget < ( pcBuffer + aBuflen - 1 ) ) )
{
*( pcTarget++ ) = *pcMessage;
if( isspace( *pcMessage ) != pdFALSE )
{
while( isspace( *pcMessage ) != pdFALSE )
{
pcMessage++;
}
}
else
{
pcMessage++;
}
}
*pcTarget = '\0';
return pcBuffer;
}

View File

@ -1,398 +0,0 @@
/*
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>
#include <stdlib.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 "NetworkBufferManagement.h"
#include "NetworkInterface.h"
/* Xilinx library files. */
#include <xemacps.h>
#include "Zynq/x_topology.h"
#include "Zynq/x_emacpsif.h"
#include "Zynq/x_emacpsif_hw.h"
/* Provided memory configured as uncached. */
#include "uncached_memory.h"
#ifndef BMSR_LINK_STATUS
#define BMSR_LINK_STATUS 0x0004UL
#endif
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
receiving packets. */
#define PHY_LS_HIGH_CHECK_TIME_MS 15000
#endif
#ifndef PHY_LS_LOW_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still low every second. */
#define PHY_LS_LOW_CHECK_TIME_MS 1000
#endif
/* The size of each buffer when BufferAllocation_1 is used:
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
#define niBUFFER_1_PACKET_SIZE 1536
/* Naming and numbering of PHY registers. */
#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
#ifndef iptraceEMAC_TASK_STARTING
#define iptraceEMAC_TASK_STARTING() do { } while( 0 )
#endif
/* Default the size of the stack used by the EMAC deferred handler task to twice
the size of the stack used by the idle task - but allow this to be overridden in
FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
#ifndef configEMAC_TASK_STACK_SIZE
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
#endif
/*-----------------------------------------------------------*/
/*
* Look for the link to be up every few milliseconds until either xMaxTime time
* has passed or a link is found.
*/
static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
/*
* A deferred interrupt handler for all MAC/DMA interrupt sources.
*/
static void prvEMACHandlerTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* EMAC data/descriptions. */
static xemacpsif_s xEMACpsif;
struct xtopology_t xXTopology =
{
.emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
.emac_type = xemac_type_emacps,
.intc_baseaddr = 0x0,
.intc_emac_intr = 0x0,
.scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
.scugic_emac_intr = 0x36,
};
XEmacPs_Config mac_config =
{
.DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
.BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
};
extern int phy_detected;
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
static uint32_t ulPHYLinkStatus = 0;
#if( ipconfigUSE_LLMNR == 1 )
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
#endif
/* ucMACAddress as it appears in main.c */
extern const uint8_t ucMACAddress[ 6 ];
/* Holds the handle of the task used as a deferred interrupt processor. The
handle is used so direct notifications can be sent to the task for all EMAC/DMA
related interrupts. */
TaskHandle_t xEMACTaskHandle = NULL;
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
{
uint32_t ulLinkSpeed, ulDMAReg;
BaseType_t xStatus, xLinkStatus;
XEmacPs *pxEMAC_PS;
const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
/* Guard against the init function being called more than once. */
if( xEMACTaskHandle == NULL )
{
pxEMAC_PS = &( xEMACpsif.emacps );
memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
if( xStatus != XST_SUCCESS )
{
FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
}
/* Initialize the mac and set the MAC address. */
XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
#if( ipconfigUSE_LLMNR == 1 )
{
/* Also add LLMNR multicast MAC address. */
XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
}
#endif /* ipconfigUSE_LLMNR == 1 */
XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
ulLinkSpeed = Phy_Setup( pxEMAC_PS );
XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
/* Setting the operating speed of the MAC needs a delay. */
vTaskDelay( pdMS_TO_TICKS( 25UL ) );
ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
/* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
packets from the receiver packet buffer memory when no AHB resource is available. */
XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
setup_isr( &xEMACpsif );
init_dma( &xEMACpsif );
start_emacps( &xEMACpsif );
prvGMACWaitLS( xWaitLinkDelay );
/* The deferred interrupt handler task is created at the highest
possible priority to ensure the interrupt handler can return directly
to it. The task's handle is stored in xEMACTaskHandle so interrupts can
notify the task when there is something to process. */
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
}
else
{
/* Initialisation was already performed, just wait for the link. */
prvGMACWaitLS( xWaitRelinkDelay );
}
/* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
DHCP process and all other communication will fail. */
xLinkStatus = xGetPhyLinkStatus();
return ( xLinkStatus != pdFALSE );
}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
{
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
iptraceNETWORK_INTERFACE_TRANSMIT();
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
}
else if( bReleaseAfterSend != pdFALSE )
{
/* No link. */
vReleaseNetworkBufferAndDescriptor( pxBuffer );
}
return pdTRUE;
}
/*-----------------------------------------------------------*/
static inline unsigned long ulReadMDIO( unsigned ulRegister )
{
uint16_t usValue;
XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
return usValue;
}
/*-----------------------------------------------------------*/
static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
{
TickType_t xStartTime, xEndTime;
const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
BaseType_t xReturn;
xStartTime = xTaskGetTickCount();
for( ;; )
{
xEndTime = xTaskGetTickCount();
if( xEndTime - xStartTime > xMaxTime )
{
xReturn = pdFALSE;
break;
}
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
xReturn = pdTRUE;
break;
}
vTaskDelay( xShortDelay );
}
return xReturn;
}
/*-----------------------------------------------------------*/
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
uint8_t *ucRAMBuffer = ucNetworkPackets;
uint32_t ul;
for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
{
pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
*( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
}
}
/*-----------------------------------------------------------*/
BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xReturn;
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxLastMinBufferCount = 0;
UBaseType_t uxCurrentCount;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
/* A possibility to set some additional task properties like calling
portTASK_USES_FLOATING_POINT() */
iptraceEMAC_TASK_STARTING();
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
for( ;; )
{
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
static UBaseType_t uxLastMinQueueSpace = 0;
uxCurrentCount = uxGetMinimumIPQueueSpace();
if( uxLastMinQueueSpace != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinQueueSpace = uxCurrentCount;
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
}
}
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
{
/* No events to process now, wait for the next. */
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
}
if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
{
xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
xResult = emacps_check_rx( &xEMACpsif );
}
if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
{
xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
emacps_check_tx( &xEMACpsif );
}
if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 0 )
{
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
emacps_check_errors( &xEMACpsif );
}
if( xResult > 0 )
{
/* A packet was received. No need to check for the PHY status now,
but set a timer to check it later on. */
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
xResult = 0;
}
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
{
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
{
ulPHYLinkStatus = xStatus;
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
}
vTaskSetTimeOutState( &xPhyTime );
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
}
else
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
}
}
}
}
/*-----------------------------------------------------------*/

Some files were not shown because too many files have changed in this diff Show More