SDK测试-串口-FIFO

完成明白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();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值