...
|
...
|
@@ -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("串口注销完毕");
|
|
|
|
...
|
...
|
|