How to send data from ISR to task for GPS

Hi,
I am working with GPS module and Freertos. The microcontroller is STM32F4 and I have done the configuration using CubeMX software for freertos.

The GPS outputs NMEA sentences for every 1 sec on UART3 and I have written my routine in ISR that receives the continuous stream of characters.
I have start character $ and end character \n. I am looking for this sentence.

$GPGGA,080339.00,1732.61630,N,07821.15740,E,2,08,1.65,584.6,M,-73.8,M,0000*74

I am storing this sentence into a buffer. My task is to send this buffer from ISR to task using Queue.
How to do this exactly.

How to allocate size for queue.

Queue01Handle = xQueueCreate(1,100); /* Create a queue */

How much size I have to create for my message as I will get GPS data for every one second of different size.
$GPGGA,080339.00,1732.61630,N,07821.15740,E,2,08,1.65,584.6,M,-73.8,M,0000*74

This is my ISR Routine
void HAL_UART_RxCpltCallback(UART_HandleTypeDef huart)
{
/
Prevent unused argument(s) compilation warning */
UNUSED(huart);

/*Process the UART */
/*
        Clear the pending interrupt
 */
int txStatus = 0;
char *pGpsSentence;

BaseType_t xHigherPriorityTaskWoken;

switch((uint32_t)huart->Instance)
{
case (uint32_t)USART2 :

		break;

case (uint32_t)USART3 :
		if(GpsUart.RxCount >= 1024)//Overflow judgment
		{
			GpsUart.RxCount = 0;
			memset(GpsUart.RxBuffer,0x00,sizeof(GpsUart.RxBuffer));
			HAL_UART_Transmit(&huartSerial, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);
		}
		else
		{
			switch(GpsUart.RxFrameState)
			{
			case UART_FRAME_IDLE  :
				pGpsSentence = (char *)&GpsUart.RxBuffer;
				memset(GpsUart.RxBuffer,0x00,sizeof(GpsUart.RxBuffer));
				if((GpsUart.RxByte == GpsUart.RxStartByte1) || (GpsUart.RxByte == GpsUart.RxStartByte2))
				{
					GpsUart.RxCount = 0;
					GpsUart.RxBuffer[GpsUart.RxCount++] = GpsUart.RxByte;
					GpsUart.RxFrameState = UART_FRAME_START;
				}
				else
				{
					GpsUart.RxFrameState = UART_FRAME_START;
				}
				break;
			case UART_FRAME_START :

				if((GpsUart.RxByte == GpsUart.RxEndByte1) || (GpsUart.RxByte == GpsUart.RxEndByte2))
				{
					GpsUart.RxBuffer[GpsUart.RxCount++] = GpsUart.RxByte;
					GpsUart.RxFrameState = UART_FRAME_READY;
					txStatus = xQueueSendFromISR(Queue01Handle, &pGpsSentence, &xHigherPriorityTaskWoken);
					if (0 == txStatus)
					{

					}
					else
					{

// portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
}
else
{
GpsUart.RxBuffer[GpsUart.RxCount++] = GpsUart.RxByte;
}
break;

			default :
				GpsUart.RxFrameState = UART_FRAME_IDLE;
				break;
			}
		}
}
HAL_UART_Receive_IT(&huartGps, (uint8_t *)&GpsUart.RxByte, 1); //Restart receive interrupt

}

This is my receiver task

void Receiver1_Task(void argument)
{
/
USER CODE BEGIN Receiver1_Task */
BaseType_t xHigherPriorityTaskWoken;
char *pGpsRxSentence ;
int RxStatus = 0;
pGpsRxSentence = NULL;

	/* Infinite loop */
	for(;;)
	{

		if(pdTRUE == xQueueReceiveFromISR(Queue01Handle,&pGpsRxSentence,&xHigherPriorityTaskWoken))
		{
//			osMutexWait(Mutex01_PrintfHandle,1000);

// printf("%s\r\n",pGpsRxSentence);
// osMutexRelease(Mutex01_PrintfHandle);
}
else
{
/* osMutexWait(Mutex01_PrintfHandle,1000);
printf("No data\r\n ");
osMutexRelease(Mutex01_PrintfHandle); */
}

		/*GpsSync();*/
		osDelay(1);
	}
	/* USER CODE END Receiver1_Task */

}

But when I run this I am going to Hard fault handler.

Queues handle fixed size items as documented. You can‘t transfer variable sized data or items using a queue.
You should use a queue of (sentence) buffer pointers (item size = sizeof(char*)) and signal the (filled) buffer pointer to your task.
BTW in your case it‘d be more efficient and faster to use message buffers.
Depending on how fast the task finishes processing the last sentence it might be a good idea to have 2 or more sentence buffers filled by the ISR following a round-robin scheme to avoid overwriting the sentence buffer by (next) ISR while the task is still processing the buffer. However, this shouldn’t be a real problem with just 1 sentence per second.
If your task needs the length of the sentence you should use a

struct 
{
  char* buffer;
  uint8_t length;
};

as Q item to signal both information to your task and avoid re-parsing of the sentence for the terminator char.

Thanks for the reply. I will try that and get back. Can you please edit the code given above for that as I am new to free rtos.

I’d propose if you rely on Cube just use it as it is. Message buffers were added to FreeRTOS V10. So probably the FreeRTOS version supported by Cube is older and it won‘t compile. I guess in your use case performance doesn‘t really matter.
Also you can try a dead simple signaling of the (1) sentence from ISR to task.
Just use a binary semaphore to signal completion of the sentence given that the task has access to the (static) sentence buffer and the optional length variable.

I use two different methods to move serial data from an ISR to a task. For slower speed serial ports, like the GPS is likely using, I just use a generic serial port driver that puts each character as it arrives in the queue, and the task pulls them out and decodes the message.

For VERY fast channels, the ISR will buffer the data into a global buffer and then signal the task that the buffer has data and it processes it. Note, the buffer is NOT transferred, it is just shared.

If there might be overlap in processing one buffer and getting another, then I will allocate a pool of buffer,s and setup two queues (with buffer pointers only), the first has all the ‘free’ buffers put onto it, and the ISR will get a buffer from this queue as needed, and the second queue the ISR puts buffers into as they are filled, and the task takes from that queue and returns the pointer to the free queue when done.