完成明白3个FIFO
#include "gsmuart.h"
#include "gkbaseusart.h"
#include "gunit.h"
#include "gbaselist.h"
#include "GAppCmd.h"
void *puart=NULL;
//++++++++++++使用串口框架+++++++++++//
typedef struct
{
volatile uint8_t start;
volatile uint32_t count;
volatile uint8_t idle;
}timeflagtype;
timeflagtype tflg;
#define RECEIVE_MAX 2048
typedef struct
{
uint16_t len;
char rxBuff[RECEIVE_MAX];
}lbDataType;
lbDataType udata;
//++++++++++++使用串口框架+++++++++++//
void mode_clear(void)
{
memset(&udata,0,sizeof(lbDataType));
memset(&tflg,0,sizeof(timeflagtype));
}
void usart_timer_isr(void)
{
if( tflg.start)
{
if( tflg.count++ > 3 )
{
memset(&tflg,0,sizeof(timeflagtype));
tflg.idle =1;
}
}
}
void smuart_rxbyte(uint8_t data)
{
//printf("data=%c\r\n",data);
tflg.start=1;
tflg.count=0;
udata.rxBuff[udata.len++%RECEIVE_MAX]=data;
}
uint8_t *rxbuf;
void puart_init(void)
{
rxbuf = malloc(100);
printf("rxbuf add = %p\r\n",rxbuf);
if( (puart = GK_usart_read_obj(1))==NULL)SHOWME;
GK_usart_init(puart,1,rxbuf,NULL);
}
void puart_reinit(void)
{
free(rxbuf);//也可以直接用 lbDataType udata;里面的 rxBuff[RECEIVE_MAX];
GK_usart_init(puart,1,NULL,smuart_rxbyte);
static node_oncetime_type T;
timer.creat(&T, 1 , 1 ,usart_timer_isr );
}
void smuart_init(void)
{
puart_init();
}
uint8_t smuart_TXRX_L1(uint8_t *TX , uint16_t TXlen , uint8_t *RX,uint16_t *RXlen )
{
if(GK_usart_TXRX(puart, TX ,TXlen ,RX,RXlen))
{
printf("TX:");printf("%s\r\n",TX);
printf("RX:");printf("%s\r\n",RX);
return 1;
}
else
return 0;
}
uint8_t smuart_TXRX_L2(uint8_t *TX , uint16_t TXlen , uint8_t *MUSTRX)
{
char cnt=100;
uint8_t RX[100]={0};
uint16_t RXlen=0;
while(--cnt !=0 )
{
HAL_Delay(100);
memset(RX,0,100);
if(smuart_TXRX_L1(TX ,TXlen ,RX,&RXlen))
{
if(strstr((char *)RX,(char *)MUSTRX))
return 1;
}
}
return 0;
}
#include "GAppCmd.h"
void smuart_test(void)
{
static uint8_t flag=0;
smuart_init();
registerCmds();
//commer.ShowSelf();
gizwitsInit();//L1级别
FIFO_Init_L2();//L2级别
FIFO_Init_pRbsend();
while(1)
{
if(flag == 0)
{
if( smuart_TXRX_L2((uint8_t *)"hello",6,(uint8_t *)"world"))
{
flag = 1;
}
}
if(flag==1)
{
puart_reinit();
mode_clear();
flag = 2;
}
if(flag==2)
{
if(tflg.idle)
{
printf("\r\n+\r\n");
G_printHEX(udata.rxBuff,udata.len);
printf("\r\n+\r\n");
#if 0 //OLD
tslProtocolPutData((uint8_t *)udata.rxBuff,udata.len);
#else //NEW PUT try:0101
ProtocolMessage_t message;
message.fd = 0;
memcpy(message.data, (uint8_t *)udata.rxBuff,udata.len);
message.len = 1;
tslProtocolPutMessage(&message);
#endif
mode_clear();
}
}
HAL_Delay(200);
}
}
#include "GAppCmd.h"
#include "gunit.h"
static void connect(int fd, uint8_t sn, uint16_t len, uint8_t *data);
static void clearCard(int fd, uint8_t sn, uint16_t len, uint8_t *data);
static node_command_type commands[] = {
{"connect", NULL, 0X0100, connect,NULL},
{"clearCard", NULL, 0X0101, clearCard,NULL},
};
static void connect(int fd, uint8_t sn, uint16_t len, uint8_t *data) {SHOWME
}
static void clearCard(int fd, uint8_t sn, uint16_t len, uint8_t *data) {SHOWME
}
//注册技术 可以把上面自己搞的函数注册进去
void registerCmds(void) {
commer.Register(&commands[0], sizeof(commands) / sizeof(commands[0]));
}
//使用案例
//node_command_type * cmdnode = commer.find(id);
//if(cmdnode !=NULL)
//cmdnode->fun();
#include "GringBuffer.h"
#define RB_MAX_LEN 200
rb_t pRb;
static uint8_t rbBuf[RB_MAX_LEN];
void gizwitsInit(void)
{
pRb.rbCapacity = RB_MAX_LEN;
pRb.rbBuff = rbBuf;
if(0 == rbCreate(&pRb))
{
printf("rbCreate Success \n");
}
else
{
printf("rbCreate Faild \n");
}
}
rb_t pRbL2;
static uint8_t rbBufL2[RB_MAX_LEN];
void FIFO_Init_L2(void)
{
pRbL2.rbCapacity = RB_MAX_LEN;
pRbL2.rbBuff = rbBufL2;
if(0 == rbCreate(&pRbL2))
{
printf("pRbL2Create Success \n");
}
else
{
printf("pRbL2Create Faild \n");
}
}
rb_t pRbsend;
static uint8_t Rbsend[RB_MAX_LEN];
void FIFO_Init_pRbsend(void)
{
pRbsend.rbCapacity = RB_MAX_LEN;
pRbsend.rbBuff = Rbsend;
if(0 == rbCreate(&pRbsend))
{
printf("pRbsendCreate Success \n");
}
else
{
printf("pRbsendCreate Faild \n");
}
}
/*
* 将收到的数据放入环形队列
*/
int32_t tslProtocolPutData(uint8_t *buf, int32_t len) {
int32_t count = 0;
if(NULL == buf) {
return -1;
}
count = rbWrite(&pRb, buf, len);
return count;
}
/*
* 将收到的数据放入环形队列
*/
int32_t tslProtocolPutMessage(ProtocolMessage_t *message)
{
int32_t count = 0;
if(NULL == message) {
return -1;
}
count = rbWrite(&pRb, (uint8_t *)message, sizeof(ProtocolMessage_t));
return count;
}
#include "GAppCmd.h"
void showp(ProtocolMessage_t *p)
{
printf("p->fd=%04X\r\n",p->fd);
G_printHEX(&p->data,10);
printf("p->len=%04X\r\n",p->len);
}
/*
* 处理用户注册的命令
* 需要单独在一个线程中运行
这里的用法是在串口中接收数据 也即是放入到FIFO 然后在任务中读FIFO拿出来解析
*/
int8_t tslProtocolHandleCmd(void) {
int32_t tempLength = 0;
ProtocolMessage_t message;
tempLength = rbRead(&pRb, (uint8_t *)&message, sizeof(ProtocolMessage_t));
if (tempLength == sizeof(ProtocolMessage_t))
{
printf("\r\n");
G_printHEX(&message,sizeof(ProtocolMessage_t));
printf("\r\n");
showp(&message);
node_command_type *node = commer.Find(message.fd);
if(node !=NULL)
node->fun(0,0,0,NULL);
return 0;
}
else
{
return -1;
}
}
/*
* 通过TCP写入一定长度的数据
* 此接口必须实现
把数据放到FIFO 它没有前面的做的好 前面是写一个结构体进去!比写数据进去好!
*/
//int32_t tslProtocolPutData(uint8_t *buf, int32_t len) {一抹一眼
uint32_t tslTcpWrite(int fd, uint8_t *data, uint32_t size) {
int32_t count = 0;
if(NULL == data) {
return 0;
}
count = rbWrite(&pRbsend, data, size);
return count;
}
/*
* 处理用户注册的命令
* 需要单独在一个线程中运行
这里的用法是在程序中任意位置调用tslTcpWrite 放入到FIFO 然后在任务中读FIFO拿出发送出去
*/
int8_t tslProtocolHandleSend(void) {
int32_t tempLength = 0;
uint8_t tempData[20];
tempLength = rbRead(&pRbsend, (uint8_t *)&tempData, sizeof(tempData));
if (tempLength >0)
{
printf("\r\n#tslProtocolHandleSend\r\n");
G_printHEX(tempData,tempLength);
printf("\r\n#tslProtocolHandleSend\r\n");
//tcpWrite(tempData, tempLength);//模块发送出去 可以是BLE W5500等
return 0;
}
return 1;
}
/* 举例
static void sendDataTask(void *pvParameters) {
int32_t tempLength = 0;
uint8_t tempData[20];
pvParameters = pvParameters;
for (; ;) {
osDelay(10);
tempLength = rt_ringbuffer_get(&sendRingBuffer, (uint8_t *)&tempData, sizeof(tempData));
if (tempLength > 0) {
tcpWrite(tempData, tempLength);
}
}
} */
typedef void (*DataHandleHook)(uint8_t len, uint8_t *data);
static DataHandleHook reciveDataHandleHook = NULL;
/*
* 设置数据处理钩子函数
* 比如数据是加密的,协议栈传输的时候是不知道的,这时可以设置钩子函数解密数据
*/
void registerReciveDataHandleHook(DataHandleHook hook) {
reciveDataHandleHook = hook;
}
#define MAX_DATA_LEN 20
typedef struct {
uint8_t head;
uint8_t num;
uint8_t rnum;
uint16_t alen;
} ProtocolHead_t;
typedef struct {
ProtocolHead_t head;
uint8_t data[MAX_DATA_LEN];
uint16_t crc;
int fd;
} ProtocolCommon_t;
static ProtocolCommon_t dataProtocol;
void show_ProtData(ProtocolCommon_t *pag)
{
printf("\n****************************************** \r\n");
printf("pag->head.head= [%02X]\r\n" , pag->head.head);
printf("pag->head.num= [%02X]\r\n" , pag->head.num);
printf("pag->head.rnum= [%02X]\r\n" , pag->head.rnum);
printf("pag->head.alen= [%04X]\r\n" , pag->head.alen);
G_printHEX(pag->data,pag->head.alen);
printf("pag->crc= [%04X]\r\n" , pag->crc);
printf("\n****************************************** \r\n");
}
//分析状态机
typedef enum {
Protocol_head,
Protocol_num,
Protocol_rnum,
Protocol_alen,
Protocol_body,
Protocol_crc,
} ProtocolStatus_t;
typedef struct {
ProtocolStatus_t status;
uint8_t alen;
uint8_t rlen;
uint8_t cmdCount;
uint16_t check;
} StatusData_t;
static StatusData_t statusMachineData;
/*
* 复位状态机 仅仅针对POS设置
*/
void resetStateMachine(void) {
statusMachineData.status = Protocol_head;
}
/*
* 复位状态机中间变量 其他成员清0
*/
void resetStateMachineData(void) {
statusMachineData.alen = 0;
statusMachineData.rlen = 0;
statusMachineData.cmdCount = 0;
statusMachineData.check = 0;
}
/*
* 协议分析
*/
int8_t protocolAnalyze(int fd, ProtocolCommon_t *protocol, uint8_t element)
{
uint16_t crc16 = 0;
uint8_t finish = 0;
switch(statusMachineData.status)
{
case Protocol_head:
{
if (element == 0XAA)
{
statusMachineData.status = Protocol_num;
protocol->head.head = 0XAA;
}
else
{
resetStateMachine();
resetStateMachineData();
}
} break;
case Protocol_num:
{
protocol->head.num = element;
statusMachineData.status = Protocol_rnum;
} break;
case Protocol_rnum :
{
protocol->head.rnum = element;
statusMachineData.status = Protocol_alen;
} break;
case Protocol_alen:
{
if (statusMachineData.cmdCount == 0)
{
protocol->head.alen = element << 8;
statusMachineData.cmdCount = 1;
}
else if (statusMachineData.cmdCount == 1)
{
protocol->head.alen |= element;
statusMachineData.cmdCount = 0;
statusMachineData.alen = protocol->head.alen;
statusMachineData.status = Protocol_body;
}
} break;
case Protocol_body:
{
protocol->data[statusMachineData.rlen++] = element;
if (statusMachineData.rlen >= statusMachineData.alen)
{
statusMachineData.status = Protocol_crc;
}
} break;
case Protocol_crc:
{
if (statusMachineData.cmdCount == 0)
{
protocol->crc = element << 8;
statusMachineData.cmdCount = 1;
}
else if (statusMachineData.cmdCount == 1)
{
protocol->crc |= element;
statusMachineData.cmdCount = 0;
finish =1;
}
} break;
default : NEVERSHOW break;
}
if(finish)
if (crc16 == protocol->crc)
{
show_ProtData(protocol);
protocol->fd = fd;
resetStateMachine();
resetStateMachineData();
return 0;
}
return -1;
}
//L1---L2的传递 L1读出来写到L2
int8_t tslProtocolLoop(void) {
int32_t tempLength = 0;
ProtocolMessage_t message;
int8_t ret = 0;
tempLength = rbRead(&pRb, (uint8_t *)&message, sizeof(ProtocolMessage_t));
if (tempLength == sizeof(ProtocolMessage_t)) {
for (int i = 0; i < message.len; i++) {
ret = protocolAnalyze(message.fd, &dataProtocol, message.data[i]);
if (ret == 0)
{
if (reciveDataHandleHook)
{
reciveDataHandleHook(dataProtocol.head.alen, dataProtocol.data);
}
rbWrite(&pRbL2, (uint8_t *)&dataProtocol, sizeof(ProtocolCommon_t));
}
}
}
return 0;
}
/*L2的读出
* 处理用户注册的命令
* 需要单独在一个线程中运行
这里的用法是在串口中接收数据 也即是放入到FIFO 然后在任务中读FIFO拿出来解析
*/
int8_t tslProtocolHandle(void)
{
int32_t tempLength = 0;
ProtocolCommon_t dataProtocol;
tempLength = rbRead(&pRbL2, (uint8_t *)&dataProtocol, sizeof(ProtocolCommon_t));
if (tempLength == sizeof(ProtocolCommon_t))
{
printf("\r\n");
G_printHEX(&dataProtocol,sizeof(ProtocolCommon_t));
printf("\r\n");
show_ProtData(&dataProtocol);
node_command_type *node = commer.Find(dataProtocol.data[0]<<8 |dataProtocol.data[1] );
if(node !=NULL)
node->fun(0,0,0,NULL);
tslTcpWrite(0,"123456",6);
return 0;
}
else
{
return -1;
}
}
#include "GAppCmd.h"
char timerid=0;
void timerpaly(void)
{
static int cnt=0;
++cnt;
// printf("\r\ncnt=%d\r\n",cnt);
// tslProtocolHandleCmd();
tslProtocolHandleSend();
tslProtocolLoop();
tslProtocolHandle();
}