电子产品世界 » 论坛首页 » 企业专区 » STM32 » 基于Linux的kfifo移植到STM32(支持os的互斥访问)

共2条 1/1 1 跳转至

基于Linux的kfifo移植到STM32(支持os的互斥访问)

菜鸟
2019-01-23 22:18:28    评分
关于kfifo

kfifo是内核里面的一个First In First Out数据结构,它采用环形循环队列的数据结构来实现;它提供一个无边界的字节流服务,最重要的一点是,它使用并行无锁编程技术,即当它用于只有一个入队线程和一个出队线程的场情时,两个线程可以并发操作,而不需要任何加锁行为,就可以保证kfifo的线程安全。

说明

关于kfifo的相关概念,有兴趣可以看相关文档,这里只将其实现过程移植重写,移植到适用stm32开发板上,并且按照个人习惯重新命名,RingBuff->意为环形缓冲区

RingBuff_t

环形缓冲区的结构体成员变量,具体含义看注释。
 buffer: 用于存放数据的缓存
 size: buffer空间的大小
 in, out: 和buffer一起构成一个循环队列。 in指向buffer中队头,而且out指向buffer中的队尾

image.png

Create_RingBuff

创建一个环形缓冲区,为了适应后续对缓冲区入队出队的高效操作,环形缓冲区的大小应为2^n字节,
如果不是这个大小,则系统默认裁剪以对应缓冲区字节。
当然还可以优化,不过我目前并未做,思路如下:如果系统支持动态分配内存,则向上对齐,避免浪费内存空间,否则就按照我默认的向下对齐,当内存越大,对齐导致内存泄漏则会越多。对齐采用的函数是roundup_pow_of_two。如果系统支持互斥量,那么还将创建一个互斥量用来做互斥访问,防止多线程同时使用导致数据丢失。

image.png

image.png

roundup_pow_of_two

image.png

Delete_RingBuff

删除一个环形缓冲区,删除之后,缓冲区真正存储地址是不会被改变的(目前我是使用自定义数组做缓冲区的),但是删除之后,就无法对缓冲区进行读写操作。并且如果支持os的话,创建的互斥量会被删除。

image.png

Write_RingBuff

向环形缓冲区写入指定数据,支持线程互斥访问。用户想要写入缓冲区的数据长度不一定是真正入队的长度,在完成的时候还要看看返回值是否与用户需要的长度一致~
这个函数很有意思,也是比较高效的入队操作,将指定区域的数据拷贝到指定的缓冲区中,过程看注释即可

image.png

image.png

Read_RingBuff

读取缓冲区数据到指定区域,用户指定读取长度,用户想要读取的长度不一定是真正读取的长度,在读取完成的时候还要看看返回值是否与用户需要的长度一致~也支持多线程互斥访问。
也是缓冲区出队的高效操作。过程看代码注释即可

image.png

image.png

获取缓冲区信息

这些就比较简单了,看看缓冲区可读可写的数据有多少

image.png

image.png

附带

这里的代码是用于测试的,随便写的

image.png

支持多个os的互斥量操作

此处模仿了文件系统的互斥操作

image.png

image.png

image.png

debug.h

最后送一份debug的简便操作源码,因为前文很多时候会调用
PRINT_ERR
PRINT_DEBUG

image.png

image.png

image.png转贴自网络



管理员
2019-01-24 08:38:29    评分
2楼

涨姿势


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]