mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-10 13:45:07 -05:00
Relocate logging sources under FreeRTOS-Plus/Source/Logging (#354)
As suggested, because logging_stack.h and logging_levels.h are used not only by demos but also by platform-specific transport code, it would make sense to move FreeRTOS-Plus/Demos/Common/Logging to FreeRTOS-Plus/Source/Logging. The same is done for demo_logging.c and demo_logging.h, which are duplicated by several demos. Win32.vcxproj project files are also updated to follow suite.
This commit is contained in:
parent
553d448865
commit
10842c9189
43 changed files with 841 additions and 2970 deletions
|
|
@ -116,7 +116,7 @@
|
|||
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;..\..\Source\Logging;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
|
@ -155,10 +155,10 @@
|
|||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c" />
|
||||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c" />
|
||||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
|
||||
<ClCompile Include="..\..\Source\Logging\logging.c" />
|
||||
<ClCompile Include="DemoTasks\SimpleTCPEchoServer.c" />
|
||||
<ClCompile Include="DemoTasks\TCPEchoClient_SingleTasks.c" />
|
||||
<ClCompile Include="DemoTasks\SimpleUDPClientAndServer.c" />
|
||||
<ClCompile Include="demo_logging.c" />
|
||||
<ClCompile Include="main.c">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Stream_Buffer.c">
|
||||
<Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="demo_logging.c" />
|
||||
<ClCompile Include="..\..\Source\Logging\logging.c" />
|
||||
<ClCompile Include="DemoTasks\SimpleTCPEchoServer.c">
|
||||
<Filter>DemoTasks</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1,526 +0,0 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.4.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and
|
||||
* disk file without making any Win32 system calls themselves.
|
||||
*
|
||||
* Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as
|
||||
* FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a
|
||||
* disk file are sent via a stream buffer to a Win32 thread which then performs
|
||||
* the actual output.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <io.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include <FreeRTOS.h>
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
|
||||
/* Demo includes. */
|
||||
#include "demo_logging.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The maximum size to which the log file may grow, before being renamed
|
||||
to .ful. */
|
||||
#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul )
|
||||
|
||||
/* Dimensions the arrays into which print messages are created. */
|
||||
#define dlMAX_PRINT_STRING_LENGTH 255
|
||||
|
||||
/* The size of the stream buffer used to pass messages from FreeRTOS tasks to
|
||||
the Win32 thread that is responsible for making any Win32 system calls that are
|
||||
necessary for the selected logging method. */
|
||||
#define dlLOGGING_STREAM_BUFFER_SIZE 32768
|
||||
|
||||
/* A block time of zero simply means don't block. */
|
||||
#define dlDONT_BLOCK 0
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Called from vLoggingInit() to start a new disk log file.
|
||||
*/
|
||||
static void prvFileLoggingInit( void );
|
||||
|
||||
/*
|
||||
* Attempt to write a message to the file.
|
||||
*/
|
||||
static void prvLogToFile( const char *pcMessage, size_t xLength );
|
||||
|
||||
/*
|
||||
* Simply close the logging file, if it is open.
|
||||
*/
|
||||
static void prvFileClose( void );
|
||||
|
||||
/*
|
||||
* Before the scheduler is started this function is called directly. After the
|
||||
* scheduler has started it is called from the Windows thread dedicated to
|
||||
* outputting log messages. Only the windows thread actually performs the
|
||||
* writing so as not to disrupt the simulation by making Windows system calls
|
||||
* from FreeRTOS tasks.
|
||||
*/
|
||||
static void prvLoggingFlushBuffer( void );
|
||||
|
||||
/*
|
||||
* The windows thread that performs the actual writing of messages that require
|
||||
* Win32 system calls. Only the windows thread can make system calls so as not
|
||||
* to disrupt the simulation by making Windows calls from FreeRTOS tasks.
|
||||
*/
|
||||
static DWORD WINAPI prvWin32LoggingThread( void *pvParam );
|
||||
|
||||
/*
|
||||
* Creates the socket to which UDP messages are sent. This function is not
|
||||
* called directly to prevent the print socket being created from within the IP
|
||||
* task - which could result in a deadlock. Instead the function call is
|
||||
* deferred to run in the RTOS daemon task - hence it prototype.
|
||||
*/
|
||||
static void prvCreatePrintSocket( void *pvParameter1, uint32_t ulParameter2 );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Windows event used to wake the Win32 thread which performs any logging that
|
||||
needs Win32 system calls. */
|
||||
static void *pvLoggingThreadEvent = NULL;
|
||||
|
||||
/* Stores the selected logging targets passed in as parameters to the
|
||||
vLoggingInit() function. */
|
||||
BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE;
|
||||
|
||||
/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32
|
||||
thread that is responsible for making Win32 calls (when stdout or a disk log is
|
||||
used). */
|
||||
static StreamBuffer_t *xLogStreamBuffer = NULL;
|
||||
|
||||
/* Handle to the file used for logging. This is left open while there are
|
||||
messages waiting to be logged, then closed again in between logs. */
|
||||
static FILE *pxLoggingFileHandle = NULL;
|
||||
|
||||
/* When true prints are performed directly. After start up xDirectPrint is set
|
||||
to pdFALSE - at which time prints that require Win32 system calls are done by
|
||||
the Win32 thread responsible for logging. */
|
||||
BaseType_t xDirectPrint = pdTRUE;
|
||||
|
||||
/* File names for the in use and complete (full) log files. */
|
||||
static const char *pcLogFileName = "RTOSDemo.log";
|
||||
static const char *pcFullLogFileName = "RTOSDemo.ful";
|
||||
|
||||
/* Keep the current file size in a variable, as an optimisation. */
|
||||
static size_t ulSizeOfLoggingFile = 0ul;
|
||||
|
||||
/* The UDP socket and address on/to which print messages are sent. */
|
||||
Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET;
|
||||
struct freertos_sockaddr xPrintUDPAddress;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vLoggingInit( BaseType_t xLogToStdout, BaseType_t xLogToFile, BaseType_t xLogToUDP, uint32_t ulRemoteIPAddress, uint16_t usRemotePort )
|
||||
{
|
||||
/* Can only be called before the scheduler has started. */
|
||||
configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED );
|
||||
|
||||
#if( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) )
|
||||
{
|
||||
HANDLE Win32Thread;
|
||||
|
||||
/* Record which output methods are to be used. */
|
||||
xStdoutLoggingUsed = xLogToStdout;
|
||||
xDiskFileLoggingUsed = xLogToFile;
|
||||
xUDPLoggingUsed = xLogToUDP;
|
||||
|
||||
/* If a disk file is used then initialise it now. */
|
||||
if( xDiskFileLoggingUsed != pdFALSE )
|
||||
{
|
||||
prvFileLoggingInit();
|
||||
}
|
||||
|
||||
/* If UDP logging is used then store the address to which the log data
|
||||
will be sent - but don't create the socket yet because the network is
|
||||
not initialised. */
|
||||
if( xUDPLoggingUsed != pdFALSE )
|
||||
{
|
||||
/* Set the address to which the print messages are sent. */
|
||||
xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort );
|
||||
xPrintUDPAddress.sin_addr = ulRemoteIPAddress;
|
||||
}
|
||||
|
||||
/* If a disk file or stdout are to be used then Win32 system calls will
|
||||
have to be made. Such system calls cannot be made from FreeRTOS tasks
|
||||
so create a stream buffer to pass the messages to a Win32 thread, then
|
||||
create the thread itself, along with a Win32 event that can be used to
|
||||
unblock the thread. */
|
||||
if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) )
|
||||
{
|
||||
/* Create the buffer. */
|
||||
xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 );
|
||||
configASSERT( xLogStreamBuffer );
|
||||
memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) );
|
||||
xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1;
|
||||
|
||||
/* Create the Windows event. */
|
||||
pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" );
|
||||
|
||||
/* Create the thread itself. */
|
||||
Win32Thread = CreateThread(
|
||||
NULL, /* Pointer to thread security attributes. */
|
||||
0, /* Initial thread stack size, in bytes. */
|
||||
prvWin32LoggingThread, /* 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( Win32Thread, ~0x01u );
|
||||
SetThreadPriorityBoost( Win32Thread, TRUE );
|
||||
SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE );
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* FreeRTOSIPConfig is set such that no print messages will be output.
|
||||
Avoid compiler warnings about unused parameters. */
|
||||
( void ) xLogToStdout;
|
||||
( void ) xLogToFile;
|
||||
( void ) xLogToUDP;
|
||||
( void ) usRemotePort;
|
||||
( void ) ulRemoteIPAddress;
|
||||
}
|
||||
#endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreatePrintSocket( void *pvParameter1, uint32_t ulParameter2 )
|
||||
{
|
||||
static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 );
|
||||
Socket_t xSocket;
|
||||
|
||||
/* The function prototype is that of a deferred function, but the parameters
|
||||
are not actually used. */
|
||||
( void ) pvParameter1;
|
||||
( void ) ulParameter2;
|
||||
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
|
||||
if( xSocket != FREERTOS_INVALID_SOCKET )
|
||||
{
|
||||
/* FreeRTOS+TCP decides which port to bind to. */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
|
||||
FreeRTOS_bind( xSocket, NULL, 0 );
|
||||
|
||||
/* Now the socket is bound it can be assigned to the print socket. */
|
||||
xPrintSocket = xSocket;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vLoggingPrintf( const char *pcFormat, ... )
|
||||
{
|
||||
char cPrintString[ dlMAX_PRINT_STRING_LENGTH ];
|
||||
char cOutputString[ dlMAX_PRINT_STRING_LENGTH ];
|
||||
char *pcSource, *pcTarget, *pcBegin;
|
||||
size_t xLength, xLength2, rc;
|
||||
static BaseType_t xMessageNumber = 0;
|
||||
va_list args;
|
||||
uint32_t ulIPAddress;
|
||||
const char *pcTaskName;
|
||||
const char *pcNoTask = "None";
|
||||
int iOriginalPriority;
|
||||
HANDLE xCurrentTask;
|
||||
|
||||
|
||||
if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) )
|
||||
{
|
||||
/* There are a variable number of parameters. */
|
||||
va_start( args, pcFormat );
|
||||
|
||||
/* Additional info to place at the start of the log. */
|
||||
if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
|
||||
{
|
||||
pcTaskName = pcTaskGetName( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
pcTaskName = pcNoTask;
|
||||
}
|
||||
|
||||
if( strcmp( pcFormat, "\n" ) != 0 )
|
||||
{
|
||||
xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%lu %lu [%s] ",
|
||||
xMessageNumber++,
|
||||
( unsigned long ) xTaskGetTickCount(),
|
||||
pcTaskName );
|
||||
}
|
||||
else
|
||||
{
|
||||
xLength = 0;
|
||||
memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH );
|
||||
}
|
||||
|
||||
xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args );
|
||||
|
||||
if( xLength2 < 0 )
|
||||
{
|
||||
/* Clean up. */
|
||||
xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength;
|
||||
cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0';
|
||||
}
|
||||
|
||||
xLength += xLength2;
|
||||
va_end( args );
|
||||
|
||||
/* For ease of viewing, copy the string into another buffer, converting
|
||||
IP addresses to dot notation on the way. */
|
||||
pcSource = cPrintString;
|
||||
pcTarget = cOutputString;
|
||||
|
||||
while( ( *pcSource ) != '\0' )
|
||||
{
|
||||
*pcTarget = *pcSource;
|
||||
pcTarget++;
|
||||
pcSource++;
|
||||
|
||||
/* Look forward for an IP address denoted by 'ip'. */
|
||||
if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) )
|
||||
{
|
||||
*pcTarget = *pcSource;
|
||||
pcTarget++;
|
||||
*pcTarget = '\0';
|
||||
pcBegin = pcTarget - 8;
|
||||
|
||||
while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) )
|
||||
{
|
||||
pcTarget--;
|
||||
}
|
||||
|
||||
sscanf( pcTarget, "%8X", &ulIPAddress );
|
||||
rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu",
|
||||
( unsigned long ) ( ulIPAddress >> 24UL ),
|
||||
( unsigned long ) ( (ulIPAddress >> 16UL) & 0xffUL ),
|
||||
( unsigned long ) ( (ulIPAddress >> 8UL) & 0xffUL ),
|
||||
( unsigned long ) ( ulIPAddress & 0xffUL ) );
|
||||
pcTarget += rc;
|
||||
pcSource += 3; /* skip "<n>ip" */
|
||||
}
|
||||
}
|
||||
|
||||
/* How far through the buffer was written? */
|
||||
xLength = ( BaseType_t ) ( pcTarget - cOutputString );
|
||||
|
||||
/* If the message is to be logged to a UDP port then it can be sent directly
|
||||
because it only uses FreeRTOS function (not Win32 functions). */
|
||||
if( xUDPLoggingUsed != pdFALSE )
|
||||
{
|
||||
if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) )
|
||||
{
|
||||
/* Create and bind the socket to which print messages are sent. The
|
||||
xTimerPendFunctionCall() function is used even though this is
|
||||
not an interrupt because this function is called from the IP task
|
||||
and the IP task cannot itself wait for a socket to bind. The
|
||||
parameters to prvCreatePrintSocket() are not required so set to
|
||||
NULL or 0. */
|
||||
xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK );
|
||||
}
|
||||
|
||||
if( xPrintSocket != FREERTOS_INVALID_SOCKET )
|
||||
{
|
||||
FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) );
|
||||
|
||||
/* Just because the UDP data logger I'm using is dumb. */
|
||||
FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* If logging is also to go to either stdout or a disk file then it cannot
|
||||
be output here - so instead write the message to the stream buffer and wake
|
||||
the Win32 thread which will read it from the stream buffer and perform the
|
||||
actual output. */
|
||||
if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) )
|
||||
{
|
||||
configASSERT( xLogStreamBuffer );
|
||||
|
||||
/* How much space is in the buffer? */
|
||||
xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer );
|
||||
|
||||
/* There must be enough space to write both the string and the length of
|
||||
the string. */
|
||||
if( xLength2 >= ( xLength + sizeof( xLength ) ) )
|
||||
{
|
||||
/* First write in the length of the data, then write in the data
|
||||
itself. Raising the thread priority is used as a critical section
|
||||
as there are potentially multiple writers. The stream buffer is
|
||||
only thread safe when there is a single writer (likewise for
|
||||
reading from the buffer). */
|
||||
xCurrentTask = GetCurrentThread();
|
||||
iOriginalPriority = GetThreadPriority( xCurrentTask );
|
||||
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
|
||||
uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) );
|
||||
uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength );
|
||||
SetThreadPriority( GetCurrentThread(), iOriginalPriority );
|
||||
}
|
||||
|
||||
/* xDirectPrint is initialised to pdTRUE, and while it remains true the
|
||||
logging output function is called directly. When the system is running
|
||||
the output function cannot be called directly because it would get
|
||||
called from both FreeRTOS tasks and Win32 threads - so instead wake the
|
||||
Win32 thread responsible for the actual output. */
|
||||
if( xDirectPrint != pdFALSE )
|
||||
{
|
||||
/* While starting up, the thread which calls prvWin32LoggingThread()
|
||||
is not running yet and xDirectPrint will be pdTRUE. */
|
||||
prvLoggingFlushBuffer();
|
||||
}
|
||||
else if( pvLoggingThreadEvent != NULL )
|
||||
{
|
||||
/* While running, wake up prvWin32LoggingThread() to send the
|
||||
logging data. */
|
||||
SetEvent( pvLoggingThreadEvent );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvLoggingFlushBuffer( void )
|
||||
{
|
||||
size_t xLength;
|
||||
char cPrintString[ dlMAX_PRINT_STRING_LENGTH ];
|
||||
|
||||
/* 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( xLogStreamBuffer ) > sizeof( xLength ) )
|
||||
{
|
||||
memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH );
|
||||
uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
|
||||
uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE );
|
||||
|
||||
/* Write the message to standard out if requested to do so when
|
||||
vLoggingInit() was called, or if the network is not yet up. */
|
||||
if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
|
||||
{
|
||||
/* Write the message to stdout. */
|
||||
printf( "%s", cPrintString ); /*_RB_ Replace with _write(). */
|
||||
}
|
||||
|
||||
/* Write the message to a file if requested to do so when
|
||||
vLoggingInit() was called. */
|
||||
if( xDiskFileLoggingUsed != pdFALSE )
|
||||
{
|
||||
prvLogToFile( cPrintString, xLength );
|
||||
}
|
||||
}
|
||||
|
||||
prvFileClose();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static DWORD WINAPI prvWin32LoggingThread( void *pvParameter )
|
||||
{
|
||||
const DWORD xMaxWait = 1000;
|
||||
|
||||
( void ) pvParameter;
|
||||
|
||||
/* From now on, prvLoggingFlushBuffer() will only be called from this
|
||||
Windows thread */
|
||||
xDirectPrint = pdFALSE;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait to be told there are message waiting to be logged. */
|
||||
WaitForSingleObject( pvLoggingThreadEvent, xMaxWait );
|
||||
|
||||
/* Write out all waiting messages. */
|
||||
prvLoggingFlushBuffer();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvFileLoggingInit( void )
|
||||
{
|
||||
FILE *pxHandle = fopen( pcLogFileName, "a" );
|
||||
|
||||
if( pxHandle != NULL )
|
||||
{
|
||||
fseek( pxHandle, SEEK_END, 0ul );
|
||||
ulSizeOfLoggingFile = ftell( pxHandle );
|
||||
fclose( pxHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
ulSizeOfLoggingFile = 0ul;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvFileClose( void )
|
||||
{
|
||||
if( pxLoggingFileHandle != NULL )
|
||||
{
|
||||
fclose( pxLoggingFileHandle );
|
||||
pxLoggingFileHandle = NULL;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvLogToFile( const char *pcMessage, size_t xLength )
|
||||
{
|
||||
if( pxLoggingFileHandle == NULL )
|
||||
{
|
||||
pxLoggingFileHandle = fopen( pcLogFileName, "a" );
|
||||
}
|
||||
|
||||
if( pxLoggingFileHandle != NULL )
|
||||
{
|
||||
fwrite( pcMessage, 1, xLength, pxLoggingFileHandle );
|
||||
ulSizeOfLoggingFile += xLength;
|
||||
|
||||
/* If the file has grown to its maximum permissible size then close and
|
||||
rename it - then start with a new file. */
|
||||
if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE )
|
||||
{
|
||||
prvFileClose();
|
||||
if( _access( pcFullLogFileName, 00 ) == 0 )
|
||||
{
|
||||
remove( pcFullLogFileName );
|
||||
}
|
||||
rename( pcLogFileName, pcFullLogFileName );
|
||||
ulSizeOfLoggingFile = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.4.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef DEMO_LOGGING_H
|
||||
#define DEMO_LOGGING_H
|
||||
|
||||
/*
|
||||
* Initialise a logging system that can be used from FreeRTOS tasks and Win32
|
||||
* threads. Do not call printf() directly while the scheduler is running.
|
||||
*
|
||||
* Set xLogToStdout, xLogToFile and xLogToUDP to either pdTRUE or pdFALSE to
|
||||
* lot to stdout, a disk file and a UDP port respectively.
|
||||
*
|
||||
* If xLogToUDP is pdTRUE then ulRemoteIPAddress and usRemotePort must be set
|
||||
* to the IP address and port number to which UDP log messages will be sent.
|
||||
*/
|
||||
void vLoggingInit( BaseType_t xLogToStdout,
|
||||
BaseType_t xLogToFile,
|
||||
BaseType_t xLogToUDP,
|
||||
uint32_t ulRemoteIPAddress,
|
||||
uint16_t usRemotePort );
|
||||
|
||||
#endif /* DEMO_LOGGING_H */
|
||||
|
||||
|
|
@ -46,50 +46,50 @@
|
|||
#include "SimpleUDPClientAndServer.h"
|
||||
#include "SimpleTCPEchoServer.h"
|
||||
#include "TCPEchoClient_SingleTasks.h"
|
||||
#include "demo_logging.h"
|
||||
#include "logging.h"
|
||||
|
||||
/* Simple UDP client and server task parameters. */
|
||||
#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL )
|
||||
#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL )
|
||||
|
||||
/* Echo client task parameters - used for both TCP and UDP echo clients. */
|
||||
#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
||||
#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
||||
#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
|
||||
/* Echo server task parameters. */
|
||||
#define mainECHO_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
||||
#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define mainECHO_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
||||
#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
|
||||
/* Define a name that will be used for LLMNR and NBNS searches. */
|
||||
#define mainHOST_NAME "RTOSDemo"
|
||||
#define mainDEVICE_NICK_NAME "windows_demo"
|
||||
#define mainHOST_NAME "RTOSDemo"
|
||||
#define mainDEVICE_NICK_NAME "windows_demo"
|
||||
|
||||
/* Set the following constants to 1 or 0 to define which tasks to include and
|
||||
exclude:
|
||||
|
||||
mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS: When set to 1 two UDP client tasks
|
||||
and two UDP server tasks are created. The clients talk to the servers. One set
|
||||
of tasks use the standard sockets interface, and the other the zero copy sockets
|
||||
interface. These tasks are self checking and will trigger a configASSERT() if
|
||||
they detect a difference in the data that is received from that which was sent.
|
||||
As these tasks use UDP, and can therefore loose packets, they will cause
|
||||
configASSERT() to be called when they are run in a less than perfect networking
|
||||
environment.
|
||||
|
||||
mainCREATE_TCP_ECHO_TASKS_SINGLE: When set to 1 a set of tasks are created that
|
||||
send TCP echo requests to the standard echo port (port 7), then wait for and
|
||||
verify the echo reply, from within the same task (Tx and Rx are performed in the
|
||||
same RTOS task). The IP address of the echo server must be configured using the
|
||||
configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in
|
||||
FreeRTOSConfig.h.
|
||||
|
||||
mainCREATE_TCP_ECHO_SERVER_TASK: When set to 1 a task is created that accepts
|
||||
connections on the standard echo port (port 7), then echos back any data
|
||||
received on that connection.
|
||||
*/
|
||||
#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 1
|
||||
#define mainCREATE_TCP_ECHO_TASKS_SINGLE 0
|
||||
#define mainCREATE_TCP_ECHO_SERVER_TASK 0
|
||||
* exclude:
|
||||
*
|
||||
* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS: When set to 1 two UDP client tasks
|
||||
* and two UDP server tasks are created. The clients talk to the servers. One set
|
||||
* of tasks use the standard sockets interface, and the other the zero copy sockets
|
||||
* interface. These tasks are self checking and will trigger a configASSERT() if
|
||||
* they detect a difference in the data that is received from that which was sent.
|
||||
* As these tasks use UDP, and can therefore loose packets, they will cause
|
||||
* configASSERT() to be called when they are run in a less than perfect networking
|
||||
* environment.
|
||||
*
|
||||
* mainCREATE_TCP_ECHO_TASKS_SINGLE: When set to 1 a set of tasks are created that
|
||||
* send TCP echo requests to the standard echo port (port 7), then wait for and
|
||||
* verify the echo reply, from within the same task (Tx and Rx are performed in the
|
||||
* same RTOS task). The IP address of the echo server must be configured using the
|
||||
* configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in
|
||||
* FreeRTOSConfig.h.
|
||||
*
|
||||
* mainCREATE_TCP_ECHO_SERVER_TASK: When set to 1 a task is created that accepts
|
||||
* connections on the standard echo port (port 7), then echos back any data
|
||||
* received on that connection.
|
||||
*/
|
||||
#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 1
|
||||
#define mainCREATE_TCP_ECHO_TASKS_SINGLE 0
|
||||
#define mainCREATE_TCP_ECHO_SERVER_TASK 0
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
|
@ -104,28 +104,28 @@ static void prvSRand( UBaseType_t ulSeed );
|
|||
static void prvMiscInitialisation( void );
|
||||
|
||||
/* The default IP and MAC address used by the demo. The address configuration
|
||||
defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is
|
||||
1 but a DHCP server could not be contacted. See the online documentation for
|
||||
more information. */
|
||||
* defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is
|
||||
* 1 but a DHCP server could not be contacted. See the online documentation for
|
||||
* more information. */
|
||||
static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };
|
||||
static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };
|
||||
static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };
|
||||
static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };
|
||||
|
||||
/* Set the following constant to pdTRUE to log using the method indicated by the
|
||||
name of the constant, or pdFALSE to not log using the method indicated by the
|
||||
name of the constant. Options include to standard out (xLogToStdout), to a disk
|
||||
file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE
|
||||
then UDP messages are sent to the IP address configured as the echo server
|
||||
address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and
|
||||
the port number set by configPRINT_PORT in FreeRTOSConfig.h. */
|
||||
* name of the constant, or pdFALSE to not log using the method indicated by the
|
||||
* name of the constant. Options include to standard out (xLogToStdout), to a disk
|
||||
* file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE
|
||||
* then UDP messages are sent to the IP address configured as the echo server
|
||||
* address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and
|
||||
* the port number set by configPRINT_PORT in FreeRTOSConfig.h. */
|
||||
const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;
|
||||
|
||||
/* Default MAC address configuration. The demo creates a virtual network
|
||||
connection that uses this MAC address by accessing the raw Ethernet data
|
||||
to and from a real network connection on the host PC. See the
|
||||
configNETWORK_INTERFACE_TO_USE definition for information on how to configure
|
||||
the real network connection to use. */
|
||||
* connection that uses this MAC address by accessing the raw Ethernet data
|
||||
* to and from a real network connection on the host PC. See the
|
||||
* configNETWORK_INTERFACE_TO_USE definition for information on how to configure
|
||||
* the real network connection to use. */
|
||||
const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
|
||||
|
||||
/* Use by the pseudo random number generator. */
|
||||
|
|
@ -135,222 +135,223 @@ static UBaseType_t ulNextRand;
|
|||
|
||||
int main( void )
|
||||
{
|
||||
const uint32_t ulLongTime_ms = pdMS_TO_TICKS( 1000UL );
|
||||
const uint32_t ulLongTime_ms = pdMS_TO_TICKS( 1000UL );
|
||||
|
||||
/*
|
||||
* Instructions for using this project are provided on:
|
||||
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html
|
||||
*/
|
||||
/*
|
||||
* Instructions for using this project are provided on:
|
||||
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html
|
||||
*/
|
||||
|
||||
/* Miscellaneous initialisation including preparing the logging and seeding
|
||||
the random number generator. */
|
||||
prvMiscInitialisation();
|
||||
/* Miscellaneous initialisation including preparing the logging and seeding
|
||||
* the random number generator. */
|
||||
prvMiscInitialisation();
|
||||
|
||||
/* Initialise the network interface.
|
||||
/* Initialise the network interface.
|
||||
*
|
||||
***NOTE*** Tasks that use the network are created in the network event hook
|
||||
* when the network is connected and ready for use (see the definition of
|
||||
* vApplicationIPNetworkEventHook() below). The address values passed in here
|
||||
* are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
|
||||
* but a DHCP server cannot be contacted. */
|
||||
FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\n" ) );
|
||||
FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
|
||||
|
||||
***NOTE*** Tasks that use the network are created in the network event hook
|
||||
when the network is connected and ready for use (see the definition of
|
||||
vApplicationIPNetworkEventHook() below). The address values passed in here
|
||||
are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
|
||||
but a DHCP server cannot be contacted. */
|
||||
FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\n" ) );
|
||||
FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
|
||||
/* Start the RTOS scheduler. */
|
||||
FreeRTOS_debug_printf( ( "vTaskStartScheduler\n" ) );
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* Start the RTOS scheduler. */
|
||||
FreeRTOS_debug_printf( ("vTaskStartScheduler\n") );
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well, the scheduler will now be running, and the following
|
||||
line will never be reached. If the following line does execute, then
|
||||
there was insufficient FreeRTOS heap memory available for the idle and/or
|
||||
timer tasks to be created. See the memory management section on the
|
||||
FreeRTOS web site for more details (this is standard text that is not not
|
||||
really applicable to the Win32 simulator port). */
|
||||
for( ;; )
|
||||
{
|
||||
Sleep( ulLongTime_ms );
|
||||
}
|
||||
/* If all is well, the scheduler will now be running, and the following
|
||||
* line will never be reached. If the following line does execute, then
|
||||
* there was insufficient FreeRTOS heap memory available for the idle and/or
|
||||
* timer tasks to be created. See the memory management section on the
|
||||
* FreeRTOS web site for more details (this is standard text that is not not
|
||||
* really applicable to the Win32 simulator port). */
|
||||
for( ; ; )
|
||||
{
|
||||
Sleep( ulLongTime_ms );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
const uint32_t ulMSToSleep = 1;
|
||||
const uint32_t ulMSToSleep = 1;
|
||||
|
||||
/* This is just a trivial example of an idle hook. It is called on each
|
||||
cycle of the idle task if configUSE_IDLE_HOOK is set to 1 in
|
||||
FreeRTOSConfig.h. It must *NOT* attempt to block. In this case the
|
||||
idle task just sleeps to lower the CPU usage. */
|
||||
Sleep( ulMSToSleep );
|
||||
/* This is just a trivial example of an idle hook. It is called on each
|
||||
* cycle of the idle task if configUSE_IDLE_HOOK is set to 1 in
|
||||
* FreeRTOSConfig.h. It must *NOT* attempt to block. In this case the
|
||||
* idle task just sleeps to lower the CPU usage. */
|
||||
Sleep( ulMSToSleep );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vAssertCalled( const char *pcFile, uint32_t ulLine )
|
||||
void vAssertCalled( const char * pcFile,
|
||||
uint32_t ulLine )
|
||||
{
|
||||
const uint32_t ulLongSleep = 1000UL;
|
||||
volatile uint32_t ulBlockVariable = 0UL;
|
||||
volatile char *pcFileName = ( volatile char * ) pcFile;
|
||||
volatile uint32_t ulLineNumber = ulLine;
|
||||
const uint32_t ulLongSleep = 1000UL;
|
||||
volatile uint32_t ulBlockVariable = 0UL;
|
||||
volatile char * pcFileName = ( volatile char * ) pcFile;
|
||||
volatile uint32_t ulLineNumber = ulLine;
|
||||
|
||||
( void ) pcFileName;
|
||||
( void ) ulLineNumber;
|
||||
( void ) pcFileName;
|
||||
( void ) ulLineNumber;
|
||||
|
||||
FreeRTOS_debug_printf( ( "vAssertCalled( %s, %ld\n", pcFile, ulLine ) );
|
||||
FreeRTOS_debug_printf( ( "vAssertCalled( %s, %ld\n", pcFile, ulLine ) );
|
||||
|
||||
/* Setting ulBlockVariable to a non-zero value in the debugger will allow
|
||||
this function to be exited. */
|
||||
taskDISABLE_INTERRUPTS();
|
||||
{
|
||||
while( ulBlockVariable == 0UL )
|
||||
{
|
||||
Sleep( ulLongSleep );
|
||||
}
|
||||
}
|
||||
taskENABLE_INTERRUPTS();
|
||||
/* Setting ulBlockVariable to a non-zero value in the debugger will allow
|
||||
* this function to be exited. */
|
||||
taskDISABLE_INTERRUPTS();
|
||||
{
|
||||
while( ulBlockVariable == 0UL )
|
||||
{
|
||||
Sleep( ulLongSleep );
|
||||
}
|
||||
}
|
||||
taskENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect
|
||||
events are only received if implemented in the MAC driver. */
|
||||
* events are only received if implemented in the MAC driver. */
|
||||
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
|
||||
{
|
||||
uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
|
||||
char cBuffer[ 16 ];
|
||||
static BaseType_t xTasksAlreadyCreated = pdFALSE;
|
||||
uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
|
||||
char cBuffer[ 16 ];
|
||||
static BaseType_t xTasksAlreadyCreated = pdFALSE;
|
||||
|
||||
/* If the network has just come up...*/
|
||||
if( eNetworkEvent == eNetworkUp )
|
||||
{
|
||||
/* Create the tasks that use the IP stack if they have not already been
|
||||
created. */
|
||||
if( xTasksAlreadyCreated == pdFALSE )
|
||||
{
|
||||
/* See the comments above the definitions of these pre-processor
|
||||
macros at the top of this file for a description of the individual
|
||||
demo tasks. */
|
||||
#if( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 )
|
||||
{
|
||||
vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY );
|
||||
}
|
||||
#endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */
|
||||
/* If the network has just come up...*/
|
||||
if( eNetworkEvent == eNetworkUp )
|
||||
{
|
||||
/* Create the tasks that use the IP stack if they have not already been
|
||||
* created. */
|
||||
if( xTasksAlreadyCreated == pdFALSE )
|
||||
{
|
||||
/* See the comments above the definitions of these pre-processor
|
||||
* macros at the top of this file for a description of the individual
|
||||
* demo tasks. */
|
||||
#if ( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 )
|
||||
{
|
||||
vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY );
|
||||
}
|
||||
#endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */
|
||||
|
||||
#if( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 )
|
||||
{
|
||||
vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );
|
||||
}
|
||||
#endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */
|
||||
#if ( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 )
|
||||
{
|
||||
vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );
|
||||
}
|
||||
#endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */
|
||||
|
||||
#if( mainCREATE_TCP_ECHO_SERVER_TASK == 1 )
|
||||
{
|
||||
vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY );
|
||||
}
|
||||
#endif
|
||||
#if ( mainCREATE_TCP_ECHO_SERVER_TASK == 1 )
|
||||
{
|
||||
vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY );
|
||||
}
|
||||
#endif
|
||||
|
||||
xTasksAlreadyCreated = pdTRUE;
|
||||
}
|
||||
xTasksAlreadyCreated = pdTRUE;
|
||||
}
|
||||
|
||||
/* Print out the network configuration, which may have come from a DHCP
|
||||
server. */
|
||||
FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
|
||||
FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );
|
||||
/* Print out the network configuration, which may have come from a DHCP
|
||||
* server. */
|
||||
FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
|
||||
FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );
|
||||
|
||||
FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
|
||||
FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );
|
||||
FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
|
||||
FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );
|
||||
|
||||
FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
|
||||
FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );
|
||||
FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
|
||||
FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );
|
||||
|
||||
FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
|
||||
FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );
|
||||
}
|
||||
FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
|
||||
FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationMallocFailedHook( void )
|
||||
{
|
||||
/* Called if a call to pvPortMalloc() fails because there is insufficient
|
||||
free memory available in the FreeRTOS heap. pvPortMalloc() is called
|
||||
internally by FreeRTOS API functions that create tasks, queues, software
|
||||
timers, and semaphores. The size of the FreeRTOS heap is set by the
|
||||
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
|
||||
vAssertCalled( __FILE__, __LINE__ );
|
||||
/* Called if a call to pvPortMalloc() fails because there is insufficient
|
||||
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
|
||||
* internally by FreeRTOS API functions that create tasks, queues, software
|
||||
* timers, and semaphores. The size of the FreeRTOS heap is set by the
|
||||
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
|
||||
vAssertCalled( __FILE__, __LINE__ );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
UBaseType_t uxRand( void )
|
||||
{
|
||||
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
|
||||
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
|
||||
|
||||
/* Utility function to generate a pseudo random number. */
|
||||
/* Utility function to generate a pseudo random number. */
|
||||
|
||||
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
|
||||
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
|
||||
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
|
||||
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSRand( UBaseType_t ulSeed )
|
||||
{
|
||||
/* Utility function to seed the pseudo random number generator. */
|
||||
ulNextRand = ulSeed;
|
||||
/* Utility function to seed the pseudo random number generator. */
|
||||
ulNextRand = ulSeed;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvMiscInitialisation( void )
|
||||
{
|
||||
time_t xTimeNow;
|
||||
uint32_t ulLoggingIPAddress;
|
||||
time_t xTimeNow;
|
||||
uint32_t ulLoggingIPAddress;
|
||||
|
||||
ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 );
|
||||
vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );
|
||||
ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 );
|
||||
vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );
|
||||
|
||||
/* Seed the random number generator. */
|
||||
time( &xTimeNow );
|
||||
FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\n", xTimeNow ) );
|
||||
prvSRand( ( uint32_t ) xTimeNow );
|
||||
FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );
|
||||
/* Seed the random number generator. */
|
||||
time( &xTimeNow );
|
||||
FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\n", xTimeNow ) );
|
||||
prvSRand( ( uint32_t ) xTimeNow );
|
||||
FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
|
||||
#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
|
||||
|
||||
const char *pcApplicationHostnameHook( void )
|
||||
{
|
||||
/* Assign the name "FreeRTOS" to this network node. This function will
|
||||
be called during the DHCP: the machine will be registered with an IP
|
||||
address plus this name. */
|
||||
return mainHOST_NAME;
|
||||
}
|
||||
const char * pcApplicationHostnameHook( void )
|
||||
{
|
||||
/* Assign the name "FreeRTOS" to this network node. This function will
|
||||
* be called during the DHCP: the machine will be registered with an IP
|
||||
* address plus this name. */
|
||||
return mainHOST_NAME;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
|
||||
#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
|
||||
|
||||
BaseType_t xApplicationDNSQueryHook( const char *pcName )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xApplicationDNSQueryHook( const char * pcName )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Determine if a name lookup is for this node. Two names are given
|
||||
to this node: that returned by pcApplicationHostnameHook() and that set
|
||||
by mainDEVICE_NICK_NAME. */
|
||||
if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
|
||||
{
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
|
||||
{
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
/* Determine if a name lookup is for this node. Two names are given
|
||||
* to this node: that returned by pcApplicationHostnameHook() and that set
|
||||
* by mainDEVICE_NICK_NAME. */
|
||||
if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
|
||||
{
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
|
||||
{
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */
|
||||
|
||||
/*
|
||||
* Callback that provides the inputs necessary to generate a randomized TCP
|
||||
|
|
@ -359,26 +360,25 @@ uint32_t ulLoggingIPAddress;
|
|||
* SYSTEMS.
|
||||
*/
|
||||
extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
|
||||
uint16_t usSourcePort,
|
||||
uint32_t ulDestinationAddress,
|
||||
uint16_t usDestinationPort )
|
||||
uint16_t usSourcePort,
|
||||
uint32_t ulDestinationAddress,
|
||||
uint16_t usDestinationPort )
|
||||
{
|
||||
( void ) ulSourceAddress;
|
||||
( void ) usSourcePort;
|
||||
( void ) ulDestinationAddress;
|
||||
( void ) usDestinationPort;
|
||||
( void ) ulSourceAddress;
|
||||
( void ) usSourcePort;
|
||||
( void ) ulDestinationAddress;
|
||||
( void ) usDestinationPort;
|
||||
|
||||
return uxRand();
|
||||
return uxRand();
|
||||
}
|
||||
|
||||
/*
|
||||
* Supply a random number to FreeRTOS+TCP stack.
|
||||
* THIS IS ONLY A DUMMY IMPLEMENTATION THAT RETURNS A PSEUDO RANDOM NUMBER
|
||||
* Supply a random number to FreeRTOS+TCP stack.
|
||||
* THIS IS ONLY A DUMMY IMPLEMENTATION THAT RETURNS A PSEUDO RANDOM NUMBER
|
||||
* SO IS NOT INTENDED FOR USE IN PRODUCTION SYSTEMS.
|
||||
*/
|
||||
BaseType_t xApplicationGetRandomNumber(uint32_t* pulNumber)
|
||||
BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber )
|
||||
{
|
||||
*(pulNumber) = uxRand();
|
||||
return pdTRUE;
|
||||
*( pulNumber ) = uxRand();
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue