/*
 * FreeRTOS Kernel V10.3.0
 * Copyright (C) 2020 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!
 */

/*
 * An example that mimics a message buffer being used to pass data from one core
 * to another.  The core that sends the data is referred to as core A.  The core
 * that receives the data is referred to as core B.  The task implemented by
 * prvCoreATask() runs on core A.  Two instances of the task implemented by
 * prvCoreBTasks() run on core B.  prvCoreATask() sends messages via message
 * buffers to both instances of prvCoreBTasks(), one message buffer per channel.
 * A third message buffer is used to pass the handle of the message buffer
 * written to by core A to an interrupt service routine that is triggered by
 * core A but executes on core B.
 *
 * The example relies on the FreeRTOS provided default implementation of
 * sbSEND_COMPLETED() being overridden by an implementation in FreeRTOSConfig.h
 * that writes the handle of the message buffer that contains data into the
 * control message buffer, then generates an interrupt in core B.  The necessary
 * implementation is provided in this file and can be enabled by adding the
 * following to FreeRTOSConfig.h:
 *
 * #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
 *
 * Core to core communication via message buffer requires the message buffers
 * to be at an address known to both cores within shared memory.
 *
 * Note that, while this example uses three message buffers, the same
 * functionality can be implemented using a single message buffer by using the
 * same design pattern described on the link below for queues, but using message
 * buffers instead.  It is actually simpler with a message buffer as variable
 * length data can be written into the message buffer directly:
 * http://www.freertos.org/Pend-on-multiple-rtos-objects.html#alternative_design_pattern
 */

/* Standard includes. */
#include "stdio.h"
#include "string.h"

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "message_buffer.h"

/* Demo app includes. */
#include "MessageBufferAMP.h"

/* Enough for 3 4 byte pointers, including the additional 4 bytes per message
overhead of message buffers. */
#define mbaCONTROL_MESSAGE_BUFFER_SIZE ( 24 )

/* Enough four 4 8 byte strings, plus the additional 4 bytes per message
overhead of message buffers. */
#define mbaTASK_MESSAGE_BUFFER_SIZE ( 60 )

/* The number of instances of prvCoreBTasks that are created. */
#define mbaNUMBER_OF_CORE_B_TASKS	2

/* A block time of 0 simply means, don't block. */
#define mbaDONT_BLOCK				0

/* Macro that mimics an interrupt service routine executing by simply calling
the routine inline. */
#define mbaGENERATE_CORE_B_INTERRUPT() prvCoreBInterruptHandler()

/*-----------------------------------------------------------*/

/*
 * Implementation of the task that, on a real dual core device, would run on
 * core A and send message to tasks running on core B.
 */
static void prvCoreATask( void *pvParameters );

/*
 * Implementation of the task that, on a real dual core device, would run on
 * core B and receive message from core A.  The demo creates two instances of
 * this task.
 */
static void prvCoreBTasks( void *pvParameters );

/*
 * The function that, on a real dual core device, would handle inter-core
 * interrupts, but in this case is just called inline.
 */
static void prvCoreBInterruptHandler( void );

/*-----------------------------------------------------------*/

/* The message buffers used to pass data from core A to core B. */
static MessageBufferHandle_t xCoreBMessageBuffers[ mbaNUMBER_OF_CORE_B_TASKS ];

/* The control message buffer.  This is used to pass the handle of the message
message buffer that holds application data into the core to core interrupt
service routine. */
static MessageBufferHandle_t xControlMessageBuffer;

/* Counters used to indicate to the check that the tasks are still executing. */
static uint32_t ulCycleCounters[ mbaNUMBER_OF_CORE_B_TASKS ];

/* Set to pdFALSE if any errors are detected.  Used to inform the check task
that something might be wrong. */
BaseType_t xDemoStatus = pdPASS;

/*-----------------------------------------------------------*/

void vStartMessageBufferAMPTasks( configSTACK_DEPTH_TYPE xStackSize )
{
BaseType_t x;

	xControlMessageBuffer = xMessageBufferCreate( mbaCONTROL_MESSAGE_BUFFER_SIZE );

	xTaskCreate( prvCoreATask,		/* The function that implements the task. */
				 "AMPCoreA",		/* Human readable name for the task. */
				 xStackSize,		/* Stack size (in words!). */
				 NULL,				/* Task parameter is not used. */
				 tskIDLE_PRIORITY,	/* The priority at which the task is created. */
				 NULL );			/* No use for the task handle. */

	for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ )
	{
		xCoreBMessageBuffers[ x ] = xMessageBufferCreate( mbaTASK_MESSAGE_BUFFER_SIZE );
		configASSERT( xCoreBMessageBuffers[ x ] );

		/* Pass the loop counter into the created task using the task's
		parameter.  The task then uses the value as an index into the
		ulCycleCounters and xCoreBMessageBuffers arrays. */
		xTaskCreate( prvCoreBTasks,
					 "AMPCoreB1",
					 xStackSize,
					 ( void * ) x,
					 tskIDLE_PRIORITY + 1,
					 NULL );
	}
}
/*-----------------------------------------------------------*/

static void prvCoreATask( void *pvParameters )
{
BaseType_t x;
uint32_t ulNextValue = 0;
const TickType_t xDelay = pdMS_TO_TICKS( 250 );
char cString[ 15 ]; /* At least large enough to hold "4294967295\0" (0xffffffff). */

	/* Remove warning about unused parameters. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Create the next string to send.  The value is incremented on each
		loop iteration, and the length of the string changes as the number of
		digits in the value increases. */
		sprintf( cString, "%lu", ( unsigned long ) ulNextValue );

		/* Send the value from this (pseudo) Core A to the tasks on the (pseudo)
		Core B via the message buffers.  This will result in sbSEND_COMPLETED()
		being executed, which in turn will write the handle of the message
		buffer written to into xControlMessageBuffer then generate an interrupt
		in core B. */
		for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ )
		{
			xMessageBufferSend( /* The message buffer to write to. */
								xCoreBMessageBuffers[ x ],
								/* The source of the data to send. */
								( void * ) cString,
								/* The length of the data to send. */
								strlen( cString ),
								/* The block time, should the buffer be full. */
								mbaDONT_BLOCK );
		}

		/* Delay before repeating with a different and potentially different
		length string. */
		vTaskDelay( xDelay );
		ulNextValue++;
	}
}
/*-----------------------------------------------------------*/

static void prvCoreBTasks( void *pvParameters )
{
BaseType_t x;
size_t xReceivedBytes;
uint32_t ulNextValue = 0;
char cExpectedString[ 15 ]; /* At least large enough to hold "4294967295\0" (0xffffffff). */
char cReceivedString[ 15 ];

	/* The index into the xCoreBMessageBuffers and ulLoopCounter arrays is
	passed into this task using the task's parameter. */
	x = ( BaseType_t ) pvParameters;
	configASSERT( x < mbaNUMBER_OF_CORE_B_TASKS );

	for( ;; )
	{
		/* Create the string that is expected to be received this time round. */
		sprintf( cExpectedString, "%lu", ( unsigned long ) ulNextValue );

		/* Wait to receive the next message from core A. */
		memset( cReceivedString, 0x00, sizeof( cReceivedString ) );
		xReceivedBytes = xMessageBufferReceive( /* The message buffer to receive from. */
												xCoreBMessageBuffers[ x ],
												/* Location to store received data. */
												cReceivedString,
												/* Maximum number of bytes to receive. */
												sizeof( cReceivedString ),
												/* Ticks to wait if buffer is empty. */
												portMAX_DELAY );

		/* Check the number of bytes received was as expected. */
		configASSERT( xReceivedBytes == strlen( cExpectedString ) );
		( void ) xReceivedBytes; /* Incase configASSERT() is not defined. */

		/* If the received string matches that expected then increment the loop
		counter so the check task knows this task is still running. */
		if( strcmp( cReceivedString, cExpectedString ) == 0 )
		{
			( ulCycleCounters[ x ] )++;
		}
		else
		{
			xDemoStatus = pdFAIL;
		}

		/* Expect the next string in sequence the next time around. */
		ulNextValue++;
	}
}
/*-----------------------------------------------------------*/

/* Called by the reimplementation of sbSEND_COMPLETED(), which can be defined
as follows in FreeRTOSConfig.h:
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
*/
void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer )
{
MessageBufferHandle_t xUpdatedBuffer = ( MessageBufferHandle_t ) xUpdatedMessageBuffer;

	/* If sbSEND_COMPLETED() has been implemented as above, then this function
	is called from within xMessageBufferSend().  As this function also calls
	xMessageBufferSend() itself it is necessary to guard against a recursive
	call.  If the message buffer just updated is the message buffer written to
	by this function, then this is a recursive call, and the function can just
	exit without taking further action. */
	if( xUpdatedBuffer != xControlMessageBuffer )
	{
		/* Use xControlMessageBuffer to pass the handle of the message buffer
		written to by core A to the interrupt handler about to be generated in
		core B. */
		xMessageBufferSend( xControlMessageBuffer, &xUpdatedBuffer, sizeof( xUpdatedBuffer ), mbaDONT_BLOCK );

		/* This is where the interrupt would be generated.  In this case it is
		not a genuine interrupt handler that executes, just a standard function
		call. */
		mbaGENERATE_CORE_B_INTERRUPT();
	}
}
/*-----------------------------------------------------------*/

/* Handler for the interrupts that are triggered on core A but execute on core
B. */
static void prvCoreBInterruptHandler( void )
{
MessageBufferHandle_t xUpdatedMessageBuffer;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

	/* xControlMessageBuffer contains the handle of the message buffer that
	contains data. */
	if( xMessageBufferReceive( xControlMessageBuffer,
							   &xUpdatedMessageBuffer,
							   sizeof( xUpdatedMessageBuffer ),
							   mbaDONT_BLOCK ) == sizeof( xUpdatedMessageBuffer ) )
	{
		/* Call the API function that sends a notification to any task that is
		blocked on the xUpdatedMessageBuffer message buffer waiting for data to
		arrive. */
		xMessageBufferSendCompletedFromISR( xUpdatedMessageBuffer, &xHigherPriorityTaskWoken );
	}

	/* Normal FreeRTOS yield from interrupt semantics, where
	xHigherPriorityTaskWoken is initialzed to pdFALSE and will then get set to
	pdTRUE if the interrupt safe API unblocks a task that has a priority above
	that of the currently executing task. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/

BaseType_t xAreMessageBufferAMPTasksStillRunning( void )
{
static uint32_t ulLastCycleCounters[ mbaNUMBER_OF_CORE_B_TASKS ] = { 0 };
BaseType_t x;

	/* Called by the check task to determine the health status of the tasks
	implemented in this demo. */
	for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ )
	{
		if( ulLastCycleCounters[ x ] == ulCycleCounters[ x ] )
		{
			xDemoStatus = pdFAIL;
		}
		else
		{
			ulLastCycleCounters[ x ] = ulCycleCounters[ x ];
		}
	}

	return xDemoStatus;
}

