zl程序教程

您现在的位置是:首页 >  其他

当前栏目

1、多子系统配置

2023-02-19 12:22:19 时间

在低功耗特性中,软件可能实现起来并没有那么难,从设计到实现的时间可能并不会耗时特别长,耗时最长的是后续的商用问题定位以及对功耗的优化,这些都是建立在一定的实战基础上才能做的越来越好,在这里推荐几种比较常用的优化或者定位问题的手段供大家参考,希望能给大家带来一些帮助。

1、多子系统配置

比如某一个公共外设,如果多个子系统共用的话,在芯片设计上建议每个子系统各放置一个,这样一可以节省系统运行过程中的访问带宽,二可以做好访问隔离,尽可能的降低了芯片通路访问的复杂性和软件设计的复杂性。

我们通过一个例子来说明一下:比如在一个系统中,只有一个DMA,存放在公共外设区〈peri),这个时候如果AP需要访问DMA的话,那么它需要先经过自己系统的SUB BUS总线,再通过SYS BUS总线访问到外设区的DMA如图19-1所示。

如BP需要访问DMA的话,那么它也需要先经过自己系统的SUB BUS总线,再通过SYS BUS总线访问到外设区的DMA;如此这般,其他子系统都是同样的访问路径。在这样的情况下,有2个缺点:一是访问路径过远增加了总线的繁忙程度,可能导致访问延时﹔二是可能存在资源竞争的发生,比如AP、BP或其他子系统同时访问的话,可能需要做仲裁处理。

那么针对这种情况,我们可以做个优化,就是把DMA在每个子系统内部的device区各放置一个,如图19-2所示,各个CPU需要使用DMA时,只用访问自己内部的DMA即可,这样可以很好的化解前边说的2个缺点。为什么说这样设计也可以做到功耗优化呢?试想如果AP侧没有这个DMA,那么在AP侧唤醒而其他子系统都睡眠的情况下,AP侧如果要访问DMA,势必需要给其他子系统上电,从而带来功耗的浪费,而如果AP子系统内部本身就有DMA的话就没有必要给其他子系统上电。这个思想当然可以用在任何IP的归置上,需要根据实际的设计场景做对应的优化。

2、并行处理

低功耗比较敏感的一个KPI是suspend和resume的时间,因为低功耗是系统中的一个常态,这一块的处理时间当然是越短越好,这样可以让用户体验更流畅。一个好的思想是让处理尽可能的并行起来,比如在suspend和resume的流程中,有一长段地址空间需要保存恢复,那么如果是用CPU的话,效率是十分低下的,这个时候我们可以使用DMA来搬移数据,同时CPU继续处理低功耗处理的其他流程,在合适的点来检查DMA的搬移状态。我们可以通过以下例子来说明。

在suspend流程中,PD MEM中的内容我们使用CPU来做下电前的保存动作,如图19-3所示,把内容保存到DDR中,耗时T1,其他suspend处理耗时为T,那么suspend总耗时为T+T1,T1时长与PD MEM的大小强相关,越大耗时越长。

那么关于大内存保存恢复这一块,其实我们可以做一个优化,那就是不使用CPU进行处理,我们使用DMA去做搬移,CPU去做其他的suspend动作,那么T1这个耗时就可能会省下来,总耗时为T,从而达到时长优化的目的。如图19-4所示。

前边讲了suspend流程的并行处理优化思想,对于resume流程来讲,同样适用,就不再做过多阐述。

3、增加打点信息

因为在低功耗流程中,会涉及到关闭时钟或者关闭电源等操作,很多debug工具是无法使用的,一个好的手段是在内存中划分一片区域专门用来给低功耗流程打点使用,打入数据通常是系统中递增的时间戳,这样有2个好处:一是可以方便查看各个阶段的耗时,二是可以根据时间戳的递增特性来快速的定位到哪一步出了异常。如图19-5所示。

我们对这个样例做个解析,可以获取到以下信息:

  1. s1打点信息为0x1234,s2打点信息为0x1255,那么我们就可以知道suspend process2处理耗时0x1255-1234=0x21个时间单位。同理我们可以计算出suspend整个流程的耗时时间。 2)如果s2打点信息为0x1111,比s1的0x1234要小,那么我们就可以确定suspend process2的处理出现了异常,代码没有继续走下去。这个方法可以使用到流程中的任意处,我们可以使用此方法来找到suspend流程中的异常点。
  2. r1的打点信息为0x1300,我们可以据此来判断当前系统是退出了睡眠流程,因为resume流程的打点信息要比suspend流程中的所有打点信息大。如果r 1要比suspend流程中的打点信息小,那么可以判定当前系统正处于睡眠状态。

4)r1打点信息是0x1300,r2打点信息是0x1311,那么我们可以判定resume process2的处理耗时为0x1311-0x1300=0x11个时间单位,同样的原理我们可以算出整个resume流程的耗时时长。

  1. 如果r1是0x1300,r2打点信息不是0x1311,而是Ox11xx,或者其他比0x1300小的值,那么我们可以确定r2的打点信息是上一次resume的打点信息,本次resume流程中的打点信息没有打上,那么就可以确定resume process2出现了异常,从而帮助我们定位异常点。

4、增加suspend流程状态检查返回点

睡眠状态是通过唤醒中断唤醒的,我们无法预知唤醒中断什么时候可以唤醒,如果在睡眠过程中我们不做检查,那么有可能在过程中唤醒中断就到来了,这个时候睡眠继续往下走是没有意义的,空多了一次唤醒过程,如果我们能在睡眠流程中及时发下唤醒中断的到来并及时停止睡眠流程,那么就节省了一次睡眠唤醒时间。我们假设suspend流程耗时T1,resume流程耗时T2,那么经过一次睡眠唤醒耗费在流程上的总时长为T1+T2。试想一下,如果在处理完suspend process1后,在处理suspend process2之前,如果唤醒事件到来,其实本次suspend流程是没有必要继续走suspend process2之后的流程的,T1-t1+T2这段时间的处理纯属浪费,白白多花费了一次睡眠唤醒流程,也延迟了唤醒事件的处理速度。示意图如图19-6所示。

那么针对这种情况,我们可以在suspend流程中添加唤醒事件判断返回点,可以提前发现唤醒事件及时中止suspend并返回到active状态。如图19-7所示。

5、设置提前唤醒量

比如某个关键的业务事件在未来的某个时间点会到来,那么我们可以根据这个时间点来提前设置一个定时器唤醒中断,最理想的情况就是定时器唤醒后刚好碰到要处理的事件,避免由关键的业务事件亲自唤n醒系统导致的业务处理延迟(毕竟加上了唤醒流程的耗时)。 优化前: 业务唤醒事件期望T1能处理事件,实际上事件到来后,系统正处于睡眠,多加了一次resume流程的处理,实际响应唤醒事件是在T2时刻。如图19-8所示。

优化后: 当系统要进入suspend时,我们可以计算一下当前时间与唤醒事件要到来的时间T1之间的差值At,然后以At 减去resume流程耗时的结果作为超时时间启动一个唤醒功能定时器,这样的话,当系统走完resume流程,刚好赶上T1时刻,可准时处理唤醒事件。如图19-9所示。

6、减少(合并)唤醒中断次数

通过减少唤醒次数,可以显著的节省系统对功耗的消耗。比如BP要往AP发送数据,每次有数据到来都要对AP做一次唤醒动作,每次醒来大概率可能只是处理了这个数据而已,然后又睡下去,过段时间可能又有数据需要发送,然后又一次唤醒AP,每一次的唤醒都是对功耗和资源的消耗。如图19-10所示。 优化前: