JZsdk_data_transmisson.c 10.7 KB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

#include "JZsdk_TaskManagement/TaskManagement.h"
#include "JZsdk_Base/JZsdk_Code/JZsdk_Code.h"
#include "JZsdk_Base/JZsdk_FrameComparsion/JZsdk_FrameComparsion.h"
#include "JZsdk_uart/JZsdk_Uart_UartDeal.h"
#include "BaseConfig.h"
#include "Hal_Recv/HalRecv.h"

typedef struct
{
	char Message[1024];	   // 传递的字符串
	int MessageLength;	   // 字符串的长度
	int ResLen;			//剩余长度
	pthread_mutex_t WriteMutex; // 互斥锁
	pthread_mutex_t ReadMutex; // 互斥锁
} JZsdk_data_transmisson;

#define BUFFER_SIZE 128*1024 		//  128k的缓冲区  
static unsigned char DataTransmissonBuffer[BUFFER_SIZE];   //data_transmisson的被动接收缓冲区
static int buffer_head = 0;  //缓冲区的写入标志位
static int buffer_end = 0;   //缓冲区的写出标志位 
static void *JZsdk_hal_data_rece(void *arg);
static void *JZsdk_hal_data_deal(void *arg);
static pthread_mutex_t DataTransmissonLock;  
static int DataTransFlag = JZ_FLAGCODE_OFF; //用于判断初始化完成

/****************
 * 
 * 	计算缓冲区剩余容量
 * 
 * **************/
static int JZsdk_data_transmisson_buffer_GetEmpty()
{
	int empty;

	//后续要找办法处理数据段长度的问题,目前先用大空间存储

	//头在尾后面 说明目前数组缓冲区组成为  空数据 尾巴 实数据 头部 空数据
	if (buffer_head >= buffer_end)
	{
		empty = BUFFER_SIZE - (buffer_head - buffer_end);
	}
	//尾在头后面 说明目前数组缓冲区组成为  实数据 头部 空数据 尾巴  实数据
	else if (buffer_head < buffer_end)
	{
		empty = (buffer_end - buffer_head);
	}

	return empty;
}

/****************
 * 
 * 	池满判断
 * 
 * **************/
static int JZsdk_data_transmisson_buffer_WriteDataEndReset() //池满判断
{
	if (buffer_end >= BUFFER_SIZE)
	{
		buffer_end = 0;
	}
}
static int JZsdk_data_transmisson_buffer_WriteDataHeadReset() //池满判断
{
	if (buffer_head >= BUFFER_SIZE)
	{
		buffer_head = 0;
	}
}

/******************************************************************

	初始化hal口数据接收

******************************************************************/
int JZsdk_data_transmisson_Receive(unsigned char *data, int data_len)
{
	//初始化完成前不能使用
	if (DataTransFlag == JZ_FLAGCODE_OFF)
	{
		return 0 ;
	}

	int temp_lenth = 0;  //临时长度;

	//后续要增加缓冲区大小判断,避免出现问题
	//计算当前缓冲区的剩余容量
	int buffer_empty = JZsdk_data_transmisson_buffer_GetEmpty();
	if (buffer_empty < data_len)
	{
		data_len = buffer_empty;
	}
	
	// 在写入解码前加锁
    pthread_mutex_lock(&DataTransmissonLock); 

	while( (data_len - temp_lenth) > 0)
	{	
		DataTransmissonBuffer[buffer_head] = data [temp_lenth];
		temp_lenth+=1;
		buffer_head+=1;  //池尾后移一组
		JZsdk_data_transmisson_buffer_WriteDataHeadReset() ; //池满判断
	}

	// 在解码数据后解锁
	pthread_mutex_unlock(&DataTransmissonLock);
}

/******************************************************************

	初始化hal口数据接收初始化

******************************************************************/
int JZsdk_data_transmisson_Receive_Init()
{
	int ret = 0;
	pthread_t Uart_rece_task;

	pthread_attr_t task_attribute;										   // 线程属性
	pthread_attr_init(&task_attribute);									   // 初始化线程属性
	pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); // 设置线程属性

	

	JZsdk_data_transmisson *parameter = (JZsdk_data_transmisson *)malloc(sizeof(JZsdk_data_transmisson));
	parameter->MessageLength = 0;
	memset(parameter->Message, 0, sizeof(parameter->Message));

	pthread_mutex_init(&DataTransmissonLock, NULL);   //初始化锁
	pthread_mutex_init(&parameter->WriteMutex, NULL);
	pthread_mutex_init(&parameter->ReadMutex, NULL);

	// 创建串口数据接收线程
	pthread_t receiveThread;
	pthread_t SerialDealThread;
	pthread_attr_t task_attribute1;											// 线程属性
	pthread_attr_t task_attribute2;											// 线程属性
	pthread_attr_setdetachstate(&task_attribute1, PTHREAD_CREATE_DETACHED); // 设置线程分离属性
	pthread_attr_setdetachstate(&task_attribute2, PTHREAD_CREATE_DETACHED); // 设置线程分离属性

	pthread_attr_init(&task_attribute1);
	pthread_attr_init(&task_attribute2);

	if (pthread_create(&receiveThread, &task_attribute1, JZsdk_hal_data_rece, parameter) != 0)
	{
		JZSDK_LOG_ERROR("Failed to create receive thread");
		return 1;
	}

	// 创建串口数据处理线程
	if (pthread_create(&SerialDealThread, &task_attribute2, JZsdk_hal_data_deal, parameter) != 0)
	{
		JZSDK_LOG_ERROR("Failed to create receive thread");
		return 1;
	}

	DataTransFlag = JZ_FLAGCODE_ON;

	JZSDK_LOG_INFO("hal数据传输模块初始化完成");
}


/***
 *
 * 	数据读取函数
 *  获取数据的数组str
 * 	最多可以获取max_get_len的长度
 * ***/
static int Buffer_get_data(unsigned char *str, int max_get_len)
{
	int return_len; //返回的长度

	//头在尾后面 说明目前数组缓冲区组成为  空数据 尾巴 实数据 头部 空数据
	if (buffer_head >= buffer_end)
	{
		if (max_get_len >= (buffer_head-buffer_end))
		{
			return_len = (buffer_head-buffer_end);
			memcpy(str, &DataTransmissonBuffer[buffer_end], return_len);
			buffer_end +=return_len;
			JZsdk_data_transmisson_buffer_WriteDataEndReset();
			return return_len;
		}
		else
		{
			return_len = max_get_len;
			memcpy(str, &DataTransmissonBuffer[buffer_end], return_len);
			buffer_end +=return_len;
			JZsdk_data_transmisson_buffer_WriteDataEndReset();
			return return_len;			
		}
	}

	//尾在头后面 说明目前数组缓冲区组成为  实数据 头部 空数据 尾巴  实数据
	else if (buffer_head < buffer_end)
	{
		if (max_get_len >= ( (BUFFER_SIZE-buffer_end) + buffer_head) )
		{
			return_len = ( (BUFFER_SIZE-buffer_end) + buffer_head);
			memcpy(str, &DataTransmissonBuffer[buffer_end], (BUFFER_SIZE-buffer_end));

			memcpy(str + (BUFFER_SIZE-buffer_end), &DataTransmissonBuffer[0], buffer_head);
			buffer_end = buffer_head;
			JZsdk_data_transmisson_buffer_WriteDataEndReset();
			return return_len;	
		}
		else if(max_get_len < ( (BUFFER_SIZE-buffer_end) + buffer_head) )
		{
			// 实数据 头部 空数据 尾巴  大于接收区的实数据
			if (max_get_len <= (BUFFER_SIZE-buffer_end) )
			{
				return_len = max_get_len;
				memcpy(str, &DataTransmissonBuffer[buffer_end], return_len);
				buffer_end+=max_get_len;
				JZsdk_data_transmisson_buffer_WriteDataEndReset();
				return return_len;	
			}
			// 实数据 头部 空数据 尾巴  小于接收区的实数据
			else
			{
				return_len = max_get_len;
				memcpy(str, &DataTransmissonBuffer[buffer_end], (BUFFER_SIZE-buffer_end));

				memcpy(str, &DataTransmissonBuffer[0], (max_get_len - (BUFFER_SIZE-buffer_end) ) );
				buffer_end = (max_get_len - (BUFFER_SIZE-buffer_end) );
				JZsdk_data_transmisson_buffer_WriteDataEndReset();
				return return_len;	
			}
			
		}
	}
	
	
	return return_len;
}	

/***
 *
 * 	数据接收线程
 *
 * ***/
static void *JZsdk_hal_data_rece(void *arg)
{

	JZsdk_data_transmisson *args = (JZsdk_data_transmisson *)arg;

	memset(args->Message, 0, sizeof(args->Message)); // 清空接收数组
	args->ResLen = 0;
	args->MessageLength = 0;

	int data_len;
	int data_len2;
	
	while (1)
	{        
		// 检查fs_read套接字是否有数据
		if (buffer_head == buffer_end)
		{
			delayMs(1);
	
			// 超时
			continue;
		}

		// 如果有数据就加锁
		pthread_mutex_lock(&args->WriteMutex);

		// 读取串口内容
		int bytesRead = Buffer_get_data(&(args->Message[args->ResLen]), (sizeof(args->Message) - args->ResLen));
		printf("bytesRead %d\n",bytesRead);

		if (bytesRead > 0) 
		{
			args->MessageLength = args->ResLen + bytesRead;

			// data_len+=bytesRead;
			// data_len2+=args->MessageLength;
			// printf("当前接收长度%d  bytesRead%d bmessage%d reslen%d\n",data_len,bytesRead,data_len2,args->ResLen);

			// JZSDK_LOG_INFO("从串口读取到,长度%d",(args->MessageLength-args->ResLen));

			// for (int i = 0; i < (args->MessageLength-args->ResLen); i++)
			// {
			// 	JZSDK_LOG_OUTPUTHEX("%s",&args->Message[i+args->ResLen]);
			// }

			args->ResLen = 0;
		} 
		else if (bytesRead == 0) 
		{
			// 串口关闭或者无数据可读
			JZSDK_LOG_ERROR("hal数据传输,读取数据为空");
			args->MessageLength = 0;
			args->ResLen = 0;
			memset(&(args->Message[0]), 0, sizeof(args->Message));
		} 
		else 
		{
			// 读取错误发生
			JZSDK_LOG_ERROR("hal数据传输读取错误");
			args->MessageLength = 0;
			args->ResLen = 0;
			memset(&(args->Message[0]), 0, sizeof(args->Message));
		}

		// 通知线程
		pthread_mutex_unlock(&args->ReadMutex); // 解锁

		delayMs(3); // 加多了可能导致实时播放难恢复,以及声音间隔  3ms32字节 会向上约1个3ms opus一帧80字节
	}

}

/***
 *
 * 	串口处理线程
 *
 * ***/
// 串口数据处理线程函数
static void *JZsdk_hal_data_deal(void *arg)
{
	JZsdk_data_transmisson *args = (JZsdk_data_transmisson *)arg;

	static int ResidualLength = 0; // 未处理数据长度

	while (1)
	{

		// 加锁
		pthread_mutex_lock(&args->ReadMutex);

		// data_len+=args->MessageLength;
		// printf("当前处理长度%d\n",data_len);

		if (args->MessageLength > 0)
		{

			//清除错误的多余半帧
			//前面有帧的长度
			if(args->ResLen != 0)
			{
				//存在第一帧,同时第二轮的数据开头是帧头,则清空前半段第一帧
				if (   (args->Message[args->ResLen ] == 0x5A) 
					&& (args->Message[args->ResLen + 1] == 0x5A) 
					&& (args->Message[args->ResLen + 2] == 0x77) )  
				{
					int temp_num;
					temp_num = args->MessageLength - args->ResLen;
					if (temp_num < 0)
					{
						temp_num = 0;
					}
		
					memcpy(args->Message, &(args->Message[args->ResLen]), temp_num);
					memset(&args->Message[temp_num], 0, (args->MessageLength - temp_num));
					args->MessageLength = temp_num;
					args->ResLen = 0;

					JZSDK_LOG_ERROR("串口上一帧为不完全帧,舍弃该帧操作");
				}
			}
			
			// 处理数据
			ResidualLength = HalRecv_type1_PreliminaryScreeningOfData(args->Message, args->MessageLength, HAL_DATA_TRANSMISSION);
			//如果还有剩余的长度
			if (ResidualLength != 0)
			{
				memcpy(args->Message, &(args->Message[args->MessageLength - ResidualLength]), ResidualLength);
				memset(&(args->Message[ResidualLength]), 0, (sizeof(args->Message) - ResidualLength));
				args->MessageLength = 0;
				args->ResLen = ResidualLength;
			}
			else
			{
				memset(args->Message, 0, sizeof(args->Message));
				args->MessageLength = 0;
				args->ResLen = 0;
			}

		}
		else
		{
			memset(args->Message, 0, sizeof(args->Message));
			args->MessageLength = 0;
			args->ResLen = 0;
		}

		pthread_mutex_unlock(&args->WriteMutex); // 解锁
	}
}