| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*
- * queue.c
- *
- * Created on: 2025年8月20日
- * Author: 龙三郎
- */
- #include <tr_queue.h>
- #include <stdio.h>
- #include "tr_protocol.h"
- // 初始化队列
- void initializeQueue(Queue *q)
- {
- q->front = 0;
- q->rear = 0;
- }
- // 判断队列是否已满
- bool isFull(Queue *q)
- {
- return (q->rear + 1) % QUEUE_MAX_SIZE == q->front;
- }
- // 判断队列是否为空
- bool isEmpty(Queue *q)
- {
- return q->front == q->rear;
- }
- // 队列现有元素个数
- int currentItems(Queue *q)
- {
- if(q->rear >= q->front) {
- return q->rear - q->front;
- } else {
- return q->rear + QUEUE_MAX_SIZE - q->front + 1;
- }
- }
- // 队列剩余空间
- int remainSpace(Queue *q)
- {
- return QUEUE_MAX_SIZE - currentItems(q);
- }
- // 入队列,单个元素
- bool enqueue(Queue *q, unsigned char element)
- {
- if (isFull(q)) {
- return false; // 队列已满,无法添加新元素
- }
- q->items[q->rear] = element; // 将元素添加到队尾
- q->rear = (q->rear + 1) % QUEUE_MAX_SIZE; // 更新队尾指针,注意循环队列的处理方式
- return true; // 成功入队返回true
- }
- // 批量入队列
- bool enqueueBatch(Queue *q, unsigned char *elements, unsigned int elSize)
- {
- if(remainSpace(q) < elSize)
- {
- return false; // 队列空间不够,无法批量添加。
- }
- int i;
- for(i = 0; i < elSize; i++)
- {
- enqueue(q, *(elements + i));
- }
- return true;
- }
- // 出队列,单个元素
- bool dequeue(Queue *q, unsigned char *element)
- {
- if (isEmpty(q)) {
- return false; // 队列为空,无法移除元素
- }
- *element = q->items[q->front]; // 获取队首元素的值并传出参数(可选)
- q->front = (q->front + 1) % QUEUE_MAX_SIZE; // 更新队首指针,注意循环队列的处理方式
- return true; // 成功出队返回true
- }
- // 批量出队列
- bool dequeueBatch(Queue *q, unsigned short len, unsigned char *elements)
- {
- if (currentItems(q) < len) {
- return false; // 长度不够
- }
- int i;
- for(i = 0; i < len; i++)
- {
- dequeue(q, elements + i);
- }
- return true; // 成功出队返回true
- }
- // 查看队列中的元素,不出队列
- static bool queryQueue(Queue *q, unsigned short start, unsigned short len, unsigned char *element)
- {
- if (currentItems(q) < (start + len)) {
- return false; // 长度不够
- }
- int i;
- for(i = 0; i < len; i++)
- {
- int index = (q->front + start + i) % QUEUE_MAX_SIZE;
- *(element + i) = q->items[index]; // 获取队首元素的值并传出参数(可选)
- }
- return true; // 成功出队返回true
- }
- // 从队列中取出一个数据包。
- bool dequeueBatchWithProtocol(Queue *q, unsigned char *d, unsigned short *dl)
- {
- while(true)
- {
- unsigned char pheader[3] = {0};
- if(!queryQueue(q, 0, 3, pheader))
- {
- return false;
- }
- if(pheader[0] == 'T' && pheader[1] == 'R' && pheader[2] == 0x01)
- {
- break;
- }
- else
- {
- dequeue(q, pheader);
- }
- }
- unsigned char plength[2] = {0};
- if(!queryQueue(q, 6, 2, plength))
- {
- return false;
- }
- unsigned short length = 0;
- length |= (plength[0] << 8) & 0xff00;
- length |= plength[1] & 0x00ff;
- // printf("length=%d\r\n", length);
- *dl = length;
- return dequeueBatch(q, length, d);
- }
- // 协议解析相关
- bool getVerFromProtocol(unsigned char *p, unsigned short pl, unsigned char *ver)
- {
- uint8_t version = ProtocolGetVersion(p, pl);
- if(!version)
- {
- return false;
- }
- *ver = version;
- return true;
- }
- // 获取目的地址
- bool getDaFromProtocol(unsigned char *p, unsigned short pl, unsigned char *da)
- {
- uint8_t destAddress = ProtocolGetDestAddress(p, pl);
- if(!destAddress)
- {
- return false;
- }
- *da = destAddress;
- return true;
- }
- // 获取数据类型
- bool getTypeFromProtocol(unsigned char *p, unsigned short pl, unsigned char *type)
- {
- uint8_t _type = ProtocolGetType(p, pl);
- if(!_type)
- {
- return false;
- }
- *type = _type;
- return true;
- }
- // 获取来源地址
- bool getSaFromProtocol(unsigned char *p, unsigned short pl, unsigned char *sa)
- {
- uint8_t sourceAddress = ProtocolGetSourceAddress(p, pl);
- if(!sourceAddress)
- {
- return false;
- }
- *sa = sourceAddress;
- return true;
- }
- // 获取源数据
- bool getPayloadFromProtocol(unsigned char *p, unsigned short pl, unsigned char *s, unsigned short *sl)
- {
- uint16_t payloadLength = ProtocolGetPayload(p, pl, s);
- *sl = payloadLength;
- if(*sl == 0)
- {
- return false;
- }
- return true;
- }
- // 转发业务相关
- // 初始化
- Queue queueList[QUEUE_NUM];
- void dataforwardInit(void)
- {
- int i;
- for(i = 0; i < QUEUE_NUM; i++)
- {
- initializeQueue(&queueList[i]);
- }
- }
- // 主流程
- static unsigned char dfmBuffer[BUFFER_SIZE_2K];
- static unsigned short dfmBufferLength = 0;
- void dataforwardMain(void)
- {
- int i;
- for(i = 0; i < QUEUE_NUM; i++)
- {
- while(dequeueBatchWithProtocol(&queueList[i], dfmBuffer, &dfmBufferLength))
- {
- unsigned char da, sa, type;
- if(!getDaFromProtocol(dfmBuffer, dfmBufferLength, &da)
- || !getSaFromProtocol(dfmBuffer, dfmBufferLength, &sa)
- || !getTypeFromProtocol(dfmBuffer, dfmBufferLength, &type))
- {
- continue;
- }
- if(da == THIS_ADDRESS)
- {
- dataNotForwardedHandle(dfmBuffer, dfmBufferLength, sa, type);
- }
- else
- {
- dataForwardedHandle(dfmBuffer, dfmBufferLength, da);
- }
- }
- }
- }
- // 将从usb发来的协议数据入队列
- bool enqueueFromUsb(unsigned char *s, unsigned short sl)
- {
- return enqueueBatch(&queueList[QUEUE_INDEX_USB], s, sl);
- }
- // 将从以太网发来的协议数据入队列
- bool enqueueFromEthernet(unsigned char *s, unsigned short sl)
- {
- return enqueueBatch(&queueList[QUEUE_INDEX_ETHERNET], s, sl);
- }
- // 将从uart发来的协议数据入队列
- bool enqueueFromUart(unsigned char c)
- {
- return enqueue(&queueList[QUEUE_INDEX_UART], c);
- }
- // 将从uart发来的协议数据入队列
- bool enqueueFromUartBatch(unsigned char *s, unsigned short sl)
- {
- return enqueueBatch(&queueList[QUEUE_INDEX_UART], s, sl);
- }
- // 从本模块发出的数据入队列,源数据。带协议格式
- bool enqueueFromHere(unsigned char *s, unsigned short sl, unsigned char da, unsigned char type)
- {
- return enqueueBatch(&queueList[QUEUE_INDEX_HEAR], s, sl);
- }
|