作者 ookk303

2.12

/*********************************
*
* 极至接收数据处理
* 数据类型1
* 用于串口协议,大疆多通道接收协议
*
* ****************************************/
#include <stdio.h>
#include "JZsdkLib.h"
#include "BaseConfig.h"
/***************
*
*
* 极至串口协议的数据初步筛选
* 用于清空无效数据
* 以及将有效数据提取出来,放置到后续处理函数中
* 输入要 处理的原始数据data 以及 数据长度DataLen 还有输入的接口
* 返回值:未处理的长度数据
*
* 返回后在
* ********************/
int HalRecv_tpye1_PreliminaryScreeningOfData(unsigned char *Data, unsigned int DataLen, int Port)
{
int ResidualLength = 0; // 剩余数据长度
switch (Port)
{
case UART_DEV_1:
//JZSDK_LOG_INFO("串口-设备1号,接受到数据+未处理数据的长度len: %d", DataLen);
break;
case UART_DEV_2:
//JZSDK_LOG_INFO("串口-设备2号,接受到数据+未处理数据的长度len: %d", DataLen);
break;
case UART_4G:
//JZSDK_LOG_INFO("串口-4G模块,接受到数据+未处理数据的长度len: %d", DataLen);
break;
case HAL_DATA_TRANSMISSION:
//JZSDK_LOG_INFO("hal-数据传输,接受到数据+未处理数据的长度len: %d", DataLen);
break;
/********** 未报备的接口 ************/
default:
ResidualLength = 0;
return ResidualLength;
break;
}
//确保有数据传输进来
if (DataLen <= 0)
{
ResidualLength = 0;
return ResidualLength;
}
int HaveReadLen = 0; // 已读长度
int HaveDealLen = 0; // 已处理长度
int FrameFlag = 0x00; // 帧标志
int FrameLen = 0;
//将数据提取出来
for (HaveReadLen = 0; HaveReadLen <= (DataLen - 3); )
{
//查找是否存在 帧头
switch (Data[HaveReadLen])
{
case 0x5A:
{
if (Data[HaveReadLen + 1] == 0x5A && Data[HaveReadLen + 2] == 0x77)
{
FrameFlag = 0x5A;
}
else
{
FrameFlag = 0x00;
}
break;
}
case 0x5B:
{
if (Data[HaveReadLen + 1] == 0x5B && Data[HaveReadLen + 2] == 0x77)
{
FrameFlag = 0x5B;
}
else
{
FrameFlag = 0x00;
}
break;
}
case 0x6A:
{
if (Data[HaveReadLen + 1] == 0x6A && Data[HaveReadLen + 2] == 0x77)
{
FrameFlag = 0x6A;
}
else
{
FrameFlag = 0x00;
}
break;
}
case 0x6B:
{
if (Data[HaveReadLen + 1] == 0x6B && Data[HaveReadLen + 2] == 0x77)
{
FrameFlag = 0x6B;
}
else
{
FrameFlag = 0x00;
}
}
default:
FrameFlag = 0x00;
break;
}
if (FrameFlag == 0x00)
{
if (HaveReadLen >= (DataLen - 5))
{
//JZSDK_LOG_INFO("没有找到帧头");
}
HaveReadLen++;
continue;
}
//如果有帧头,则先判断前面有没有多余的数据残留,并将其移除
if (HaveReadLen > HaveDealLen)
{
//JZSDK_LOG_INFO("残余处理%d",(HaveReadLen - HaveDealLen));
HaveDealLen = HaveReadLen;
}
//检查帧长度是否超出数据剩余的内容
FrameLen = (((int)Data[HaveReadLen+3]) << 8) + (int)Data[HaveReadLen+4];
if (FrameLen > (DataLen - HaveReadLen))
{
//JZSDK_LOG_DEBUG("当前帧长度位长度%d 超出剩余帧长度%d ",FrameLen,(getbufLen - HaveReadLen));
// 直接跳出for循环
break;
}
//检查帧长度是否为0,避免卡死接收串口
if (FrameLen == 0)
{
JZSDK_LOG_ERROR("严重错误,接收到的帧出现长度为空");
//直接清空接收的数组
return 0;
}
//以上检查都没问题,则正常输出帧
//JZSDK_LOG_INFO("正常输出帧%d",FrameLen);
//UartDeal_Recv_Ouput(type, Uart_fd, &getbuf[HaveReadLen], FrameLen);
HaveReadLen = HaveReadLen + FrameLen;
HaveDealLen = HaveReadLen;
JZSDK_LOG_INFO("Prot:%x f_len%d h_r%d [h_r]:%x get%d",Port,FrameLen ,HaveReadLen, getbuf[HaveReadLen-1], DataLen);
FrameLen = 0;
FrameFlag = 0;
}
// 如果没有数据残留了
if (HaveDealLen >= DataLen)
{
//printf("HaveReadLen:%d HaveDealLen%d getbufLen:%d\n",HaveReadLen,HaveDealLen,getbufLen);
ResidualLength = 0;
return ResidualLength;
}
else
{
}
return ResidualLength;
}
static T_JZsdkReturnCode
\ No newline at end of file
... ...
... ... @@ -17,15 +17,19 @@
struct UartDev_UseFlag
{
int UartDev_DEV1 ;
int UartDev_DEV2 ;
int UartDev_DEV2 ;
int UartDev_DEV3 ;
int UartDev_DEV4 ;
int UartDev_4G ;
};
static struct UartDev_UseFlag UartDevUseFlag = {JZ_FLAGCODE_OFF, JZ_FLAGCODE_OFF, JZ_FLAGCODE_OFF};
static struct UartDev_UseFlag UartDevUseFlag = {JZ_FLAGCODE_OFF, JZ_FLAGCODE_OFF, JZ_FLAGCODE_OFF, JZ_FLAGCODE_OFF,JZ_FLAGCODE_OFF};
/****************
*
* 回复串口是否有被调用
* 用于状态同步时,是否需要通知该设备
*
* *************/
int JZsdk_Get_UartDev_UseFlag(int UART_DEV_NAME)
... ... @@ -47,6 +51,7 @@ int JZsdk_Get_UartDev_UseFlag(int UART_DEV_NAME)
/**************
*
* 串口部分初始化
* 按默认参数对串口进行初始化
*
* *********/
int JZsdk_Uart_Init(int UART_DEV_NAME)
... ... @@ -112,7 +117,8 @@ int JZsdk_Uart_BitRateChange(int UART_DEV_NAME, int BitRate)
/**************
*
* 串口部分串口再注册
* 串口部分
* 串口再注册函数
*
* *********/
int JZsdk_Uart_SecondInit(int UART_DEV_NAME, int BitRate)
... ...
... ... @@ -24,7 +24,7 @@ typedef struct
{
int UartFd; // 串口识别符
int UartDevName; //串口名
char Message[1024]; // 传递的字符串
unsigned char Message[2048]; // 传递的字符串
int MessageLength; // 字符串的长度
int ResLen; //剩余长度
pthread_mutex_t WriteMutex; // 互斥锁
... ... @@ -56,14 +56,11 @@ static int Deal_Thread = JZ_FLAGCODE_OFF; //用于判断处理线程是否成功
static void *UartDeal_rece(void *arg);
static void *UartDeal_deal(void *arg);
/*********************
*
* 串口接收线程
*
* *****************/
/******************************************************************
初始化串口接收和处理
传入 串口描述符 和 串口名
******************************************************************/
int JZsdk_Uart_UartDeal_Receive(int Uart_fd, int Uart_Dev_name)
... ... @@ -75,17 +72,26 @@ int JZsdk_Uart_UartDeal_Receive(int Uart_fd, int Uart_Dev_name)
pthread_attr_init(&task_attribute); // 初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); // 设置线程属性
//根据串口名,将串口描述符赋值给对应的串口,并打开对应的线程开关
if (Uart_Dev_name == UART_DEV_1)
{
Uart_DEV1_fd = Uart_fd;
Uart_DEV1_Switch = JZ_FLAGCODE_ON;
}
else if (Uart_Dev_name == UART_DEV_2)
{
Uart_DEV2_fd = Uart_fd;
Uart_DEV2_Switch = JZ_FLAGCODE_ON;
}
else if (Uart_Dev_name == UART_4G)
{
Uart_4G_fd = Uart_fd;
Uart_4G_Switch = JZ_FLAGCODE_ON;
}
else
{
JZSDK_LOG_ERROR("Uart_Dev_name error");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
s_SerialArgs *parameter = (s_SerialArgs *)malloc(sizeof(s_SerialArgs));
... ... @@ -109,6 +115,8 @@ int JZsdk_Uart_UartDeal_Receive(int Uart_fd, int Uart_Dev_name)
pthread_attr_init(&task_attribute1);
pthread_attr_init(&task_attribute2);
// 创建串口接收线程
if (pthread_create(&receiveThread, &task_attribute1, UartDeal_rece, parameter) != 0)
{
JZSDK_LOG_ERROR("Failed to create receive thread");
... ... @@ -129,39 +137,38 @@ int JZsdk_Uart_UartDeal_Receive(int Uart_fd, int Uart_Dev_name)
* ***/
static void *UartDeal_rece(void *arg)
{
s_SerialArgs *args = (s_SerialArgs *)arg;
struct timeval timeout; // 超时时间
fd_set fs_read;
//获取串口描述符
int Uart_fd = args->UartFd;
FD_ZERO(&fs_read);
FD_SET(Uart_fd, &fs_read);
memset(args->Message, 0, sizeof(args->Message)); // 清空接收数组
//清空接收数组与初始化配置
memset(args->Message, 0, sizeof(args->Message));
args->ResLen = 0;
args->MessageLength = 0;
int *TheadSwtch = NULL;
if (args->UartDevName == UART_4G)
{
TheadSwtch = &Uart_4G_Switch;
Uart_4G_Switch = JZ_FLAGCODE_ON;
}
else if (args->UartDevName == UART_DEV_1)
{
TheadSwtch = &Uart_DEV1_Switch;
Uart_DEV1_Switch = JZ_FLAGCODE_ON;
}
else if (args->UartDevName == UART_DEV_2)
{
TheadSwtch = &Uart_DEV2_Switch;
Uart_DEV2_Switch = JZ_FLAGCODE_ON;
}
// 根据设备名称设置相应的线程开关
int *TheadSwtch = NULL; //线程开关
switch(args->UartDevName)
{
case UART_4G:
TheadSwtch = &Uart_4G_Switch;
break;
case UART_DEV_1:
TheadSwtch = &Uart_DEV1_Switch;
break;
case UART_DEV_2:
TheadSwtch = &Uart_DEV2_Switch;
break;
default:
return NULL; // 或者处理未知设备的情况
}
while (*TheadSwtch)
{
//重置处理时间
FD_ZERO(&fs_read);
FD_SET(Uart_fd, &fs_read);
... ... @@ -170,17 +177,20 @@ static void *UartDeal_rece(void *arg)
// 检查fs_read套接字是否有数据
int ret = select(Uart_fd + 1, &fs_read, NULL, NULL, &timeout);
if (ret < 0) {
// 发生错误
JZSDK_LOG_ERROR("串口select出错");
// 发生错误
if (ret < 0)
{
//清空缓冲区
JZSDK_LOG_ERROR("uart select error");
args->MessageLength = 0;
args->ResLen = 0;
memset(&(args->Message[0]), 0, sizeof(args->Message));
delayMs(3);
continue;
} else if (ret == 0)
}
// 超时
else if (ret == 0)
{
// 超时
continue;
}
... ... @@ -189,8 +199,11 @@ static void *UartDeal_rece(void *arg)
// 读取串口内容
int bytesRead = read(Uart_fd, &(args->Message[args->ResLen]), (sizeof(args->Message) - args->ResLen));
//正常读取到数据
if (bytesRead > 0)
{
//计算当前的数据长度
args->MessageLength = args->ResLen + bytesRead;
// data_len+=bytesRead;
... ... @@ -204,12 +217,14 @@ static void *UartDeal_rece(void *arg)
// JZSDK_LOG_OUTPUTHEX("%s",&args->Message[i+args->ResLen]);
// }
// 更新剩余长度
args->ResLen = 0;
}
//读取到数据为空
else if (bytesRead == 0)
{
// 串口关闭或者无数据可读
JZSDK_LOG_ERROR("串口读取数据为空");
JZSDK_LOG_ERROR("Error reading from serial port is empty");
args->MessageLength = 0;
args->ResLen = 0;
memset(&(args->Message[0]), 0, sizeof(args->Message));
... ... @@ -227,12 +242,13 @@ static void *UartDeal_rece(void *arg)
//pthread_cond_signal(&args->cond);
pthread_mutex_unlock(&args->ReadMutex); // 解锁
// 添加适当延时,确保接收缓冲区完全填满
// 添加适当延时,确保接收缓冲区有足够的数据
delayMs(3); // 加多了可能导致实时播放难恢复,以及声音间隔 3ms32字节 会向上约1个3ms opus一帧80字节
}
//注销相关
Recv_Thread = JZ_FLAGCODE_OFF;
// 通知线程
//pthread_cond_signal(&args->cond);
pthread_mutex_unlock(&args->WriteMutex); // 解锁
... ... @@ -252,24 +268,22 @@ static void *UartDeal_deal(void *arg)
static int ResidualLength = 0; // 未处理数据长度
int *TheadSwtch = NULL;
if (args->UartDevName == UART_4G)
{
TheadSwtch = &Uart_4G_Switch;
Uart_4G_Switch = JZ_FLAGCODE_ON;
}
else if (args->UartDevName == UART_DEV_1)
{
TheadSwtch = &Uart_DEV1_Switch;
Uart_DEV1_Switch = JZ_FLAGCODE_ON;
}
else if (args->UartDevName == UART_DEV_2)
{
TheadSwtch = &Uart_DEV2_Switch;
Uart_DEV2_Switch = JZ_FLAGCODE_ON;
}
//int data_len = 0;
// 根据设备名称设置相应的线程开关
int *TheadSwtch = NULL; //线程开关
switch(args->UartDevName)
{
case UART_4G:
TheadSwtch = &Uart_4G_Switch;
break;
case UART_DEV_1:
TheadSwtch = &Uart_DEV1_Switch;
break;
case UART_DEV_2:
TheadSwtch = &Uart_DEV2_Switch;
break;
default:
return NULL; // 或者处理未知设备的情况
}
while (*TheadSwtch)
{
... ... @@ -283,45 +297,22 @@ static void *UartDeal_deal(void *arg)
// 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 = UartDeal_Recv_interface(0, args->UartFd, args->Message, args->MessageLength);
//如果还有剩余的长度
if (ResidualLength != 0)
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
else //清空一次缓冲区
{
memset(args->Message, 0, sizeof(args->Message));
args->MessageLength = 0;
... ... @@ -329,6 +320,8 @@ static void *UartDeal_deal(void *arg)
}
}
//如果不存在数据 或 存在异常 ,则顺便清空一次缓冲区
else
{
memset(args->Message, 0, sizeof(args->Message));
... ... @@ -344,6 +337,30 @@ static void *UartDeal_deal(void *arg)
JZSDK_LOG_WARN("串口处理线程被关闭");
}
/********************************************************************************************************************
*
*
* 分割线
*
*
**********************************************************************************************************************/
/*
数据排出函数
... ... @@ -824,13 +841,12 @@ static void *CloseUart(void *arg)
return 0;
}
//直到某个串口达成了关闭,这里不能明确到判断哪个串口关闭,但是识别第一个关闭的串口
while ( (Recv_Thread != JZ_FLAGCODE_OFF) && (Deal_Thread != JZ_FLAGCODE_OFF))
{
delayMs(1);
}
delayMs(100);
//保证全部注销后
JZSDK_LOG_INFO("串口注销完毕");
... ...