打印

事件驱动的流模型

[复制链接]
1321|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Simon21ic|  楼主 | 2015-9-9 00:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Simon21ic 于 2015-9-9 01:55 编辑

以前在其他版块发过这个帖子,不过貌似没啥人来参与讨论,还是这里玩开发思想的人多。

我自己的构架里,也实现了一些驱动模型,比较典型的就是流模型和块模型。
流模型里,可以实现串口流,TCP流,基于tcpip的音频流,文件流,通过IIC和I2S通用接口实现的音频流,等等
块模型里,主要用于各种存储器,以及一些特殊块设备。

有些应用,会综合利用这些流驱动和块驱动,比如:
TCP流-->视屏流-->frame流-->frame块驱动-->刷屏
当然,这个只是逻辑构架,frame流和调用块驱动刷屏,都是在framebuffer里实现的。

上面的例子相对复杂,就不用这个举例了,就用个简单一些的,音频流实现line_in直接流到line_out:
app.audio_stream.fifo.buffer.buffer = app.audio_buffer;
app.audio_stream.fifo.buffer.size = sizeof(app.audio_buffer);
stream_init(&app.audio_stream);
audiodrv.connect_output(&app.audio_stream);
audiodrv.connect_input(&app.audio_stream);
其实就是初始化流,并且,把audio里的output和input接口,链接到同一个流实例。

这里,audio驱动实现了2个流接口,一个是输出流对应line_out(输出接口会从流里读取数据,并且写到到I2S),一个是输入流对应line_in(输入接口会从I2S得到数据,并且写入流)。
上面的代码,就是把audio的输出接口,链接到流的输入端;把audio的输入接口,链接到流的输出端。然后,其他的就很自然的发生了。放音时,音频流也可以从其他地方来,比如文件的流输入接口,或者某个网络协议提供的音频流输入接口。
录音时,那就是把audio的输入接口,通过流,链接到其他的的输出流接口,比如文件的输出流接口。

说完应用方式,就说原理了。
事件驱动的流,其实也就是一个fifo+事件驱动。通知事件包括链接事件,数据收发事件。
链接事件,就是流的一段链接上后,会通知另一端我连上了。如果另一端还没链接的话,会在另一端链接后,发送这个事件。
数据收发事件就简单了,流的一端写入数据或者读取数据,都会发送事件给流的另一端。
代码就不上了,非常简单,每个函数就几行而已。

这些事件怎么处理,那就看各个模块了。
比如,用USB CDC实现的串口流,发送连接事件给串口命令行模块,然后串口命令行写入命令行提示符到流里,然后,CDC模块收到了流的写入事件后,发现CDC的对应端口不在忙碌状态,就读取出数据写到USB的某个端点,并且设置端点忙绿状态,在USB数据发送完成事件里,继续检测流里是否有数据,有的话,就读取出来,继续写到USB,没有的话,就清除USB端点的忙绿状态。
当流里的fifo满的时候,读写事件也可以通知另外一端,可以继续操作流了。
读写数据事件除了处理数据外,也可以处理其他东西,比如,音频输出流里没数据的话,那就关闭音频输出口,如果收到写入数据事件的话,并且音频口关闭,那再重新打开。

相关帖子

沙发
hunyuanqi| | 2015-9-9 08:06 | 只看该作者
能否分享整个流模型的完整代码?谢谢。

使用特权

评论回复
板凳
Simon21ic|  楼主 | 2015-9-9 10:38 | 只看该作者
hunyuanqi 发表于 2015-9-9 08:06
能否分享整个流模型的完整代码?谢谢。

思想已经讲这么清楚了,那几行代码,真是分分钟搞定的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

266

主题

2597

帖子

104

粉丝