Compare commits
2 Commits
22b508ad31
...
90a2ab4ff8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90a2ab4ff8 | ||
|
|
697fe56098 |
@ -169,6 +169,7 @@ void HDLogDebugSetGetTask(HDLogGetTaskType_t getTask);
|
||||
* @param size 栈大小
|
||||
*/
|
||||
void HDLogDebugInitStackAddr(unsigned long currTask, uint32_t size);
|
||||
void HDLogDebugInitStackAddrInfo(unsigned long currTask, uint32_t size, uint32_t stackAddr);
|
||||
|
||||
/**
|
||||
* @brief 删除当前任务的栈大小记录
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
#define HDPROTOCOL_DELAY_TIMEOUT (100)
|
||||
|
||||
// 数据占用时间
|
||||
#define HDPROTOCOL_OCCUPY_TIMEOUT (3000)
|
||||
#define HDPROTOCOL_OCCUPY_TIMEOUT (1000)
|
||||
|
||||
|
||||
enum eHDProtocolSupport
|
||||
@ -37,6 +37,7 @@ enum eHDProtocolSupport
|
||||
kHDProtocolNone = 0x00, ///< 无协议, 不阻塞等待
|
||||
kHDProtocolFpga = 0x01, ///< fpga协议, 独占解析端
|
||||
kHDProtocolVP = 0x02, ///< vp协议, 独占解析端
|
||||
kHDProtocolTV = 0x04, ///< tv协议
|
||||
};
|
||||
|
||||
/**
|
||||
@ -51,10 +52,13 @@ typedef struct __attribute__((__packed__)) HDProtocolServerInfo
|
||||
uint8_t src; ///< 源数据口
|
||||
uint8_t dst; ///< 目标数据口(如果需要始终转发可以修改该项目, 否则默认和src一样)
|
||||
uint8_t tmpDst; ///< 临时回送目标数据口(用于该指令需要先请求某个数据后才能回复的情况)
|
||||
uint8_t tmpReadCount : 6; ///< 临时数据最大等待回复次数
|
||||
uint8_t tmpReadCount : 5; ///< 临时数据最大等待回复次数
|
||||
uint8_t tmpEnable : 1; ///< 当前临时目标等待数据, 需要等待数据内部标记开启, 数据完成或者超时后自动关闭
|
||||
uint8_t run : 1; ///< 内部标记当前正常读取, 如果再次触发解析, 则不等待
|
||||
uint8_t delayCount; ///< 延时等待次数(默认: 1), 每次等待时间为 HSCHEDULE_DELAY_TIMEOUT
|
||||
uint8_t checkAlarm : 1; ///< 启动缓存报警检查
|
||||
uint8_t notifyAlarm : 1; ///< 通知缓存报警(内部管理)
|
||||
uint8_t occupy : 1; ///< 内部标记当前正在占用
|
||||
uint8_t delayCount : 6; ///< 延时等待次数(默认: 1), 每次等待时间为 HSCHEDULE_DELAY_TIMEOUT
|
||||
} HDProtocolServerInfo;
|
||||
|
||||
/**
|
||||
@ -65,7 +69,7 @@ typedef struct __attribute__((__packed__)) HDProtocolServerInfo
|
||||
*/
|
||||
typedef int (*HDProtocolReadCallback)(HDProtocolServerInfo *info, uint8_t isTimeout);
|
||||
typedef void (*HDProtocolWriteCallback)(HDProtocolServerInfo *info, const uint8_t *data, int len);
|
||||
|
||||
typedef void (*HDProtocolCheckAlarmCallback)(HDProtocolServerInfo *info);
|
||||
/**
|
||||
* @brief 设置协议回调函数
|
||||
* @param readCall 读取回调函数
|
||||
@ -73,6 +77,12 @@ typedef void (*HDProtocolWriteCallback)(HDProtocolServerInfo *info, const uint8_
|
||||
*/
|
||||
void HDProtocolSetCallback(HDProtocolReadCallback readCall, HDProtocolWriteCallback writeCall);
|
||||
|
||||
/**
|
||||
* @brief 设置缓冲区报警回调, 需要立刻返回, 不能阻塞
|
||||
* @param checkCall 检查缓冲区报警回调函数
|
||||
*/
|
||||
void HDProtocolCheckAlarmCall(HDProtocolCheckAlarmCallback checkCall);
|
||||
|
||||
/**
|
||||
* @brief 初始化协议信息结构, 将原始缓冲器转换成环状缓冲区(需要消耗一些字节)
|
||||
* @param info 协议信息结构
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
// 定时器注册最大数量
|
||||
#ifndef HTIMER_REGISTER_MAX
|
||||
#define HTIMER_REGISTER_MAX (1)
|
||||
#define HTIMER_REGISTER_MAX (5)
|
||||
#endif
|
||||
|
||||
// 无效值
|
||||
@ -38,9 +38,9 @@ typedef void (*HTimerCallType)();
|
||||
///< 注册的定时器信息, 定义为数组, 数量由外部控制
|
||||
typedef struct HTimerInfo {
|
||||
uint32_t flags : 1; ///< 定时器标志, eTimerFlags
|
||||
uint32_t enable : 1; ///< 定时器使能
|
||||
volatile uint32_t enable: 2; ///< 定时器使能
|
||||
uint32_t curr : 1; ///< 当前回调者
|
||||
uint32_t duration : 29; ///< 定时触发时长, 毫秒为计数单元
|
||||
uint32_t duration : 28; ///< 定时触发时长, 毫秒为计数单元
|
||||
uint32_t lastTime; ///< 上次触发时间
|
||||
HTimerCallType call; ///< 定时触发函数
|
||||
} HTimerInfo;
|
||||
|
||||
@ -524,6 +524,11 @@ void HDLogDebugSetGetTask(HDLogGetTaskType_t getTask)
|
||||
void HDLogDebugInitStackAddr(unsigned long currTask, uint32_t size)
|
||||
{
|
||||
void *start = 0;
|
||||
HDLogDebugInitStackAddrInfo(currTask, size, (uint32_t)&start - sizeof(void *));
|
||||
}
|
||||
|
||||
void HDLogDebugInitStackAddrInfo(unsigned long currTask, uint32_t size, uint32_t stackAddr)
|
||||
{
|
||||
for (int i = 0; i < USE_CHECK_STACK_NUM; ++i)
|
||||
{
|
||||
if (sStackCheckInfo[i].enable)
|
||||
@ -532,7 +537,7 @@ void HDLogDebugInitStackAddr(unsigned long currTask, uint32_t size)
|
||||
}
|
||||
|
||||
sStackCheckInfo[i].enable = 1;
|
||||
sStackCheckInfo[i].stackAddr = (unsigned long)&start - sizeof(void *);
|
||||
sStackCheckInfo[i].stackAddr = stackAddr;
|
||||
sStackCheckInfo[i].stackSize = size;
|
||||
sStackCheckInfo[i].taskID = currTask;
|
||||
break;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "HDProtocolServer.h"
|
||||
#include "HRingBuffer.h"
|
||||
// #include "src/sys/inc/HDSystemTask.h"
|
||||
#include "HDLog.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@ -11,7 +12,8 @@
|
||||
#define HDDelayMs(ms)
|
||||
#endif
|
||||
|
||||
#define OCCUPIED_MAX (5)
|
||||
// 占用信息监测, 需要大于协议数量
|
||||
#define OCCUPIED_MAX (10)
|
||||
|
||||
|
||||
struct __attribute__((__packed__)) OccupiedInfo {
|
||||
@ -25,6 +27,7 @@ struct __attribute__((__packed__)) OccupiedInfo {
|
||||
struct __attribute__((__packed__)) HScheduleRegisterInfo {
|
||||
HDProtocolReadCallback readCall; ///< 读取回调
|
||||
HDProtocolWriteCallback writeCall; ///< 写入回调
|
||||
HDProtocolCheckAlarmCallback checkAlarmCall; ///< 检查缓冲区报警回调
|
||||
HDProtocolServerInfo *info; ///< 协议信息
|
||||
uint8_t infoLen; ///< 协议信息长度
|
||||
uint8_t useIndex; ///< 当前使用的索引
|
||||
@ -38,7 +41,7 @@ static uint8_t IsOccupied(uint8_t currIndex, uint8_t protocol, uint8_t *occupied
|
||||
{
|
||||
if (currIndex >= OCCUPIED_MAX) {
|
||||
LogE("index[%d] out of range[%d]", currIndex, OCCUPIED_MAX);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < OCCUPIED_MAX; ++i) {
|
||||
@ -59,6 +62,7 @@ static uint8_t IsOccupied(uint8_t currIndex, uint8_t protocol, uint8_t *occupied
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 被其他协议占用
|
||||
sOccupiedInfo[i].waitOccupy = 1;
|
||||
return 1;
|
||||
}
|
||||
@ -95,6 +99,8 @@ static void SetOccupied(uint8_t currIndex, uint8_t protocol, uint8_t enable)
|
||||
sOccupiedInfo[i].protocol = 0;
|
||||
sOccupiedInfo[i].occupyTime = 0;
|
||||
sOccupiedInfo[i].waitOccupy = 0;
|
||||
|
||||
sInfo.info[currIndex].occupy = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -111,6 +117,8 @@ static void SetOccupied(uint8_t currIndex, uint8_t protocol, uint8_t enable)
|
||||
sOccupiedInfo[index].index = currIndex;
|
||||
sOccupiedInfo[index].protocol = protocol;
|
||||
sOccupiedInfo[index].occupyTime = HDLogGetTime();
|
||||
|
||||
sInfo.info[currIndex].occupy = 1;
|
||||
}
|
||||
|
||||
static void WaitRead(HDProtocolServerInfo *info)
|
||||
@ -120,6 +128,7 @@ static void WaitRead(HDProtocolServerInfo *info)
|
||||
}
|
||||
|
||||
for (int i = 0; i < info->delayCount; ++i) {
|
||||
uint32_t curr = HDLogGetTime();
|
||||
for (int j = 0; j < HDPROTOCOL_DELAY_TIMEOUT; ++j) {
|
||||
HDProtocolRun();
|
||||
if (info->tmpEnable == 0) {
|
||||
@ -130,6 +139,10 @@ static void WaitRead(HDProtocolServerInfo *info)
|
||||
if (info->run == 0) {
|
||||
HDDelayMs(1);
|
||||
}
|
||||
|
||||
if (HDLogGetTime() - curr >= HDPROTOCOL_DELAY_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->tmpEnable == 0) {
|
||||
@ -137,6 +150,10 @@ static void WaitRead(HDProtocolServerInfo *info)
|
||||
}
|
||||
}
|
||||
|
||||
if (info->tmpEnable) {
|
||||
LogD("wait tmp read not recv[%d]", info->src);
|
||||
}
|
||||
|
||||
info->tmpEnable = 0;
|
||||
}
|
||||
|
||||
@ -145,6 +162,12 @@ static void ParseReadData(int index, int isTimeout)
|
||||
sInfo.useIndex = index;
|
||||
const int len = sInfo.readCall(&sInfo.info[index], isTimeout);
|
||||
sInfo.useIndex = sInfo.infoLen;
|
||||
// 当前在中断, 且自身处于占用状态, 立刻返回
|
||||
if (sInfo.info[index].run && sInfo.info[index].occupy) {
|
||||
return ;
|
||||
}
|
||||
|
||||
sInfo.info[index].notifyAlarm = 0;
|
||||
if (len == 0 && sInfo.info[index].tmpEnable) {
|
||||
// 临时路由转发数据
|
||||
if (sInfo.info[index].tmpReadCount > 0) {
|
||||
@ -169,6 +192,11 @@ void HDProtocolSetCallback(HDProtocolReadCallback readCall, HDProtocolWriteCallb
|
||||
sInfo.writeCall = writeCall;
|
||||
}
|
||||
|
||||
void HDProtocolCheckAlarmCall(HDProtocolCheckAlarmCallback checkCall)
|
||||
{
|
||||
sInfo.checkAlarmCall = checkCall;
|
||||
}
|
||||
|
||||
void HDProtocolInitInfo(HDProtocolServerInfo *info, uint8_t src, void *data, int dataLen)
|
||||
{
|
||||
if (info == NULL) {
|
||||
@ -192,7 +220,7 @@ void _HDProtocolSetSupportProtocol(HDProtocolServerInfo *info, int len, ...)
|
||||
va_list args;
|
||||
va_start(args, len);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
info->supportProtocol |= (1 << va_arg(args, int));
|
||||
info->supportProtocol |= va_arg(args, int);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
@ -258,7 +286,7 @@ uint8_t HDProtocolGetDest(HDProtocolServerInfo *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info->tmpEnable) {
|
||||
if (info->tmpEnable && info == HDProtocolGetCurrInfo()) {
|
||||
return info->tmpDst;
|
||||
}
|
||||
|
||||
@ -295,13 +323,13 @@ void HDProtocolRead(uint8_t src, const void *data, int len)
|
||||
sInfo.info[src].run = 1;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (HRingBufferFull(sInfo.info[src].readBuff)) {
|
||||
// 只需要检查一次
|
||||
if (occupy == 0xff) {
|
||||
// 当自身处于未占用时, 需要检查一次
|
||||
if (sInfo.info[src].occupy == 0) {
|
||||
occupy = IsOccupied(src, sInfo.info[src].supportProtocol, NULL);
|
||||
}
|
||||
|
||||
// 检查是否占用
|
||||
if (occupy == 0) {
|
||||
// 自身处于占用状态或者当前可占用时执行读取
|
||||
if (sInfo.info[src].occupy || occupy == 0) {
|
||||
ParseReadData(src, 0);
|
||||
}
|
||||
}
|
||||
@ -309,6 +337,16 @@ void HDProtocolRead(uint8_t src, const void *data, int len)
|
||||
HRingBufferAddDataOver(sInfo.info[src].readBuff, srcData[i]);
|
||||
}
|
||||
|
||||
// 协议开启缓存报警检测时, 且未通知过
|
||||
if (sInfo.info[src].checkAlarm && sInfo.info[src].notifyAlarm == 0 && sInfo.checkAlarmCall) {
|
||||
const HRingBufferLenType readLen = HRingBufferGetUseByteLen(sInfo.info[src].readBuff);
|
||||
const HRingBufferLenType buffLen = HRingBufferGetLen(sInfo.info[src].readBuff) >> 1;
|
||||
if (readLen >= buffLen) {
|
||||
// 只通知一次, 读取数据后再次检查
|
||||
sInfo.info[src].notifyAlarm = 1;
|
||||
sInfo.checkAlarmCall(&sInfo.info[src]);
|
||||
}
|
||||
}
|
||||
sInfo.info[src].run = 0;
|
||||
}
|
||||
|
||||
@ -331,8 +369,8 @@ void HDProtocolRun()
|
||||
// 有之前的数据已经占用了, 并且检查是否超时
|
||||
uint8_t occupiedIndex = OCCUPIED_MAX;
|
||||
if (IsOccupied(i, sInfo.info[i].supportProtocol, &occupiedIndex)) {
|
||||
// 异常情况
|
||||
if (occupiedIndex >= OCCUPIED_MAX) {
|
||||
LogE("occupiedIndex[%d] is out of range[%d]", occupiedIndex, OCCUPIED_MAX);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -341,7 +379,7 @@ void HDProtocolRun()
|
||||
continue;
|
||||
}
|
||||
|
||||
// 通知协议超时
|
||||
// 通知协议超时, 数据清空
|
||||
ParseReadData(occupiedIndex, 1);
|
||||
|
||||
// 如果还占用, 说明用户那边自己要求继续占用
|
||||
|
||||
@ -463,6 +463,11 @@ uint8_t HDRPCParseArgs(void *data, uint16_t len, HDRPCSession *session)
|
||||
uint8_t _HDRPCCheckArgs(HDRPCSession *session, uint8_t *type, uint8_t index, uint8_t len)
|
||||
{
|
||||
for (uint8_t i = index; i < len; ++i) {
|
||||
if (i >= session->index) {
|
||||
LogD("Check type[%d] index[%d] len[%d] error", type[i], i, session->index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (session->args[i].type != type[i]) {
|
||||
LogD("Check index[%d] Type[0x%x][0x%x] faild", i, session->args[i].type, type[i]);
|
||||
return 0;
|
||||
|
||||
@ -199,37 +199,24 @@ HRingBufferLenType HRingBufferGetByteDatas(HRingBufferType* buffer, uint8_t *dat
|
||||
|
||||
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
|
||||
const HRingBufferLenType typeSize = GetRingBufferTypeSize(buffer);
|
||||
const HRingBufferLenType dataLen = HRingBufferGetUseByteLen(buffer);
|
||||
len = len / typeSize * typeSize;
|
||||
len = (len > dataLen) ? dataLen : len;
|
||||
HRingBufferLenType readLen = 0;
|
||||
if (base->start >= base->end) {
|
||||
int copySize = (base->len - base->start) * typeSize;
|
||||
if (copySize > len) {
|
||||
copySize = len;
|
||||
const HRingBufferLenType startPos = base->start;
|
||||
const HRingBufferLenType endPos = base->end;
|
||||
int copyLen = (endPos - startPos) * typeSize;
|
||||
if (startPos >= endPos) {
|
||||
copyLen = (base->len - startPos) * typeSize;
|
||||
}
|
||||
|
||||
memcpy(data, GetRingByteData(buffer, base->start), copySize);
|
||||
readLen += copySize;
|
||||
data += copySize;
|
||||
len -= copySize;
|
||||
AdjustReadPos(buffer, copySize / typeSize);
|
||||
if (copyLen > len) {
|
||||
copyLen = len / typeSize * typeSize;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return readLen;
|
||||
if (copyLen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copySize = (base->end - base->start) * typeSize;
|
||||
if (copySize > len) {
|
||||
copySize = len;
|
||||
}
|
||||
|
||||
memcpy(data, GetRingByteData(buffer, base->start), copySize);
|
||||
readLen += copySize;
|
||||
len -= copySize;
|
||||
AdjustReadPos(buffer, copySize / typeSize);
|
||||
return readLen;
|
||||
memcpy(data, GetRingByteData(buffer, startPos), copyLen);
|
||||
AdjustReadPos(buffer, copyLen / typeSize);
|
||||
return copyLen;
|
||||
}
|
||||
|
||||
// 获取环形缓冲区数据长度
|
||||
|
||||
@ -68,11 +68,17 @@ static int16_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call,
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < sTimeRegisters[id].len; ++i) {
|
||||
if (sTimeRegisters[id].timers[i].enable == 1) {
|
||||
if (sTimeRegisters[id].timers[i].enable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 防中断导致数据重叠
|
||||
sTimeRegisters[id].timers[i].enable = 1;
|
||||
if (sTimeRegisters[id].timers[i].enable != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sTimeRegisters[id].timers[i].enable = 2;
|
||||
sTimeRegisters[id].timers[i].duration = duration;
|
||||
sTimeRegisters[id].timers[i].lastTime = GetCurrentMs();
|
||||
sTimeRegisters[id].timers[i].call = call;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user