关于内存,要讲的东西有点多,还是分篇聊吧,这一篇笔记说是讲事件,其实是想借着事件来讲一下内存管理,正好事件这块也用到了内存管理,所以就一块讲了吧,水平有限,讲到哪里算哪里吧,讲不到的地方就靠你们了。站在应用的角度上来讲,开发一款软件,当你的构架定型的时候,状态机也就基本定型了,能控制事件的数量和大小,那就取决于你对状态机的应用能力了。但是有一点无论你的事件控制的多小,他总归会占很大一部分比重,因为整个应用所有的交互全靠事件来驱动。
假如你用传统的方式定义了所有的事件,所谓传统的方式就是静态的定义,你要问啥是静态的定义,那么这么讲,你这么问就证明你现在用的方式都是静态的,那么后面的内容都不用讲了,直接下课了,因为静态定义的变量(单片机中常这么称呼),从出生开始就不会凋零,也就是不会GAMEOVER,那你还谈什么生命周期,内存回收。内存管理?没有内存管理了(那还聊什么,友谊的小船说翻就翻,掀桌子...)。
传统的静态的定义事件,也并不是一无是处,例如,稳定,不会产生系统潜在的风险,申请不到,提前回收等等问题,说白了,就是用起来简单,不用想那么多复杂的场景,但是有个最大的缺点就是消耗内存,当然这个问题嵌入式领域,完全可以通过升级内存来解决,这也意味着成本的上升,那全部定义成动态事件?也会存在很多问题,首先他无形的提高了对编程者的水平要求,各种漏洞总是五花八门,合理的分配静态和动态事件所占的比例,用有限的资源实现整个应用,才是我们真正的追求。那什么样子的事件适合被定义为静态事件.
这里总结了一下,给大家两个建议:
1. 这个事件从定义开始,就不会发生任何变化,也就是事件的参数不会发生改变。
2. 这个事件总是被频繁的使用,贯穿整个应用,例如由QF_tick产生的周期事件。
为了增加应用的灵活性,掌握动态事件的使用时关键,下面聊得都是以动态事件为基础的内存方案。
接下来我们来聊聊,关于事件是如何在QF中传递的,我们知道事件要被发送到相应的事件队列,那么真正传递到事件队列的是什么?其实是有两种方案,第一种是值传递,这种情况,你要传递一个事件,你就需要把整个事件复制出一个复制品,并放进事件队列中,实际情况比这还要复杂,这只是将事件传递到事件队列,还有事件循环要从事件队列取出事件,给到状态机,这中间是否有牵扯一次的事件复制,在很多RTOS中都是采用这种值传递,他的好处是用内存开销来换取确定性,其存取模型如图:
还有一种事件的派发机制,叫做零事件派发机制,实际就是应用指针传递,这种方式不太适合传统的RTOS这里记住就好了,展开讲就太细节了,但是这种方式非常适合QF框架,因为他是明显的控制倒置的类型,框架对于维护事件的指针还是合适的,因为框架可以从头到尾的跟踪整个事件指针的来龙去脉,不会再RTC中过多的停留。其存取模型如图:
从图中可以看到动态事件全部被指向事件池,也就是在传递过程中传递的是指针。还有一个点需要关注一下,就是一个动态事件的生命周期中所有权的问题,直接看图吧,大概理解一下图:
关于内存管理再讲篇幅就有点长了,还是分开聊,看下篇吧 。