序
在我们的系统中,难免用到一些数据处理的东西,但是效率是个问题,在网上找到的资源也是乱七八糟的,所以现在的我自己处理一套验证过的demo,在我的github中,还会慢慢更新,现在我把写的一些数据处理相关的东西开源出来,写得不好,请多见谅~~大神们请绕道!!!
我的demo是基于stm32f103开发平台的,算是利用闲时时间整理的吧,把这些东西再整理一遍,以后使用时会很方便,全部是采用驼峰规范命名的方式,即使不懂英语的也能复制粘贴到谷歌翻译得出结果!全局的函数/变量全部驼峰命名,内部调用函数/变量一律小写加‘_’隔开,注释的话有点类似Doxygen规范注释,算不上很标准,但注释了关键地方。
1
如果没看过前面的文章请从前面的文章看起:
环形缓冲区的代码我是基于Linux的kfifo修改而来,之前在demo中使用了除法算到浮点数,我被"word天"教育了一下,除法运算在程序中要少用,所以Linux的kfifo源码写得还是很好的,比较经典(目前好像更新到4.0.8)我用这个还是在2.几的版本,改到我们的32中,会比较常用。而且我后续会改进,会让它支持RTOS,添加互斥锁以保护资源,不过现在仅支持裸机。
本文不讲原理,只讲实现。原理见
RingBuff结构体:
创建一个RingBuff:
创建很简单,只不过要注意,为了后面的运算,缓冲区大小必须为2^n字节,为什么呢,后面讲解,此处记住即可,调用内部函数 “roundup_pow_of_two”为了内存的对齐,可以选择向上对齐/向下对齐。我个人建议向下对齐,丢弃部分内存更安全,否则可能导致指针非法访问。当然如果是动态内存的话,可以选择向上对齐。
该函数具体见:
而这个“fls”就很简单了:
删除一个缓冲区:
往缓冲区写入数据,算法的精妙就在这里:
用心体会,就知道算法的精妙了。暂时先不说,多人问我就说一下。。。
读缓冲区数据:
懂了上面的这个也是很简单的啦~~
然后就是附带写的获取缓冲区信息的一些函数,可读缓冲区长度,可写缓冲区长度等:(后续可能会陆续更新)
然后就是写个小例子:
2
数据打包
串口数据会有丢包现象,将数据以数据包的形式发送,也就是写自己的协议,不符合的数据就丢弃,其实还是蛮好的。黄工有一个公众号在写mavlink,这是一种用于飞控的轻量级通信协议,个人感觉很不错,等他写完我也研究研究。
我不知道怎么形容我写的这种数据包:看格式吧
所有数据将以这种格式发送,定义一个接收状态标记,用于记录接收的状态,一个32位的变量,最高两位用于记录接收状态,低16位用于记录接收的长度。
发送数据,发送数据的时候会将数据打包:写得不算好,但能用。
特点:
支持通过宏定义选择发送的形式,支持DMA与普通串口发送,接收也是支持(DMA+空闲中断接收)与普通串口中断接收。支持宏定义选择CRC校验,不过目前我利用stm32本身的CRC校验不太行,以后要自己写一个校验才行。
有些简单的发送函数我就不写了,自己看源码即可,下面是采用DMA+空闲中断方式接收:
这里是采用普通串口中断方式,这种方式效率不高,不建议使用!
接收完数据必须得验包啊,下面是数据包处理函数,如果不是完全正确的数据,则丢弃掉!
这些PRINTF_DEBUG/PRINTF_ERR是通过宏定义使能释放要打印这些调试信息的,我只在调试的时候打印,正常使用将对应的宏定义失能即可。
下面是随便写的例子:
3
数据处理
这个函数是参考C标准库写的,用于将字符串转换成整数的!说有用也有用,说没用也没用,仁者见仁智者见智吧!不对这个函数文件做介绍!
将整形数转换成字符!最大为int32类型的数
内部调用的一些函数:
END