📄 hl_serve.c
字号:
#include "Holley_ext.h"
/************************************************************************/
/* 本函数从缓冲区 HL_Buffered_Data 数据结构中查找第一个 */
/* 有效的数据帧, 并将查找到的数据帧保存到指定的位置 */
/* 参数 */
/* pBuf 指向缓冲区的指针 */
/* pucData 查找到的数据帧存放位置 */
/* 返回值 */
/* int8u 查找到的数据帧的长度. 如果没有查找到,则返回 0 */
/* 其他说明 */
/* 1. 对于 UART 数据, 在将数据复制到 pucData 时, 去掉帧头帧尾 */
/* 2. 数据在保存到 HL_Buffered_Data 之前, 已经进行了校验, 因此不必 */
/* 在本函数中再次校验 */
/************************************************************************/
int8u Get_First_Valid_Frame( HL_Buffered_Data * pBuf, int8u * pucData )
{
int8u ucLength = 0;
int16u uiRear;
if ( pBuf->uiValid_Frames == 0 ) // 此时不能将 pBuf 清除,因为可能正在接收新数据帧
return 0;
if ( pBuf->uiStart_Of_First_Frame + 1 == HL_BUFFER_SIZE )
ucLength= pBuf->acBuffer[0];
else
ucLength= pBuf->acBuffer[pBuf->uiStart_Of_First_Frame+1]; // 获得帧长度
ucLength += 4;
uiRear = HL_BUFFER_SIZE - pBuf->uiStart_Of_First_Frame;
if ( uiRear >= ucLength )
{
MEMCOPY ( pucData, pBuf->acBuffer + pBuf->uiStart_Of_First_Frame, ucLength );
}
else
{
MEMCOPY ( pucData, pBuf->acBuffer + pBuf->uiStart_Of_First_Frame, uiRear );
MEMCOPY ( pucData + uiRear, pBuf->acBuffer, ucLength-uiRear );
}
ucLength -= 4;
MEMCOPY ( pucData, pucData+2, ucLength ); // 去掉帧头帧尾
return ucLength;
}
/************************************************************************/
/* 检测数据帧是否符合帧格式 */
/* 参数 */
/* pBuf 要检查的数据缓冲区指针 */
/* 返回值 */
/* TRUE 数据符合帧格式 */
/* FALSE 数据不符合帧格式 */
/* 其他说明 */
/* 1. 仅在 SINK 端使用 HL_Buffered_Data 来缓存 UART 数据, 因此 */
/* 数据帧最大长度不能超过 HL_UART_MAX_FRAME_LENGTH 字节 */
/* 2. 在从 UART 接收到新的数据后, 调用本函数来判断接收到的数据 */
/* 格式是否正确 */
/* 3. 如果数据格式正确, 则在本函数中修改 uiEnd_Of_Last_Frame */
/* 和 uiValid_Frames 参数 */
/************************************************************************/
BOOL Check_Buffered_Frame( HL_Buffered_Data * pBuf )
{
int8u i;
int8u ucSum = 0;
int8u ucLength;
int16u j;
int16u uiStart_Of_New_Frame;
int16u uiEnd_Of_New_Frame;
int16u uiSum_Position;
if ( pBuf->uiStart_Of_First_Frame == pBuf->uiEnd_Of_Last_Frame ) // 新数据帧起始位置
{
uiStart_Of_New_Frame = pBuf->uiStart_Of_First_Frame; // = 0, 初始状态
}
else
{
uiStart_Of_New_Frame = pBuf->uiEnd_Of_Last_Frame + 1;
if ( uiStart_Of_New_Frame == HL_BUFFER_SIZE )
uiStart_Of_New_Frame = 0;
}
if ( pBuf->acBuffer[uiStart_Of_New_Frame] == HL_UART_FRAME_HEADER ) // 判断帧头
{
if ( uiStart_Of_New_Frame + 1 == HL_BUFFER_SIZE )
ucLength = pBuf->acBuffer[0];
else
ucLength = pBuf->acBuffer[uiStart_Of_New_Frame+1]; // 获得帧长度
if ( ( ucLength > 0 ) && ( ucLength <= HL_UART_MAX_FRAME_LENGTH ) ) // 判断帧长度
{
uiEnd_Of_New_Frame = uiStart_Of_New_Frame + ucLength + 3;
if ( uiEnd_Of_New_Frame >= HL_BUFFER_SIZE )
uiEnd_Of_New_Frame -= HL_BUFFER_SIZE;
if ( pBuf->acBuffer[uiEnd_Of_New_Frame] == HL_UART_FRAME_END ) // 判断帧尾
{
for ( i=0; i<ucLength; i++ )
{
j = uiStart_Of_New_Frame + i + 2;
if ( j >= HL_BUFFER_SIZE )
j -= HL_BUFFER_SIZE;
ucSum += pBuf->acBuffer[j];
}
uiSum_Position = uiStart_Of_New_Frame + ucLength + 2;
if ( uiSum_Position >= HL_BUFFER_SIZE )
uiSum_Position -= HL_BUFFER_SIZE;
if ( ucSum == pBuf->acBuffer[uiSum_Position] ) // 检查校验和
{
pBuf->uiEnd_Of_Last_Frame = uiEnd_Of_New_Frame;
pBuf->uiValid_Frames ++;
return TRUE;
}
}
}
}
return FALSE;
}
/************************************************************************/
/* 删除 HL_Buffered_Data 缓冲区中的一个帧, 如果缓冲区中已经没有 */
/* 缓存数据, 则清空缓冲区 */
/* 参数 */
/* pBuf 要删除的数据缓冲区指针 */
/* 返回值 */
/* 无 */
/************************************************************************/
void Delete_Buffered_Frame( HL_Buffered_Data * pBuf )
{
int16u uiStart_Of_Next_Frame;
int8u ucLength;
if ( pBuf->uiValid_Frames == 0 )
{
if ( pBuf->uiEnd_Of_Last_Frame == pBuf->uiPoint )
MEMSET( ( int8u *) pBuf, 0, sizeof( HL_Buffered_Data ) );
return;
}
if ( pBuf->uiStart_Of_First_Frame + 1 == HL_BUFFER_SIZE )
ucLength = pBuf->acBuffer[0];
else
ucLength = pBuf->acBuffer[pBuf->uiStart_Of_First_Frame+1];
uiStart_Of_Next_Frame = pBuf->uiStart_Of_First_Frame + ucLength + 4;
if ( uiStart_Of_Next_Frame >= HL_BUFFER_SIZE )
uiStart_Of_Next_Frame -= HL_BUFFER_SIZE;
pBuf->uiStart_Of_First_Frame = uiStart_Of_Next_Frame; // 下一帧的起始位置
pBuf->uiValid_Frames --;
if ( pBuf->uiValid_Frames == 0 )
{
if ( pBuf->uiEnd_Of_Last_Frame == pBuf->uiPoint )
MEMSET( ( int8u *) pBuf, 0, sizeof( HL_Buffered_Data ) );
}
}
/************************************************************************/
/* 本函数检查数据是否符合 UART 帧格式 */
/* 参数 */
/* pData 要检查的数据指针 */
/* ucPoint 要检查的数据长度 */
/* 返回值 */
/* int8u 实际有效数据帧的长度, 不包括帧头帧尾那 4 个字节 */
/* 返回 0 则说明数据帧无效 */
/************************************************************************/
int8u Check_UART_Frame( int8u *pData, int16u uiPoint )
{
int8u ucLength;
int8u i;
int8u ucSum = 0;
if ( uiPoint <= HL_UART_MAX_FRAME_LENGTH )
{
if ( pData[0] == HL_UART_FRAME_HEADER )
{
ucLength = pData[1];
if ( ucLength > 0 && ucLength <= uiPoint-4 )
{
for ( i=2; i<ucLength+2; i++ )
ucSum += pData[i];
if ( ucSum == pData[ucLength+2] )
if ( pData[ucLength+3] == HL_UART_FRAME_END )
return ucLength;
}
}
}
return 0;
}
/************************************************************************/
/* 获得节点的 Neighbor_Table */
/* 参数 */
/* pucResult Neighbor_Table 存放指针 */
/* 返回值 */
/* int8u Neighbor 的个数 */
/************************************************************************/
int8u Get_Neighbor_Table( int8u * pucResult )
{
EmberNeighborTableEntry sEntry;
int8u i, j=0;
for ( i=0; i<EMBER_NEIGHBOR_TABLE_SIZE; i++ )
{
if ( emberGetNeighbor( i, &sEntry ) == EMBER_SUCCESS )
{
Store_BIT16_Value( pucResult+2*j, sEntry.shortId );
j ++;
}
}
return j;
}
/************************************************************************/
/* 返回格式的读 OD 函数 */
/* 参数 */
/* uiIndex 被读参数的 OD 索引 */
/* ucSub 被读参数的 OD 子索引 */
/* pucResult 读操作返回结果的娣胖刚? */
/* 返回值 */
/* int8u 读操作返回结果的长度 */
/* 其他说明 */
/* 本函数与 Read_OD() 函数之间的区别在于, 本函数的返回结果中 */
/* 已经包含的帧结构信息, 可直接发送 */
/************************************************************************/
int8u Read_OD_Shell( int16u uiIndex, int8u ucSub, int8u * pucResult )
{
MEMCOPY( pucResult+1, emberGetEui64(), 8 ); // long addr.
Store_BIT16_Value( pucResult+9, uiIndex ); // index
pucResult[11] = ucSub; // subindex
pucResult[12] = Read_OD( uiIndex, ucSub, pucResult+13 );
if ( pucResult[12] == 0 )
{
pucResult[0] = HL_CMD_READ_OD_ERR;
pucResult[12]= 1;
}
else
{
if ( pucResult[12] > HL_RF_PAYLOAD_LENGTH ) // 读取的数据太长
{
pucResult[0] = HL_CMD_READ_OD_ERR; // 无法用 RF 发送
pucResult[12]= 1;
pucResult[13]= HL_OD_ERR_WRONG_LENGTH;
}
else
pucResult[0] = HL_CMD_READ_OD;
}
return ( pucResult[12] + 13 );
}
/************************************************************************/
/* 读 OD 函数 */
/* 参数 */
/* uiIndex 被读参数的 OD 索引 */
/* ucSub 被读参数的 OD 子索引 */
/* pucResult 读操作返回结果的存放指针 */
/* 返回值 */
/* int8u 读操作返回结果的长度 */
/* 如果返回 0, 则说明出现了读错误, 并且错误
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -