2

光伏云项目杂记02 – 构建Ringbuff(环形缓冲)1

 3 years ago
source link: http://yiiyee.cn/blog/2019/05/13/%e5%85%89%e4%bc%8f%e4%ba%91%e9%a1%b9%e7%9b%ae%e6%9d%82%e8%ae%b002-%e6%9e%84%e5%bb%baringbuff%e7%8e%af%e5%bd%a2%e7%bc%93%e5%86%b21/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

光伏云项目杂记02 – 构建Ringbuff(环形缓冲)1

在做这个项目的时候,遇到一个问题。我们使用的STMF103C8T6,资源很可怜,看看:

图1 STM32F103C8T6的参数

72M的频率,内存只有20K。而这个芯片需要做的事情:

1 3个串口的收发;
2 3个灯的控制,让用户通过灯的闪烁判断处于什么状态,方便维护;
3 GPRS模块的协议管理;
4 与逆变器端的协议管理;
5 看门狗的任务处理;
6  服务器端协议的处理,包含应用端口和配置端口;

以FreeRTOS为架构,估计用了近20个任务来完成这些工作。每个任务给的堆栈是0.5K,加上串口需要的缓冲区,一番操作下来,内存基本用光光。一起开发的兄弟,暂且称为烟枪吧(抽烟很快,1分钟一根,当得起这个称呼)。每天嚷嚷,说内存严重不够用,不能让客户再提新的需求了。虽然通过map文件计算了每个任务所用的栈空间,尽可能不浪费。不过再改的话,程序就直接溢出了,问题出在哪都不知道。

我很同意他的看法,也很同情我们的处境。可是,客户又不是我家的,他想提要求,我又控制不住。何况有些要求还是很中肯的,咱们都是讲道理的,对吧?

那怎么办?

分析源代码,我盯上了串口处理的这段代码。三个串口,除去串口接收发送所需要建立的任务外,每个串口还用了256字节的缓冲区。另外,程序写得耦合性比较差,估计换个芯片,所有代码都得重写。

程序逻辑是这样的:

  1. 将缓冲区分为两段,A段128字节,B段128字节;
  2. 串口接收启用DMA传输,不占用CPU资源;
  3. 当触发串口接收DMA中断,中断处理程序将缓冲区指向A段,接收数据;
  4. 接收完毕后缓冲区指向B段;
  5. 有一个任务专门监听,发现有数据立即取走;
  6. 新的数据来了,DMA接收中断处理程序用B段缓冲区取走数据,收完后缓冲区指针再指向A段。

也就是说,当监听任务在处理数据的时候,DMA接收中断使用了另外一段缓冲区,大家互不干涉(当然程序中也利用了FreeRTOS的互斥量来实现)。

这样实现其实没有太大问题,因为精心计算了串口和DMA的处理时间。接收串口的数据越长,越不会出现问题。

问题就出在小数据上。如果串口接收大量的小数据,频繁的触发中断,CPU就有可能丢失数据了。(实际运行中没有出现过,连续发送1个字节的情况,在客户环境中可认为概率是0)

烟枪和我商量了一段时间,我们决定使用ringbuffer(环形缓冲)来实现。他把这个任务轻飘飘的交给我了,调他的板子去了。

没办法,开始干活吧。 Ringbuffer的基本原理,我大概了解。维基百科中也有说明:https://en.wikipedia.org/wiki/Circular_buffer

A 24-byte keyboard circular buffer. When the write pointer is about to reach the read pointer – because the microprocessor is not responding, the buffer will stop recording keystrokes and – in some computers – a beep will be played.

我能用的资源有限。必须实现原有的串口接收,不能丢数据;同时还有提供尽可能简单的接口,供应用层的函数调用。

因此,我选择使用Contiki中的代码,用它的核心思想来构建这个架构。当时估计错误,我不觉得能有多难,本以为一周左右能搞定。没想到对芯片的DMA以及串口不那么熟悉,整整花了我三周时间。

这是一段痛并快乐的回忆。

1,294 total views, 3 views today


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK