做一个接收的缓冲,cup空闲时刻处理缓冲数据
来源:互联网 发布:淘宝制作假护照 编辑:程序博客网 时间:2024/05/18 00:52
功能简介:
实现一个数据流(笔者用于串口)的接收缓冲,然后在cpu空闲的时候处理这些数据流,一般数据流有特定的格式,以便于程序分割命令和参数。
本文使用的是类似linxu shell的可见字符串。实际使用中也可以更改为16进制数据。
使用环境示例:
串口接收函数调用write_queue();插入上位机输入的数据。程序通过调用read_queue()获取数据。
/*queue.c--实现功能:定义一个环形消息队列,实现1.读一个字节 2.插入一个字节 3.取出一条命令。---------- 命令格式定义:cmd prama\r 获取命令依照" "区分命令和参数,依照"\r"区分结尾。author:nomedate :2014/4/18*/#include "string.h"#include "queue.h"#define Q_LEN 100 //队列长度#define TIMEOUT 900000 char strqueue[Q_LEN]; //队列数组int write = 0; //写偏移int read = 0;//读偏移/* * 功能:从队列中读取一个字节 * 失败:返回-1 * 成功:返回0*/char read_queue(char *pdata){if(write==read)return -1;*pdata = strqueue[read];read = (read+1)%Q_LEN;return 0;}/* * 功能:往队列中写入一个字节 * 失败:返回-1 * 成功:返回0*/char write_queue(char data){if((write+1)%Q_LEN==read)return -1;strqueue[write] = data;write = (write+1)%Q_LEN;return 0;}/* * 功能:从队列中取出一个完整的字符串命令。 * 失败:返回-1 * 成功:返回0 *cmd 存放命令的指针,param 存放参数的指针。*/int get_q_string(char *cmd,char *param){int i = 0;int timeout = 0;char data;if(read_queue(&data)) //查看队列中是否有数据,没有数据返回,有数据等待接收完整命令。return -1;cmd[i++] = data;for(;;){if(0==read_queue(&cmd[i]))i++;if(cmd[i-1]==' ')break;if(timeout>TIMEOUT)return -1;timeout++;}cmd[i] = 0; //提供一个cmd结束符timeout = 0;i = 0;for(;;){if(0==read_queue(¶m[i]))i++;if(param[i-1]=='\r')break;if(timeout>TIMEOUT)return -1;timeout++;}param[i-1] = 0; //去掉\r 换成结束符return 0;}
下面一个.c和一个.h用于处理上面.c取出的字符串。
#ifndef _USART_CMD_H#define _USART_CMD_Hstruct _cmd_list{char *cmd;void (*func)(char *param);};#define CMD_CALLBACK_LIST_BEGIN struct _cmd_list cmd_list[] = {NULL,null,#define CMD_CALLBACK_LIST_END NULL,NULL};#define CMD_CALLBACK(cmd_string,callback)cmd_string,callback,#endif
#include "queue.h"#include "string.h"#include "math.h"#include "stdio.h"#include "usart_cmd.h"extern void usart_sendstring(char *str); //定义一个串口发送字符串的函数//字符串转intint str_to_int(char *str){int i = 0,j = 0;int ret = 0;for(;;){if(str[i++]==0||i>20)break;}j = i = i-2;for(;i>=0;i--){ret += (str[i]-'0')*(pow(10,(j-i)));}return ret;}/********************一些回调函数 不必在意*****************************/void setfreq(char *param){SX1276LoRaSetRFFrequency(str_to_int(param)); memset(param,0,32);sprintf(param,"setfreq ok! freq=%d\r\n",SX1276LoRaGetRFFrequency()); usart_sendstring(param); }extern int send_receive_flag ;extern int packet_num ;void send(char *param){send_receive_flag = 0;packet_num = str_to_int(param);}void receive(char *param){send_receive_flag = 1;}void null(char *param){}/********************一些回调函数 不必在意*****************************///在此处添加你的命令字符串和回调函数CMD_CALLBACK_LIST_BEGINCMD_CALLBACK("setfreq",setfreq)CMD_CALLBACK("send",send)CMD_CALLBACK("receive",receive)CMD_CALLBACK_LIST_ENDchar cmd[10];char param[32];int get_cmd(void){int i = 0;if(get_q_string(cmd,param))return 0;for(;;){if(strcmp(cmd,cmd_list[i].cmd)==0)return i;if(cmd_list[++i].cmd==NULL)return 0;}}//这个函数需要在main函数中轮询调用void dispose_cmd(void){cmd_list[get_cmd()].func(param);}
0 0
- 做一个接收的缓冲,cup空闲时刻处理缓冲数据
- 自己做的一个输入输出缓冲池
- 针对-128到127之间的数据,做了一个数据缓冲池
- socket接收缓冲的思考
- 单缓冲 vs 双缓冲 处理数据时间计算方法
- 数据接收之环形缓冲 TCP粘包处理-RingBuf方法
- 数据缓冲
- 一段缓冲处理的源代码
- ASP.NET的缓冲处理
- ASP.NET的缓冲处理
- 接收端的视频缓冲方法
- FPGA利用FIFO做数据缓冲
- symbian s60一个数据缓冲效果的代码
- 环形数据缓冲的实现
- 从一个缓冲到另一个缓冲的输出
- 缓冲
- 缓冲
- 缓冲
- windows下查看某个端口被哪个程序占用的方法
- C# thread的join方法使用解析
- BCD码
- JAVA的StringBuffer类
- 经典c程序(0022)---杂乱的5X5的数组变盘蛇形
- 做一个接收的缓冲,cup空闲时刻处理缓冲数据
- 你是否混谈MVC和三层?
- TestDriven.NET 怎么设置快捷键keyboard shortcut
- C++应用程序的编译过程和模板类的编译过程
- [JAVA] [StringUtils] 工具类的方法解释
- item1----practice 1
- 迁移服务器之后页面变形了,出现不兼容问题
- CheckBox背景透明
- 在Oracle Linux 5 和6上使用UDEV SCSI Rules配置ASM