补充逻辑,加入保护时间,通信建立了后接收端在此时间内不能发起通信
This commit is contained in:
parent
4fb7ee7edb
commit
540c3e1fca
68
tcl.c
68
tcl.c
@ -20,7 +20,7 @@
|
|||||||
#define CLIENT_RETRY_PERIOD_MS (MIN_TR_PERIOD_MS + 1000 * 10) // 客户端重试时间间隔
|
#define CLIENT_RETRY_PERIOD_MS (MIN_TR_PERIOD_MS + 1000 * 10) // 客户端重试时间间隔
|
||||||
#define MAX_RETRY_CNT 3
|
#define MAX_RETRY_CNT 3
|
||||||
#define RING_BUFFER_SIZE (1024 * 3)
|
#define RING_BUFFER_SIZE (1024 * 3)
|
||||||
#define FRAME_SIZE_MAX (200)
|
#define MAX_FRAME_LENGTH (200)
|
||||||
|
|
||||||
/// @brief 主从模式,主机拥有更高优先级
|
/// @brief 主从模式,主机拥有更高优先级
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -41,22 +41,23 @@ typedef enum
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
ERR_OK = 0,
|
ERR_OK = 0,
|
||||||
|
ERR_NOK,
|
||||||
|
ERR_TIMEOUT,
|
||||||
ERR_HEADER,
|
ERR_HEADER,
|
||||||
ERR_TAIL,
|
ERR_TAIL,
|
||||||
ERR_CRC,
|
ERR_CRC,
|
||||||
ERR_TIMEOUT,
|
ERR_LENGTH,
|
||||||
ERR_UNKNOWN,
|
ERR_NREADY
|
||||||
ERR_NOK
|
|
||||||
} err_t;
|
} err_t;
|
||||||
|
|
||||||
static devmode_t devMode = HOST_MODE;
|
static devmode_t devMode = HOST_MODE;
|
||||||
static devstatus_t curMode = R_MODE;
|
static devstatus_t curMode = R_MODE;
|
||||||
static devstatus_t tarMode = R_MODE;
|
static devstatus_t tarMode = R_MODE;
|
||||||
volatile int trySwt = 0; // 是否尝试切换到发送模式
|
volatile int isOK2Swt = 1; // 是否尝试切换到发送模式
|
||||||
static devstatus_t tarDevMode = R_MODE; // 目标端工作模式
|
static devstatus_t tarDevMode = R_MODE; // 目标端工作模式
|
||||||
static MultiTimer retryTimer, timeoutTimer; // 重试定时器、超时定时器
|
static MultiTimer retryTimer, timeoutTimer; // 重试定时器、超时定时器
|
||||||
static int rxNewDataFlag = 0;
|
static int rxNewDataFlag = 0;
|
||||||
static uint8_t lstLineRxData[FRAME_SIZE_MAX]; // 透传缆最后一个接收到的数据
|
static uint8_t lstLineRxData[MAX_FRAME_LENGTH]; // 透传缆最后一个接收到的数据
|
||||||
static uint8_t lstLineRxDataLen = 0; // 透传缆最后一个接收到的数据长度
|
static uint8_t lstLineRxDataLen = 0; // 透传缆最后一个接收到的数据长度
|
||||||
static int isTimeOut = 0;
|
static int isTimeOut = 0;
|
||||||
static Node *userRxBuffList = NULL; // user端接收缓冲链表
|
static Node *userRxBuffList = NULL; // user端接收缓冲链表
|
||||||
@ -168,10 +169,7 @@ uint64_t getPlatformTicks(void)
|
|||||||
// Callback functions for the timers
|
// Callback functions for the timers
|
||||||
void retryTimerCallback(MultiTimer *timer, void *userData)
|
void retryTimerCallback(MultiTimer *timer, void *userData)
|
||||||
{
|
{
|
||||||
if (tarDevMode == R_MODE && curMode == R_MODE && tarMode == T_MODE) // 两端为收方可发起请求
|
isOK2Swt = 1;
|
||||||
{
|
|
||||||
trySwt = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Timer 1 fired at %lu ms\n", getPlatformTicks());
|
printf("Timer 1 fired at %lu ms\n", getPlatformTicks());
|
||||||
}
|
}
|
||||||
@ -200,11 +198,16 @@ uint8_t bccCRC(uint8_t *data, uint8_t len)
|
|||||||
/// @brief 检查数据有效性
|
/// @brief 检查数据有效性
|
||||||
/// @param data 待校验数据
|
/// @param data 待校验数据
|
||||||
/// @param len 数据长度
|
/// @param len 数据长度
|
||||||
/// @return 0->有效 1->帧头无效 2->帧尾无效 3->校验位无效
|
/// @return 0->有效
|
||||||
err_t chkDataValid(uint8_t *data, uint8_t len)
|
err_t chkDataValid(uint8_t *data, uint8_t len)
|
||||||
{
|
{
|
||||||
// 按帧发送数据
|
// 按帧发送数据
|
||||||
// 判断帧的完整性及校验位
|
// 判断帧的完整性及校验位
|
||||||
|
if (len > MAX_FRAME_LENGTH)
|
||||||
|
{
|
||||||
|
return ERR_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
if (data[0] != 0x5A || data[1] != 0xA5) // 帧头校验
|
if (data[0] != 0x5A || data[1] != 0xA5) // 帧头校验
|
||||||
{
|
{
|
||||||
return ERR_HEADER;
|
return ERR_HEADER;
|
||||||
@ -228,13 +231,23 @@ err_t chkDataValid(uint8_t *data, uint8_t len)
|
|||||||
/// @param len
|
/// @param len
|
||||||
void userRecDataCallback(uint8_t *data, uint8_t len)
|
void userRecDataCallback(uint8_t *data, uint8_t len)
|
||||||
{
|
{
|
||||||
if (chkDataValid(data, len))
|
//等待时间内不能发送数据
|
||||||
|
if (!isOK2Swt)
|
||||||
{
|
{
|
||||||
|
userTransmitData(ERR_NREADY,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t rst= chkDataValid(data, len);
|
||||||
|
if (rst == ERR_OK)
|
||||||
|
{
|
||||||
|
//校验通过则加入待发列表
|
||||||
appendNode(&userRxBuffList, data, len);
|
appendNode(&userRxBuffList, data, len);
|
||||||
|
//由发送函数反馈发送结果
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
userTransmitData(CMD_ACK_NOK, 1);
|
//校验不通过立即反馈
|
||||||
|
userTransmitData(rst, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +273,7 @@ err_t getACK(int timeOut)
|
|||||||
{
|
{
|
||||||
if (isTimeOut)
|
if (isTimeOut)
|
||||||
{
|
{
|
||||||
return ERR_NOK;
|
return ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rxNewDataFlag)
|
if (rxNewDataFlag)
|
||||||
@ -318,6 +331,10 @@ void handleTR()
|
|||||||
{
|
{
|
||||||
lineTransmitData(CMD_ACK_OK, 1);
|
lineTransmitData(CMD_ACK_OK, 1);
|
||||||
userTransmitData(lstLineRxData, lstLineRxDataLen);
|
userTransmitData(lstLineRxData, lstLineRxDataLen);
|
||||||
|
//每次建立通信后10s内收端不能发起通信
|
||||||
|
isOK2Swt = 0;
|
||||||
|
multiTimerStop(&retryTimer);
|
||||||
|
multiTimerStart(&retryTimer, 10*1000, retryTimerCallback, NULL); // Start timer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -327,14 +344,14 @@ void handleTR()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 有数据需要发送
|
// 有数据需要发送
|
||||||
if (getListSize(userRxBuffList) > 0)
|
if (isOK2Swt && getListSize(userRxBuffList) > 0)
|
||||||
{
|
{
|
||||||
// 发送数据
|
// 发送数据
|
||||||
uint8_t reTryCnt = 0;
|
uint8_t reTryCnt = 0;
|
||||||
err_t lstState = ERR_OK;
|
err_t lstState = ERR_OK;
|
||||||
while (userRxBuffList != NULL) // 遍历链表
|
while (userRxBuffList != NULL) // 遍历链表
|
||||||
{
|
{
|
||||||
if (lstState != ERR_OK)
|
if (lstState == ERR_NOK)
|
||||||
{
|
{
|
||||||
if (!isTimeOut)
|
if (!isTimeOut)
|
||||||
{
|
{
|
||||||
@ -350,12 +367,21 @@ void handleTR()
|
|||||||
lineTransmitData(userRxBuffList->data, userRxBuffList->size);
|
lineTransmitData(userRxBuffList->data, userRxBuffList->size);
|
||||||
if (USING_ACK == 1) // 使用ACK
|
if (USING_ACK == 1) // 使用ACK
|
||||||
{
|
{
|
||||||
if (getACK(userRxBuffList->size * 10) == ERR_OK) // ACK正常
|
err_t rst = getACK(userRxBuffList->size * 10);
|
||||||
|
if (rst == ERR_TIMEOUT)
|
||||||
|
{
|
||||||
|
lstState = ERR_TIMEOUT;
|
||||||
|
userTransmitData(ERR_TIMEOUT, 1);
|
||||||
|
// 超时错误大概率是透传缆损坏,不主动重试,终止发送
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (rst == ERR_OK) // ACK正常
|
||||||
{
|
{
|
||||||
lstState = ERR_OK;
|
lstState = ERR_OK;
|
||||||
userRxBuffList = userRxBuffList->next; // 正常则移动指针
|
userRxBuffList = userRxBuffList->next; // 正常则移动指针
|
||||||
deleteFirstNode(&userRxBuffList);
|
deleteFirstNode(&userRxBuffList);
|
||||||
userTransmitData(CMD_ACK_OK, 1);
|
// userTransmitData(CMD_ACK_OK, 1);
|
||||||
|
userTransmitData(ERR_OK, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -365,11 +391,13 @@ void handleTR()
|
|||||||
{
|
{
|
||||||
reTryCnt = 0;
|
reTryCnt = 0;
|
||||||
lstState = ERR_OK;
|
lstState = ERR_OK;
|
||||||
userRxBuffList = userRxBuffList->next; // 正常则移动指针
|
userRxBuffList = userRxBuffList->next; // 次数超出阈值则移动指针
|
||||||
deleteFirstNode(&userRxBuffList);
|
deleteFirstNode(&userRxBuffList);
|
||||||
userTransmitData(CMD_ACK_NOK, 1);
|
// userTransmitData(CMD_ACK_NOK, 1);
|
||||||
|
userTransmitData(ERR_NOK,1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//失败的原因可能是数据碰撞,需要根据优先级等待不同的时间后进行重试
|
||||||
multiTimerStop(&timeoutTimer);
|
multiTimerStop(&timeoutTimer);
|
||||||
multiTimerStart(&timeoutTimer, time2Retry, timeOutTimerCallback, NULL); // Start timer
|
multiTimerStart(&timeoutTimer, time2Retry, timeOutTimerCallback, NULL); // Start timer
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user